Grimwar/VSig
Use VSig to connect Grimwar entities and react to map or round events. Start with a working map from Grimwar/Mapping. Vertex/VSig explains the editor and language basics; Grimwar/VSig reference covers expressions, schedules, modules, and the standard library.
Make a door open from a trigger
- Place a
func_doornamedmain_doorand parent its geometry underneath it. Set a useful Move Direction and leave Start Locked off. - Place a
trigger_multiplenamedentry_triggerin front of it. Set Allowed Activators to Participants and Allowed Teams to Order and Union. - Keep those entity names at the hierarchy root for this example.
- Save the map and open Code → Map script. Enter the script below.
- Build with Play in Game. Enter the trigger, leave it, and check that the door opens and closes.
scene "Door test"
ref entry: trigger_multiple match entry_trigger
ref door: func_door match main_door
on entry.start_touch:
door.open
on entry.end_touch_all:
door.close
A ref gives an entity a script alias. start_touch fires for an accepted occupant; end_touch_all fires after the last occupant leaves. The door's own open and close outputs fire when its motion finishes.
If you move the door under a group named Building, update its match path to Building/main_door. A wildcard such as Doors/Door* can target several doors, but reading a state or property requires exactly one match.
Server and client logic
Gameplay handlers run on the server by default. Ambient audio is client presentation. Add an env_ambient named door_audio, choose a one-shot sound, and disable Play On Start. Add these lines to the door script:
ref sound: env_ambient match door_audio
client on door.open:
sound.play
The clients hear the sound when the door finishes opening. The compiler checks the authority of entity calls. Use the entity reference to check the contract before choosing a handler side.
Map and round events
These global events do not need an entity:
| Event | Use |
|---|---|
map.ready |
Set up once map entities and required map scripts are ready. |
round.warmup |
Apply warmup behavior. |
round.pre_round |
Reset round state before play. |
round.live |
Start live-round behavior. |
round.overtime |
Handle overtime. |
round.post_round |
Stop round tasks and show the result. |
round.intermission |
Handle the interval between matches or rounds. |
gravewar.wave_started(wave: int, zombies: int) |
React to a Gravewar wave starting. |
gravewar.wave_ended(wave: int, result: string) |
React to a Gravewar wave ending. |
Use once on map.ready: for setup once per map load. Use round events for work that must repeat each round. They only fire when the running mode reaches that phase.
Delays and repeating work
A wait pauses one chain. A named schedule lets you cancel pending work:
on round.pre_round:
cancel open_gate
door.close
on round.live:
schedule open_gate after 3s:
door.open
on round.post_round:
cancel open_gate
door.close
This fragment uses the door ref from the first example. For repeated actions, use schedule pulse every 1s: and cancel it when its round or activity ends. Avoid comparing elapsed time with exact equality; use a one-shot schedule or indexed timer ticks. See the schedule reference.
Entity lifecycle and operational state
kill permanently removes an entity until the map reloads. Use an entity's reversible action when that is what you need: door.close, damageable.reset, or an operational entity's disable.
Operational entities support enable, disable, toggle, enabled, disabled, and is_enabled. The meaning of disabled depends on the type; it does not remove the entity from the map. See the lifecycle reference.
Activator, caller, and self
!activator identifies what began a signal chain, such as a touching participant. !caller identifies the entity that made the current call, and !self identifies the current entity. These values travel with that execution, including delayed work.
They do not provide arbitrary access to game objects or permission to kill a player. Use the context reference for supported procedural calls.
Reuse an assembly
Put reusable modules in local .vsiglib files, or use a logic_script host that selects a library and module. Hierarchy binding lets each placed assembly find its own child entities.
Grimwar's spawn-door prefabs already include a hierarchy-bound script host. Give its alias an explicit unique name if the map script needs to call it. See modules and script hosts.
Use a VMod when you need player services, server commands, persistent storage, or custom mode control. A VMod can subscribe to map signals and emit under its own mod:<mod-id> alias. Clients do not execute VMod code.
For an extraction zone, trigger_multiple.execute emits executed with a participant snapshot token. The subscribed VMod resolves it during that callback; the token expires when dispatch returns. See the VMod example.
Build and test
Resolve the Code workspace diagnostics, save externally edited sources, and rebuild the map. Compilation embeds VSig in the scene. Test each route in Grimwar, including a second round and a map reload. A changed loose script beside the installed add-on does not replace the embedded program.