GlymeraRevive - Downed State & Co-op Revival
When a player would take lethal damage, they don't die. Instead they go into a downed state with a gravestone at their feet and a countdown timer. A teammate can break the gravestone to revive them. If nobody comes in time, they die for real - with a 50% item / 10% durability loss.
What is GlymeraRevive?
A co-op revival system inspired by the "downed state" mechanic from games like Left 4 Dead or Apex Legends. Instead of dying on the spot when health hits zero, players are knocked down, immobilised, and stay alive long enough for their team to rescue them.
The downed player is teleported into a hidden limbo space (near the world ceiling) the moment they go down. This stops NPCs from being able to attack them while waiting for rescue - no more bears beating on an immobilised player. Their original death position is remembered, so when revived, they're teleported right back to where they fell.
Includes its own asset pack with two custom items (a Revive Gravestone block and a Bandage healing item) and one custom UI page (the give-up screen).
Features
Downed State
- Lethal damage triggers a downed state instead of death: HP forced to 1, custom
DownedComponent added, movement frozen
- Inventory is kept intact while downed (no items lost during the rescue window)
- A gravestone marker block is spawned at the death position - this is what teammates break to revive
- A
Stunned-stars particle pulses on the downed player's head as a visual cue
- A HUD page shows the countdown timer and a "Give Up & Respawn" button
Aggro-Drop via Limbo Teleport
- The downed player is teleported to a hidden zone near the world ceiling (Y=318) with a bedrock block placed below them
- All NPCs in the original area naturally lose target lock through Hytale's built-in range filter - no NPC state hacking, no behaviour-tree manipulation
- The original death position is saved server-side. On revive, the player is teleported back exactly where they fell
- The limbo bedrock block is cleaned up automatically when the player is revived or dies
Three Ways Out
- Revive: a teammate breaks the gravestone → player wakes up at
healPercent of MaxHP at the original death position
- Give Up: the downed player presses the Give-Up HUD button (or breaks their own gravestone) → real death, respawn at world spawn
- Timeout: the countdown reaches zero → real death
Real Death (Give-Up / Timeout)
- Hytale's normal death pipeline fires: drops animation, respawn at the world spawn
- Items are lost according to the world's
GameplayConfig.Death setting (default: 50% of stackable items, 10% durability loss on tools/weapons/armor)
- Server-side cleanup: gravestone removed, limbo floor removed, downed state cleared
Quit-and-Rejoin Anti-Cheat
- Persistent state file
downed-state.json tracks every currently-downed player UUID
- If a downed player quits and rejoins, they're killed on reconnect (no exploit to escape death by closing the client)
- Stale entries on plugin restart are detected and cleaned up automatically
Custom UI
- The downed-state HUD page uses Hytale's
InteractiveCustomUIPage with a custom give-up button
- The page is opened after the limbo teleport completes - opening before would have the teleport sync packet wipe the button binding (a Hytale-specific quirk that took a while to track down)
- HUD refresh runs at 1 Hz to keep button events flowing reliably
Persistence
- Downed players are recorded in
downed-state.json (atomic writes via .tmp + rename)
- Survives server restarts: any player marked as downed who rejoins gets resolved via the normal kill pipeline
Items
Revive Gravestone
- Custom block, plugin-only - no crafting recipe
- Spawned automatically at the death position when a player goes down
- Uses Hytale's native tombstone model and break decals
- The block is owner-tied: a teammate breaks it to revive, the owner breaks it to give up
- Auto-cleaned up on revive, timeout, or death
Bandage
- Custom item, asset is registered with the plugin (crafting recipe not yet wired up)
- Reserved for a future "self-revive" feature
Configuration
config.json (plugins/GlymeraRevive/config.json)
downedSeconds : 60
healPercent : 25
healDelaySeconds : 2.5
respawnPoints : { "world-name": [x, y, z] }
| Field |
Description |
downedSeconds |
How long a player can stay downed before they die automatically. Default 60 |
healPercent |
Health restored on revive, as a percentage of MaxHP. Default 25 |
healDelaySeconds |
Delay before the revive HP is applied, for a visual "wake-up" moment. Default 2.5 |
respawnPoints |
Per-world spawn override for real deaths. Empty by default - falls back to the world's own spawn |
Installation
- Place
GlymeraRevive-1.0.0.jar in your server's mods/ folder
- Start (or restart) the server
- Done. Config is auto-generated on first run.
How It Works
Downed Flow
- A player takes lethal damage in a damage event
ReviveDamageHook intercepts the event before Hytale's ApplyDamage system runs
- The plugin cancels the lethal damage, sets HP to 1, adds the
DownedComponent, and freezes movement
- A gravestone marker block is placed at the player's feet
- The player is teleported (~100 ms later) to the hidden limbo zone with a bedrock floor below them
- The give-up HUD page is opened (~400 ms after the teleport) - this ordering is critical, see Good to Know
Revive Flow
- A teammate breaks the gravestone marker
ReviveBreakBlockSystem matches the broken block against the marker map and identifies the downed player
- The plugin removes the
DownedComponent (via the entity command buffer, not the store - the event handler runs in a store-processing context where direct removal silently no-ops)
- The player is teleported back to the original death position and the limbo bedrock is cleaned up
- After
healDelaySeconds, the player's HP is restored to healPercent of MaxHP
Timeout / Give-Up Flow
- Either the tick system reaches zero on the timer, or the player presses the give-up button (or breaks their own gravestone)
- The kill is deferred to the next world execution cycle - calling
DeathComponent.tryAddComponent directly from a tick context crashes with "Store is currently processing"
- Items are reduced (50% quantity / 10% durability based on world config) before death
DeathComponent.tryAddComponent fires Hytale's normal death pipeline
- Player respawns at the configured world spawn
Quit-and-Rejoin
- The downed UUID is in
downed-state.json on disk
- The player quits while downed - the file still lists them
- On reconnect, the 1 Hz periodic scan sees: player online, UUID in
downedLog, NOT in liveDowned (in-memory)
- The kill pipeline runs in "stale" mode: items reduced,
DeathComponent added, but plugin-side teleport is skipped (Hytale's own respawn handles that, otherwise the two collide and produce an Incorrect teleportId disconnect)
Good to Know
- Limbo Y coordinate: 318. The world ceiling is
ChunkUtil.HEIGHT = 320 (so Y range 0..319). Setting blocks or teleporting outside this range silently fails - 318 is the highest usable spot
- Block-side anti-cheats: the gravestone is a normal custom block. Anyone can break it, so anti-grief assumes you trust your party. Self-break by the owner is also a valid give-up path on purpose
- PvE-only revive trigger: the heal pipeline runs off
BreakBlockEvent, not damage. Worlds with IsPvpEnabled: false filter out player-vs-player damage entirely, so a damage-based trigger wouldn't fire there
- HUD throttle: the give-up page rebuild is throttled to 1 Hz. A faster rebuild rate (e.g. 20 Hz to match the tick rate) destroys the button's event binding before clicks reach the server
- Death drop animation: programmatic
DeathComponent calls fire Hytale's death animation but not its item-drop pipeline. The plugin applies the GameplayConfig.Death losses manually before adding the component, so items disappear from inventory consistently with what would happen on a real death
- Multiple downed players simultaneously: each player has their own marker + limbo position + timer. They don't interfere with each other
Made with care by Glymera for the Hytale community