Player Die Scripts
Die scripts are global player events that execute when OpenBOR processes a native player death and life loss. Numbered scripts provide slot-specific behavior, while dieall.c provides one shared listener for every player.
The numbered series consists of:
data/scripts/die1.cdata/scripts/die2.cdata/scripts/die3.cdata/scripts/die4.c
The shared listener is:
data/scripts/dieall.c
OpenBOR distinguishes an entity entering a dead state, a player losing a life, and an entity being killed or removed from play. The Die series represents the player-life event. This makes it useful for life-loss penalties, cooperative defeat handling, continue systems, player-specific statistics, encounter adjustment, audiovisual feedback, and any other system that should respond when a player leaves active play through the native death routine.
Usage
Create any desired Die-script files in data/scripts. OpenBOR loads them automatically, so no model, level, or project command is required.
die#.c is documentation shorthand in which # represents the player number. Literal filenames use 1 through 4.
| File | Scope | Player identification |
|---|---|---|
data/scripts/die1.c
|
Player 1 | Filename - index 0
|
data/scripts/die2.c
|
Player 2 | Filename - index 1
|
data/scripts/die3.c
|
Player 3 | Filename - index 2
|
data/scripts/die4.c
|
Player 4 | Filename - index 3
|
data/scripts/dieall.c
|
Every player | Local variable playerindex
|
Projects may use only the numbered files, only dieall.c, or both layers together.
Die Event
The Die series executes when OpenBOR's native player-death routine processes a player leaving active play. Common causes include completing a normal defeat sequence, falling into a pit, moving beyond the permitted off-screen boundary, or another condition routed through native player death handling.
This event is not a general entity-death listener. It does not execute merely because an entity enters a dead state or because killentity() removes an entity through an unrelated path. The event belongs specifically to player-slot life processing.
Each native player death runs the applicable Die-script chain once. If the player has another life, OpenBOR later creates the replacement player entity and executes the Respawn series. If no lives remain, the Respawn series does not follow.
Execution Order
OpenBOR performs the relevant player-death sequence in this order:
- OpenBOR identifies the dying entity's player slot.
- The player's life count is reduced when native life deduction is active.
- The corresponding numbered script,
die1.cthroughdie4.c, executes when present. dieall.cexecutes when present and receivesplayerindex.- OpenBOR clears the player slot's entity reference and stores health and magic values for a possible respawn.
- OpenBOR removes the old entity or leaves an inert corpse according to the model's death configuration.
- If no lives remain, OpenBOR performs the applicable continue or game-over preparation and ends the death routine.
- If lives remain, OpenBOR creates the replacement player entity and executes the numbered and shared Respawn scripts.
- Native post-respawn enemy-drop, rumble, and timer-reset behavior continues as configured.
The player's remaining-life value is already current when either Die-script layer begins. The dying entity is also still assigned to the player slot and can be retrieved through the player property API during the event.
The numbered script always executes before dieall.c. Shared logic can consequently consume state established by the slot-specific script during the same death event.
Numbered Die Scripts
Numbered Die scripts are tied to the player slot identified by their filename. They receive no automatic event variables because the player identity is already fixed by that filename.
void main()
{
// die3.c always represents Player 3, player index 2.
setglobalvar("player_three_defeated", 1);
setglobalvar("party_state_changed", 1);
}
Slot-specific files are convenient for asymmetric penalties, unique defeat effects, fixed cooperative roles, individual statistics, or other behavior tied to one player position.
Dieall
dieall.c is the shared listener for every player slot. OpenBOR supplies one automatic local variable:
| Variable | Type | Description |
|---|---|---|
playerindex
|
Integer | Zero-based index of the player whose native death routine is being processed. Values range from 0 through 3 for Players 1 through 4.
|
void main()
{
int remaining_lives = getplayerproperty(playerindex, "lives");
setglobalvar("last_defeated_playerindex", playerindex);
setglobalvar("last_defeat_remaining_lives", remaining_lives);
}
The zero-based index matches OpenBOR's player property and scripting conventions:
playerindex
|
Player label | Corresponding numbered script |
|---|---|---|
0
|
Player 1 | die1.c
|
1
|
Player 2 | die2.c
|
2
|
Player 3 | die3.c
|
3
|
Player 4 | die4.c
|
dieall.c does not receive an automatic entity reference. The dying entity remains available from the player slot until both Die-script layers finish:
void main()
{
void dying_entity = getplayerproperty(playerindex, "entity");
if (dying_entity)
{
setglobalvar("defeat_effect_playerindex", playerindex);
}
}
Creators can use dying_entity immediately with entity properties, visual effects, audio ownership, bindings, or other systems that operate on an active entity reference. OpenBOR clears the player slot's reference after dieall.c returns.
Life Count Timing
Native life deduction occurs before the Die scripts. Reading the player's lives property therefore returns the remaining count rather than the count that existed before death.
OpenBOR decides between exhausted-life handling and respawn only after both Die-script layers finish. Creators may therefore modify the remaining life count during the event to implement shared-life pools, revive tokens, insurance systems, checkpoint allowances, or other custom continuation rules.
void main()
{
int remaining_lives = getplayerproperty(playerindex, "lives");
int revive_tokens = getglobalvar("revive_tokens");
if (remaining_lives <= 0 && revive_tokens > 0)
{
changeplayerproperty(playerindex, "lives", 1);
setglobalvar("revive_tokens", revive_tokens - 1);
setglobalvar("revive_token_used", playerindex);
}
}
The numbered script can apply slot-specific life rules first. dieall.c then receives the same event and can reconcile the resulting life count before OpenBOR chooses its next branch.
void main()
{
int remaining_lives = getplayerproperty(playerindex, "lives");
if (remaining_lives <= 0)
{
setglobalvar("player_out_playerindex", playerindex);
setglobalvar("check_continue_state", 1);
}
else
{
setglobalvar("prepare_respawn_playerindex", playerindex);
}
}
This timing allows one listener to distinguish a death that will proceed to respawn from a death that exhausts the player's current life supply. Native options that prevent life consumption naturally leave the life count unchanged.
Combining Numbered and Shared Logic
Both layers may participate in the same death event. Their fixed execution order supports a useful division of responsibility:
- Numbered
die#.cperforms slot-specific defeat handling. - Shared
dieall.cperforms project-wide reconciliation after that handling.
For example, numbered scripts might apply different penalties to asymmetric cooperative roles while dieall.c updates a shared defeat counter, checks the remaining-life state, changes encounter intensity, and prepares common audiovisual feedback.
Die, Death, and Kill Hooks
| Hook | Scope | Event represented | Entity availability |
|---|---|---|---|
| Ondeathscript | Model | Entity enters native death processing | self is the dying entity
|
Numbered die#.c
|
One player slot | Native player life-loss routine | Player slot still references the dying entity |
dieall.c
|
Every player slot | Shared native player life-loss listener | Retrieve the dying entity using playerindex
|
| Onkillscript | Model | Entity is being removed from play | self is available immediately before removal
|
| Respawn Scripts | Player | Replacement player entity has been created after life loss | Player slot references the new entity |
These hooks represent different transitions and may all participate in one defeat sequence. Their separation allows entity-specific death behavior, player-life systems, removal cleanup, and replacement-player setup to remain independent.
Choosing a Die Script
| Need | Recommended hook |
|---|---|
| Behavior unique to one fixed player slot | Corresponding die#.c
|
| The same life-loss behavior for every player | dieall.c
|
| Fixed slot handling followed by common party reconciliation | Numbered die#.c and dieall.c together
|
| Behavior for any entity entering death processing | Ondeathscript |
| Cleanup immediately before an entity is removed from play | Onkillscript |
| Setup for the newly created replacement player | Respawn Scripts |
Other Uses
Quick applications include:
- Life-loss penalties - Remove resources, reset streaks, alter score systems, or apply player-specific consequences.
- Cooperative defeat handling - Update shared lives, revival opportunities, team resources, rescue systems, or remaining-party rules.
- Encounter adjustment - Reduce or increase pressure, redirect opponents, change hazards, or suspend objectives when a player falls.
- Defeat presentation - Trigger sounds, screen effects, announcements, portraits, controller feedback, or spectator transitions.
- Continue systems - Detect exhausted lives, prepare custom continue state, or coordinate project-specific game-over flow.
- Statistics and achievements - Record defeat counts, remaining lives, player order, survival milestones, or challenge failures.
- Role management - Release responsibilities, transfer shared ownership, select a new leader, or update cooperative formations.
- Development tools - Log player-death order, verify remaining-life values, inspect the dying entity, or test corpse and respawn configurations.
Related Scripts
| Script | Relationship |
|---|---|
| Respawn Scripts | Execute after the replacement player entity is created when lives remain. The numbered script runs before respawnall.c.
|
| Join Scripts | Execute when a player completes an in-progress join rather than returning from death. |
| Ondeathscript | Model-level hook for entity death processing. |
| Onkillscript | Model-level hook that executes immediately before entity removal. |
| Onspawnscript | Model-level creation hook that may execute for the replacement player entity before the Respawn series. |