Skip to content

Freeze & thaw

A tag that freezes instead of handing off a role, plus a second interaction that lets a free runner thaw a frozen one. This is the Freeze Tag shape.

playerJoinStates:
- { it: true, frozen: false } # the tagger(s)
- { it: false, frozen: false } # runners (last entry repeats)
theme:
playerMarkers:
- { when: { key: frozen, value: true }, color: "#60a5fa" } # icy blue
- { when: { key: it, value: true }, color: "#dc2626" } # tagger red
- { color: "#16a34a" } # free runner green

First-match-wins, so list frozen first if a frozen player could also be “it”.

A tagger touching a free runner freezes them — note we do not hand off it:

interactions:
- verb: freeze
label: "Freeze"
rangeMeters: 5
initiatorFilters: [{ key: "state.it", value: true }]
targetFilters: [{ key: "state.frozen", value: false }]
rules:
- id: freeze
when:
kind: and
children:
- { kind: interaction, verb: freeze } # same = tagger, other = runner
- { kind: state_equals, who: other, key: it, value: false }
do:
- { kind: set_state, target: other, key: frozen, value: true }
- { kind: send_event, to: other, event: { type: toast, text: "Frozen! Wait for a thaw." } }

A free runner reaching a frozen one unfreezes them. Use a separate interaction so the player chooses to thaw:

interactions:
# …plus the freeze interaction above…
- verb: thaw
label: "Thaw"
rangeMeters: 3
initiatorFilters: [{ key: "state.frozen", value: false }, { key: "state.it", value: false }]
targetFilters: [{ key: "state.frozen", value: true }]
rules:
- id: thaw
when: { kind: interaction, verb: thaw } # same = thawer, other = frozen player
do:
- { kind: set_state, target: other, key: frozen, value: false }
- { kind: send_event, to: other, event: { type: toast, text: "Thawed — run!" } }

The taggers win the instant zero runners are unfrozen:

- id: all_frozen
when:
kind: and
children:
- { kind: count_state, who: any, key: frozen, value: false, n: 0 } # no free runners left
- { kind: state_equals, who: same, key: it, value: true }
- { kind: state_equals, who: same, key: announced, value: false }
do:
- { kind: set_state, target: same, key: announced, value: true }
- { kind: send_event, to: any, event: { type: toast, text: "All frozen — taggers win!" } }
- { kind: end_game }

This pattern is a variation on Tagging — same interaction machinery, different state effect (disable + revive instead of handoff). See the Freeze Tag game in the catalog.