First time visiting the jcsref website? Check out the welcome page for information.

Browse through the latest news to see what's going on with JCS and level editing in general.

Take a look at this month's feature articles for some of our best content.

Been a while since your last visit? Find out what's new in the latest updates section.

What have people been talking about on the site? Find out in the latest comments section.

Get to know the staff members of jcsref and find out how to contact us.

Our links section is full of great JCS resources. If you can't find it here, you'll find it on one of the links.

Not really sure what you're looking for? Want to see what all jcsref has to offer? Check out our topics listing now! You can use the link above, the book icon up top, or the topics tab to the left.

Do you know exactly what you're looking for? Are you trying to get information on several topics? Give our archive search a try! Use the link above, the magnifying glass icon up top, or the search tab on the left.

Not sure on the spelling of your topic? Need to browse through some keywords to find what you want? Our site index is just what you're looking for! To go there now, use the link above, the papers icon up top, or the index tab to the left.
 Viewing node Remembering Triggers

Remembering Triggers

A common design question in single player levels is how the level can know what the player did and where the player went before dying. Checkpoints take players back to specific locations, but at least in single player, very few other data get retained between lives. However, there are many cases where a player must smash three or four trigger crates to continue past an area, or where the entire level involves finding a number of coins, and it would be a lot nicer to the player if the level remembered which coins had been found or which trigger crates had been smashed, even after death. This article describes how to retain such data. The system this article describes is quite small, requires only one trigger per accomplishment (plus one universal always-on trigger), and will remember which triggers were set at the time of death and turn them on again after reincarnation. It relies heavily on, and presupposes understanding of, the JCSref articles Tile Cache and at least the first half or so of Event Theory. You can conceivably get by just through copying the illustrations into JCS and calling it good, but those articles will make your understanding a lot richer and you'll be able to use more variation and handle problems more easily.

Blocks in Boxes

Crates other than gem crates may contain additional objects inside of them, ranging from enemies to other crates to coin warps. The ExtraEvent parameter specifies which object to spawn on the crate's destruction and the NumEvent parameter how many of that object. For instance, a carrot crate with ExtraEvent 100 and NumEvent 5 will spawn five Tuf Turtles on destruction. For the most part, ExtraEvent objects are stored only temporarily in JJ2's memory and will disappear in single player games when the player moves enough tiles away from them. One set of events that do not disappear are the various block-type events: Collapse Scenery, Trigger Scenery, Destruct Scenery, Destruct Scenery BOMB, and Buttstomp Scenery. Most of this article is only about Trigger Scenery, but keep in mind that most everything that is said applies equally well to the other events, modulo different means of causing them to advance in frames.

For an example case, consider a bomb crate that has fallen in front of a Float Up event. The bomb crate contains a silver coin ExtraEvent. In event memory are a bomb crate and a float up. When you open the bomb crate, a silver coin is added to event memory, along with its position, and the bomb crate is removed from event memory. This has no effect on the float up. When the player goes 31 tiles away, both the float up and the silver coin are erased from event memory. When the player returns, JJ2 checks the tile and sees that the first eight bits of its bitmap specify a float up event, so JJ2 adds a float up to event memory. The silver coin is gone because its existence was not stored in any remotely permanent fashion.

If the bomb crate contains a trigger scenery, however, things go quite differently. The bomb crate is destroyed, and event memory contains a trigger scenery and a float up. However, JJ2 also edits the bitfield of the tile so that the event on that tile is not a float up but a trigger scenery. (The last 24 bytes remain constant.) When the player goes 31 tiles away, both are removed from event memory, and when the player returns, JJ2 puts the trigger scenery back in event memory, but there is no record of the float up and it is no longer there. The .j2l file itself has not been changed, but JJ2's understanding of the tile has been. What's more, the only ways to get the float up back are to quit JJ2 or to reload the level: the tile remains trigger scenery even after death. If you die and then open the crate again, then a second tile will become trigger scenery forever.

At this point JJ2 handles the tile as if it had had the event on it from the beginning. If it's not an animated tile, it goes blank. If it was an animated tile, then animation stops and the tile displays the first frame until triggered. If there was already another such event (trigger, destruct, etc.) on the tile, or if two crates both with such events open on the same tile, then the animated tile disappears and cannot be recovered, even if the player goes 31 tiles away. This can be a problem if you don't take proper precautions, as if the same crate is opened on the same tile twice, once before a death and once after, the tile will vanish completely and be no longer usable. Plan ahead! There are a few different things one may do with this technique – replicating the JAIL2 system is fairly trivial with the use of a speed destruct scenery – but this article focuses on the specific goal of recording which triggers have been turned on since the level began, no matter how many times the player has died since then.

Step 1

First there needs to be some standard JCS work. The basic requirement is that somewhere in the level there is a way to turn a certain TriggerID – arbitrarily, call it 1 – to on. In most cases, particularly if you are collecting coins, this should also include something to prevent that particular area from being accessed once the trigger is on, regardless of from where in the level it is triggered. Here is a very simple example:

fig. 1.0 – A basic trigger. The player falls into the pit and hits the trigger zone (TriggerID 1), which causes the trigger scenery to become masked. S/he then warps out of the pit but cannot return because the entrance is sealed up. Even after death, assuming that the trigger is on, the pit will be unenterable.

Step 2

The most important part of the whole setup is the crate containing the trigger scenery event. It must be on the right animated tile, but it cannot be placed on that animated tile in JCS because its bitfield would get in the way. Instead move the crate onto the animated tile using belts. When the crate does open, the trigger scenery will use the bitfield attached to the animated tile and here gain a TriggerID of 5. This trigger will be on at all times and will thus detect whether the tile is trigger scenery or not. (5 is of course arbitrary and could be replaced with any other number from 1-31, or even 0 if you feel like using a trigger crate.)

fig. 2.0 – The crate containing the trigger scenery. The crate is placed two tiles above the belt events so that the crate's Speed Point does not detect its own bitfield and go somewhere undesired. The MCE Event with Event 24 then serves to position the belt-moving crate directly in the middle of the animated tile. When the crate is opened, the trigger scenery will take its TriggerID from the Event of the MCE Event beneath it, here 5.

Step 3

The crate with the trigger scenery 5 should be opened, but only when the player turns on TriggerID 1. This is simple enough: place a crate containing TNT on top of a trigger scenery block with TriggerID 1, and have the crate burst open on falling. The easiest way to do this is an animated tile at speed 70 going back and forth between masked and unmasked. For maximum reliability, place the TNT-containing-crate on the animated tile to begin with and have it bounce back into it and explode from a red spring below.

fig. 3.0 – The TNT crate is added. When TriggerID 1 is activated, the TNT crate falls down, hits the red spring, bounces up into the animated tile, and opens. The TNT instantly explodes and opens the top crate, which lets out the new trigger scenery event. Once the level trigger is activated, the crate-spawned trigger scenery event will never go away.

Step 4

Whenever the player begins the level, particularly after dying, the level should check to see if the trigger scenery inside of the crate was released. To do this, force the player to turn on TriggerID 5 before doing anything else, for instance using sucker tubes. Be sure to use a WaitTime, because during the initial invincible period the player cannot use trigger zones, and be sure to put masked tiles under the sucker tubes, because if the player is in a sucker tube with WaitTime and has not yet landed on solid ground s/he gets stuck.

fig. 4.0 – Jazz Start. The player sits in a WaitTime sucker tube until the initial invincibility wears off, then activates TriggerID 5. If the trigger scenery in the top bomb crate has been released, then the animated tile marked by the top-right MCE Event will trigger and go solid. Otherwise TriggerID 5 will have no (relevant) effect.

Step 5

Here is where the tile cache comes in. The idea is that if the animated tile is now solid, then TriggerID 1 should turn on, because it was only through the level trigger turning on in the first place that the animated tile became a trigger scenery (TriggerID 5). If it's not solid, then TriggerID 1 should remain off, as all triggers are at the beginning of a level. Here is a simple way of finding out: have another copy of the same block, and send the player through it using sucker tubes. If the animated tile is solid, the player will hit against it, fall down, turn on TriggerID 1 (and here collect a silver coin again), and then continue on through the tube. Be sure not to put an event on the animated tile within the sucker tube system, because that would cause JCS to recognize it as a new block, rather than a second copy of the old one.

fig. 5.0 – The tiles outlined in yellow are two instances of the same four-tile block. When TriggerID 5 is activated, as it is at the beginning of the level after the WaitTime sucker tube, then assuming the uppermost crate has been opened, the animated tiles in both copies of the block will trigger and go solid. When the player hits the solid animated tile, s/he will fall down and reactivate TriggerID 1.

Step 6

This last step is just cleanup. Currently when the player hits the solid animated tile in the sucker tube network and turns on TriggerID 1, the lower bomb crate will again fall onto the red spring, bounce up, and explode. Then the upper bomb crate will open again, releasing another copy of trigger scenery, and the animated tile will disappear forever. To prevent this, the lower bomb crate should only explode if the animated tile isn't yet trigger scenery. This can be achieved by creating yet another copy of the block and having the red spring be in front of the animated tile. Move the spring onto it using belts – the parameter settings to move the spring enough pixels are provided in the below image. This way, if the top crate has been opened, then turning on TriggerID 5 will make the tile where the spring is solid, and the lower crate (containing the TNT) will be unable to land on the spring and bounce up to its destruction. Here, then, is the entire system:

fig. 6.0 – Added is the middle yellow-outlined block, which moves the red spring onto the all-important animated tile using a belt. Just as the player activating TriggerID 5 at the beginning can solidify the animated tile in the sucker tube network, so too can it solidify this one, which prevents the lower bomb crate from exploding after TriggerID 1 is activated. This is the complete system.

Finally, here's a level in which the system is implemented not once but four separate times, exactly the same each time, showing off its plug-in-ability. Note that a different block is used for each setup, as indicated (and caused) by the different plant tiles. The only point of concern is that the player should be within 31 tiles of the actual trigger scenery with TriggerID5 before the bomb crate with the TNT has a chance to explode again, so that the game has a chance to register that the animated tile in the block should now be solid. but that's a memory issue and can best be solved on a level-to-level basis.
Example Level
Again, this is not the only effect that can be yielded by putting trigger scenery and other such events inside of crates. It is, for instance, possible to retain a virtually unlimited number of block changes such as in the system above without using up any triggers at all, if one uses speed blocks instead and does some careful tile cache work. However, the above system seems extremely robust and should serve for most any purpose, assuming that memory is taken into consideration.

Added on: 29 June 2009 09:22. Made by Violet CLM.