Checkpoints
Before this: Maps, Mods, Per-Player State
Checkpoints along a course. Each player’s furthest checkpoint is remembered, and a player who falls off, or comes back from the spawn point, is sent back to it.
Contents
You need
- Three bricks with an Attached Zone each: the checkpoints, in course order.
- One Attached Zone under the course, where a falling player lands.
- One Attached Zone across the way out of the spawn area, where every player walks after spawning.
zone1 "Zone Ref" -> chip cp1
zone2 "Zone Ref" -> chip cp2
zone3 "Zone Ref" -> chip cp3
zone4 "Zone Ref" -> chip fall
zone5 "Zone Ref" -> chip spawn
Code
const COUNT = 3 // checkpoints on the course, shown in the message
@left in cp1: zone
@left in cp2: zone
@left in cp3: zone
@left in fall: zone
@left in spawn: zone
var reached: Map<string, int>
var spot: Map<string, vector>
mod reach(who: character, n: int) {
let id = who.GetUserId()
let had = reached.get(id)
if had.Found && had.Value >= n {
return
}
reached.set(id, n)
spot.set(id, who.GetLocation())
who.ShowStatusMessage("Checkpoint ${n} of ${COUNT}")
}
mod sendBack(who: character) {
let saved = spot.get(who.GetUserId())
if saved.Found {
who.SetLocation(saved.Value)
}
}
on ZoneEntered(zone = cp1) -> (character) { reach(character, 1) }
on ZoneEntered(zone = cp2) -> (character) { reach(character, 2) }
on ZoneEntered(zone = cp3) -> (character) { reach(character, 3) }
on ZoneEntered(zone = fall) -> (character) { sendBack(character) }
on ZoneEntered(zone = spawn) -> (character) { sendBack(character) }
Wire it
- Compile the chip and paste it in-game near the course.
- Wire each checkpoint’s Attached Zone Zone Ref to
cp1,cp2andcp3, in the order players reach them. - Wire the zone under the course to
fall, and the zone at the way out of spawn tospawn. - Make the checkpoint zones tall and wide enough that nobody can jump past one, and the fall zone wide enough to catch everyone.
Check it in game
- Walk into the first checkpoint: a status message says “Checkpoint 1 of 3”.
- Walk back through it: no message, since you have reached it already.
- Reach the second checkpoint, then jump off the course: you land in the fall zone and appear back at the second checkpoint.
- Walk back into the first checkpoint and fall again: you still go back to the second one. Progress only moves forward.
- Die (or reset), and walk out of spawn: you are moved to your checkpoint.
- A friend who has not reached any checkpoint falls: nothing moves them.
Change it
- Add a fourth checkpoint: a
cp4pin, a handler that callsreach(character, 4), andCOUNT = 4. - Make players take the checkpoints in order: in
reach, readlet last = if had.Found then had.Value else 0and return unlesslast == n - 1. - Add a restart button at the start: wire a Button’s Press Count
and Character to two new pins (an
intand acharacter). Press Count is how many players hold the button right now, so in anon Change(...)handler on it, keep the last count in avarand act only when the count went up:if holding > last { ... }thenlast = holding. Inside theif, remove that player’s entries fromreachedandspot. That catches every press, even one made while another player still holds the button, and ignores releases. - The game also has its own Checkpoint brick, which sets a player’s spawn point without any wires. Try it next to this part.
How it works
Every zone has its own on ZoneEntered handler (Reacting to the
Game), and the checkpoint handlers share one
mod, reach, which takes the player and the
checkpoint’s number. Progress lives in two maps
keyed by GetUserId(), so it survives a respawn, when the player gets a new
character but keeps their user id. spot stores where the player stood when
they reached the checkpoint, a vector, and
SetLocation puts them back there. .Found guards every read, since a
player who has reached nothing has no entry.
This part does not choose where a player respawns. The spawn zone works
around that: a player who respawns walks out of the spawn
area, enters the zone, and is moved on to their checkpoint.
Back to Parts.