Skip to content

Entries and exits

An entry is a place where the player can arrive on a map. An exit is a trigger that sends the player to an entry on another map. To connect two maps, give each one an entry and an exit that leads to the other's entry.

Adding an entry

An entry is an Entry marker. To add one, right-click the floor in the map editor where the player should arrive, select New Entry..., and give it a name, such as Back. Then turn it to face the way the player should face as they arrive.

The map numbers its entries in the order they appear in the Outline, starting at 0. In the map's code, this entry is $Back, and $Back.index is its number. For more, see Entry markers.

To send the player to another map's entry, include that map's header, such as #include "world/area/kmr/kmr_03.h", and refer to the entry as a field of the map, such as $kmr_03.Front.

Choosing how the player arrives

When a map loads, its main EVT script brings the player in at the entry they came through, then binds the map's exits. A new map walks the player in at every entry:

Set(LVar0, EVS_BindExitTriggers)
Exec(EnterWalk)

EnterWalk starts the player a short way behind the entry, walks them onto it, and then starts the EVT script in LVar0. Binding exits only after the player arrives stops them from walking straight back out. EnterWalkShort is the same with a shorter walk.

If entries need different arrivals, such as one through a door, check the entry with GetEntryID in an EVT script that the main EVT script starts:

EvtScript EVS_EnterMap = {
    Call(GetEntryID, LVar0)
    Switch(LVar0)
        CaseEq($Back.index)
            Set(LVar2, MODEL_door)
            Set(LVar3, DOOR_SWING_OUT)
            ExecWait(EnterSingleDoor)
            Exec(EVS_BindExitTriggers)
        CaseDefault
            Set(LVar0, EVS_BindExitTriggers)
            Exec(EnterWalk)
    EndSwitch
    Return
    End
};

In EVS_Main, replace the lines that start EnterWalk with Exec(EVS_EnterMap).

Arriving from a save

When the player saves at a save block, the game saves the map, the entry the player came through, and the player's position. Loading the save loads that map with that entry, and GetLoadType gives LOAD_FROM_FILE_SELECT.

EnterWalk and the door enter EVT scripts check for this: instead of walking the player in, they put the player where they saved. The pipe entries don't, so if a map with a save block has a pipe entry, check first, as kmr_02 does:

EvtScript EVS_EnterMap = {
    Call(GetLoadType, LVar1)
    IfEq(LVar1, LOAD_FROM_FILE_SELECT)
        Exec(EnterSavePoint)
        Exec(EVS_BindExitTriggers)
        Return
    EndIf
    // ...
};

A save stores the map by its name. If you rename a map, saves made in it start at the new game's entry, NEW_GAME_ENTRY in dx/config.h.

Edge exits

The most common exit is walking off the edge of a map. Make the exit EVT script with EVT_EXIT_WALK, and bind it to a collider at the edge with TRIGGER_FLOOR_ABOVE:

EvtScript EVS_ExitWalk_kmr_05 = EVT_EXIT_WALK(60, $BehindVillage, $kmr_05.GoombaVillage);

EvtScript EVS_BindExitTriggers = {
    BindTrigger(EVS_ExitWalk_kmr_05, TRIGGER_FLOOR_ABOVE, COLLIDER_deili1, true, 0)
    Return
    End
};

EVT_EXIT_WALK takes how far the player walks, the entry on this map beside the exit, and the entry on the other map to go to. The player walks out the opposite way to that entry's direction, so put an entry at each edge exit, facing into the map. Players arrive at an edge entry with EnterWalk.

Doors

A door exit opens the door, walks the player through it, and goes to the other map. Bind it to the door's collider with TRIGGER_WALL_PRESS_A:

EvtScript EVS_ExitDoor_arn_12_0 =
    EVT_EXIT_SINGLE_DOOR($Arn12, $arn_12.Arn10, COLLIDER_tte, MODEL_o37, DOOR_SWING_OUT);

EvtScript EVS_BindExitTriggers = {
    BindTrigger(EVS_ExitDoor_arn_12_0, TRIGGER_WALL_PRESS_A, COLLIDER_tte, true, 0)
    Return
    End
};

The first argument is the entry in front of the door, facing away from it into the room. The player walks out through the door, the opposite way. The door swings with DOOR_SWING_IN or DOOR_SWING_OUT. If it swings the wrong way, use the other one.

To bring the player in through a door, set the door's models in local variables and run the matching enter EVT script, as in Choose how the player arrives:

DoorExitEnterSet before entering
One modelEVT_EXIT_SINGLE_DOOREnterSingleDoorLVar2: the model. LVar3: the swing.
Split into a top and bottom modelEVT_EXIT_SPLIT_SINGLE_DOOREnterSplitSingleDoorLVar2: the top model. LVar4: the bottom model. LVar3: the swing.
A pair of doorsEVT_EXIT_DOUBLE_DOOREnterDoubleDoorLVar2: the left model. LVar3: the right model.

For other door sounds, such as a creaky door, use EVT_EXIT_SINGLE_DOOR_SET_SOUNDS or EVT_EXIT_DOUBLE_DOOR_SET_SOUNDS, which take a DOOR_SOUNDS_ value, such as DOOR_SOUNDS_CREAKY, as their last argument.

Pipes

The pipe exits and entries are in world/common/entity/Pipe.inc.c, which the map's main.c includes:

#include "world/common/entity/Pipe.inc.c"

A pipe exit runs an EVT script of yours once the player is inside the pipe. That EVT script goes to the other map with GotoMap:

EvtScript EVS_GotoMap_tik_12_0 = {
    Call(GotoMap, $tik_12.ScalesRoom)
    Wait(100)
    Return
    End
};

EvtScript EVS_ExitPipe_tik_12_0 = EVT_EXIT_PIPE_VERTICAL($MetalBlockRoom, COLLIDER_ttd2, EVS_GotoMap_tik_12_0);
PipeExitBind the exit withEnter
Vertical, entered by pressing down on the Control StickEVT_EXIT_PIPE_VERTICALTRIGGER_FLOOR_TOUCH on the pipe's topEVT_ENTER_PIPE_VERTICAL(EVS_BindExitTriggers)
Horizontal, entered by walking into itEVT_EXIT_PIPE_HORIZONTALTRIGGER_WALL_PUSH on the pipe's openingEVT_ENTER_PIPE_HORIZONTAL(COLLIDER, EVS_BindExitTriggers)

The exit's first argument is the pipe's own entry on this map. The player lines up on it before going down the pipe, and arrives at it when they come out of the pipe. Use the enter macros in place of Exec(EnterWalk), such as in a CaseEq for the pipe's entry. If the map has a save block, check for arriving from a save first.

Changing maps from an EVT script

To send the player to another map without an exit, such as at the end of a scene, call GotoMap with the entry:

Call(GotoMap, $kmr_02.Epilogue)
Wait(100)

The Wait(100) keeps the EVT script from carrying on while the screen fades out. For a different screen transition, use GotoMapSpecial, which takes a TRANSITION_ value after the entry, such as TRANSITION_SLOW_FADE_TO_WHITE.

Testing entries and exits

Select Game > Play with the map's main.c open, and the game starts at the map's first entry, or where you last saved if that was on the map.

To start at another entry, select its Entry marker in the map editor, and select Play from here in its properties.