Encounter waves
Usage guide of encounters.waves: fights as data, telegraphed waves at spawn points, the next wave when the last is cleared, settings and defaults, the start_encounter verb, events and the encounter.start hook.
Room encounters with waves (encounters.waves) #
What it is for #
Fights as data. When a room with an encounter is entered, waves of enemies appear at its spawn points after a short telegraph; the next wave comes once the previous one is cleared, and the room is cleared after the last wave. The enemies themselves come from enemy.ai.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "encounters.waves" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "encounters.waves",
config: { "startDelay": 0.8, "telegraph": 0.6 } }
Needs world.rooms, enemy.ai, game.engine; installing the kit brings them along.
First example #
<!-- test: kits/game_engine/host/tests/encounters_waves.rs::waves_run_one_after_the_other_and_clear --> An encounter of two waves: two grunts, then, 0.1 s after the first wave is cleared, one brute. Starting it announces the encounter, then each wave once its spawn markers have stood for telegraph seconds.
{ "encounters": [{ "id": "pair", "waves": [
{ "spawns": [{ "enemy": "grunt", "count": 2 }] },
{ "delay": 0.1, "spawns": [{ "enemy": "brute", "count": 1 }] } ] }] }
call encounters.waves.start("pair") -> true (an encounter without wave answers false)
event encounter.started { encounter: "pair", room: "", waves: 2 }
call encounters.waves.active() -> { id: "pair", wave: 1, waves: 2, remaining: 2 }
event encounter.wave { encounter: "pair", wave: 1, count: 2 }
Settings and defaults #
| Setting | Default | Meaning |
|---|---|---|
startDelay | 0.8 | Default seconds before a wave (a wave can set its own delay). |
spread | 1.2 | Random offset around a spawn point (m). |
telegraph | 0.6 | Seconds a spawn marker shows before its enemy appears. |
countScaleVar | difficulty.enemy_count | Game variable that multiplies the enemies of each spawn row (rounded, at least 1): scale by player count or by a difficulty menu. Unset or empty: 1. |
The collection encounters holds documents { id, waves: [{ spawns: [{ enemy, count }], delay? }] }. A scene can carry its own encounters (documents or ids): the first one starts when the scene is entered, at the instances tagged encounter_spawn, and a running encounter ends with its enemies when the scene is left.
Services, events, variables #
- Service
encounters.waves:start(encounter),active(),clear(). - Verbs and conditions:
start_encounter({ "start_encounter": "enc_crypt" }; a running one is replaced). - Events:
encounter.started(encounter,room,waves),encounter.wave(encounter,wave,count),encounter.cleared(encounter,room). It listens toroom.entered,enemy.killed,entity.despawned. - Variables:
encounter.wave,encounter.waves,encounter.remaining.
Hooks and modding #
| Hook | Meaning |
|---|---|
encounter.start | An encounter is about to start in a room (a pacified room, a fight the story skips); cancelled, no wave comes and the room is cleared like a room without encounter. |
Moddable: the four settings and the collection encounters.
Limits #
Runs as the same Rust logic on the web, in the native player, Godot, Unity and Unreal. The hook runs on the web and native players; on Godot, Unity and Unreal every encounter starts as usual. Spawn points keep away from every player, not only the first.
Versions #
Kit 1.4.0 (hook and moddable settings in 1.4.0, countScaleVar in 1.3.0); service encounters.waves 1.3.0. It relies on world.rooms ^1, enemy.behaviors ^1 (from enemy.ai) and game.engine ^1.