Skip to content

Markers

A marker is a named point or shape that you place in a map with the map editor, such as where an NPC stands, where the player arrives, or where a chest sits. The map's code reads each marker by its name with a $ in front, such as $Goompa, so to move something, you drag its marker instead of changing numbers in code.

Place a marker

  1. Open the map's map.xml, and select the Markers tab of the Outline.
  2. Right-click the floor where the marker should go, and select the kind of marker to make, such as New NPC....
  3. Enter a name for the marker, such as Goompa, and select Create.

To move a marker, select it and drag the move gizmo, or type its position in its card. To rename it, right-click it in the Outline and select Rename....

Use a marker in code

Save the map and build the mod. The map's header, such as kmr_02.h, includes map.xml.h, which declares each marker as a constant.

Each kind of marker has a type in map.h, and its fields hold what you set in the editor. For example, an NPC marker named Goompa is an NpcMarker, and $Goompa.pos is its position, a Vec3f with .x, .y, and .z. The fields are constants, so they work in data, such as an NpcData, and in EVT scripts.

Position

A Position marker is a point, such as where an item appears or where an effect plays. It's a PositionMarker, with one field, pos.

Call(MakeItemEntity, ITEM_SHOOTING_STAR, $ShootingStar.pos.x, $ShootingStar.pos.y, $ShootingStar.pos.z,
    ITEM_SPAWN_MODE_FIXED_NEVER_VANISH, GF_KMR02_Item_ShootingStar)

Entry

An Entry marker is where the player appears when they enter the map, facing the marker's direction. It's an EntryMarker, with pos, yaw, index, and map. index is the entry's place in the map's list of entries, and map is the name of the map.

The map's entries are its Entry markers in the order they appear in the Outline. To do something when the player arrives at one entry, compare the entry ID with that marker's index:

Call(GetEntryID, LVar0)
Switch(LVar0)
    CaseEq($Front.index)
        Exec(EVS_EnterFromTown)
EndSwitch

To move an entry to a different place in the list, drag its marker in the Outline. Code that uses index follows it, including code in other maps.

Send the player to another map

The build also puts each map's entries in a header in the area's folder, such as world/area/kmr/kmr_03.h. A map that includes it gets the entries as fields of a constant named after the map, so the entry $Front in kmr_03 is $kmr_03.Front:

#include "world/area/kmr/kmr_03.h"

EvtScript EVS_ExitWalk_kmr_03 = EVT_EXIT_WALK(60, $West, $kmr_03.Front);

The exit macros, such as EVT_EXIT_WALK and EVT_EXIT_SINGLE_DOOR, take the entry the player leaves by and the entry they arrive at. GotoMap and GotoMapSpecial take the entry they arrive at:

Call(GotoMap, $kmr_03.Front)
Call(GotoMapSpecial, $kmr_03.Front, TRANSITION_STANDARD)

For more about exits, see Entries and exits.

NPC

An NPC marker is where an NPC starts, and the area it wanders, patrols, and watches for the player in. It's an NpcMarker, with pos, yaw, and territory. You set the territory in the marker's card, and territory is an EnemyTerritory ready for the NPC's data:

NpcData NpcData_Goompa = {
    .id = NPC_Goompa,
    .pos = $Goompa.pos,
    .yaw = $Goompa.yaw,
    .territory = $Goompa.territory,
    ...
};

Entity

An Entity marker is an object the game makes at a position, such as a save block, a chest, or a switch. You choose its type and settings in its card, such as the item a block holds or the flag that records that a chest was opened. It's an EntityMarker.

Make the entity from an EVT script, usually the one that makes the map's entities:

EvtScript EVS_MakeEntities = {
    Call(MakeMarkerEntity, $SaveBlock)
    Call(MakeMarkerEntity, $PipeToTunnels)
    Return
    End
};

Like MakeEntity, MakeMarkerEntity returns the entity's index in LVar0.

Path

A Path marker is a set of points where each point can lead to any number of others, such as a route, a patrol, or the spaces of a board game. It's a PathMarker, with count and points.

Draw a path

  1. Right-click the floor where the path should start, and select New Path....
  2. Enter a name for the path, such as Route, and select Create. The new path has one point, where you right-clicked.
  3. Select the Paths button in the view's toolbar, which shows an arrow leading away from a point.
  4. Drag from the path's point to another place on the floor. When you let go, a new point appears there, and the first point leads to it.

Paths mode shows every path in the map, and draws their points over everything else so you can reach them behind scenery. The arrows along each line show which way it leads. In Paths mode, the mouse edits whichever path you're pointing at:

ToDo this
Add a point that a point leads toDrag from the point to an empty spot.
Connect two pointsDrag from the first point to the second.
Disconnect two pointsDrag from the first point to the second again. The line turns red before you let go.
Add a point in the middle of a lineClick the line, or drag from it to where the new point should go.
Route a line through an existing pointDrag from the line to the point.
Delete a pointRight-click it, or select it and press Delete.
Remove a lineRight-click it.
Move pointsHold Alt and drag a point.

A drag snaps to a point of the same path when it ends near one, and that point grows so you can see which one you'll hit. Deleting a point keeps the path connected: the points that led to it lead to the points it led to instead.

To move points with the move gizmo, select Select mode, select the path's marker in the Outline, and click one of its points. The point's card shows its position, so you can also type exact values there.

Use a path in code

Each point is a PathMarkerPoint, with a position and the indices of the points it leads to:

typedef struct PathMarkerPoint {
    Vec3s pos;
    u16 nextCount;
    const u16* next;
} PathMarkerPoint;

To refer to a point in code, select it and enter a name in the Name field of its card, such as Start. $Route_Start is then that point's index in $Route.points. This function finds where a point leads, taking the first way when there's more than one:

s32 next_stop(s32 stop) {
    const PathMarkerPoint* point = &$Route.points[stop];
    return point->nextCount > 0 ? point->next[0] : -1;
}

Sphere

A Sphere marker is a ball, such as the area a bomb has to explode in to break a wall. It's a SphereMarker, with pos and radius.

BombTrigger BombPos_Wall = {
    .pos = $BombWall.pos,
    .diameter = 2.0f * $BombWall.radius,
};

Cylinder

A Cylinder marker is an upright cylinder, such as an area the player can stand in. It's a CylinderMarker, with pos, the center of its base, and radius and height.

f32 dx = playerStatus->pos.x - $Fountain.pos.x;
f32 dz = playerStatus->pos.z - $Fountain.pos.z;
b32 inFountain = SQ(dx) + SQ(dz) < SQ($Fountain.radius);

Volume

A Volume marker is a box, such as where water drips from or where flowers can grow. It's a VolumeMarker, with min and max, its opposite corners:

DripVolume Drips[] = {
    {
        .minPos = { $Drip.min.x, $Drip.min.z },
        .maxPos = { $Drip.max.x, $Drip.max.z },
        .startY = $Drip.max.y,
        .endY = $Drip.min.y,
    },
};

Camera target

A Camera Target marker is a place for the camera to look at and the camera settings to use there, such as one shot of a scene. It's a CamTargetMarker.

In its card, give the marker camera settings, which work like a camera zone's, or select Camera Settings From Zone to use the settings of the zone below it. With zone settings, Override Boom Length replaces the zone's distance and Override Boom Angles replaces its angles. Select Use Current View to set the marker up from the editor's camera, and Toggle Preview to see the shot.

Point the camera at the marker with UseCamTarget:

EvtScript EVS_ShowShore = {
    Call(UseCamTarget, CAM_DEFAULT, $Shore)
    Wait(30)
    Call(ResetCam, CAM_DEFAULT, 4.0)
    Return
    End
};

If the marker has Generate Camera Pan selected, UseCamTarget pans the camera there at its Move Speed and waits until it arrives. Otherwise, it only changes the camera's settings and target, and you start the pan with PanToTarget, as in Moving the camera from an EVT script.

Light

A Light marker lights sprites, such as a torch casting a red glow on the player. Lights only show when the map has sprite shading. To turn it on, select nothing to see the map's settings, and select Sprite shading under Lighting. There you also set the Base color, the color of a sprite's unlit side, and the Edge offset, how wide the lit edges of sprites are.

A map can have up to 7 Light markers. The shading applies when the map loads, before its main EVT script runs, so the map needs no code for it.

A battle stage's variants can differ in whether they're shaded, so a stage's shading doesn't apply until a script sets it. The stage's header gives its shading as MAP_SPRITE_SHADING, so set it in the pre-battle script of each variant that uses it:

EvtScript EVS_PreBattle = {
    Call(SetSpriteShading, MAP_SPRITE_SHADING)
    Return
    End
};