Zones & bounds
Patterns for the spatial side of a game: keeping players in bounds, tracking occupancy, and gating zones by state.
Soft out-of-bounds
Section titled “Soft out-of-bounds”The friendliest boundary: a toast when you leave, a toast when you return. No elimination. Both conditions are edge-triggered, so they fire once per crossing.
- id: out_of_bounds when: { kind: left_zone, who: any, zoneId: play_area } do: - { kind: send_event, to: same, event: { type: toast, text: "Out of bounds." } }
- id: back_in when: { kind: entered_zone, who: any, zoneId: play_area } do: - { kind: send_event, to: same, event: { type: toast, text: "Back in bounds." } }Source: apps/wage-engine/src/games/tag/game.yaml.
Convert a zone edge into a state flag
Section titled “Convert a zone edge into a state flag”To let other rules ask “is this player in the zone?”, flip a flag on entry/exit
(this is the King of the Hill inHill pattern):
- id: enter_hill when: { kind: entered_zone, who: any, zoneId: hill } do: [{ kind: set_state, target: same, key: inHill, value: true }]
- id: leave_hill when: { kind: left_zone, who: any, zoneId: hill } do: [{ kind: set_state, target: same, key: inHill, value: false }]Now state.inHill is queryable by a scoring tick rule. See
Scoring.
Hard walls and gated zones
Section titled “Hard walls and gated zones”For boundaries the engine should enforce (reject the position update), use zone flags in the map rather than rules:
navigable: false— an unconditional wall; players can’t enter.blockedBy: { key, value }— keep matching players out (e.g. a base only your team may enter).confinedBy: { key, value }— keep matching players in (e.g. a holding pen until released).
zones: - id: red_base blockedBy: { key: teamId, value: blue } # blue players can't step into red base shapes: [ /* … */ ]See Map & zones for the full field list.
Keep spawns off a sub-area
Section titled “Keep spawns off a sub-area”Punch an exclusion cutout so random item
spawns (spawn_item inZone / items spawnZoneId) avoid part of a zone — e.g.
keep loot off the ships:
shapes: - { id: island, kind: rectangle, from: { x: -35, y: -35 }, to: { x: 35, y: 35 } } - { id: no-ship, kind: circle, center: { x: -35, y: 35 }, radius: 15, exclusion: true }Source: apps/wage-engine/src/games/pirates_booty/game.yaml.