Skip to content

[follow-up] Preserve current health across relog like C++ #82

Description

@alseif0x

Follow-up from #79 live validation. #79 fixed current power/mana persistence; current health has the same C++ save/load shape but should be handled as its own focused issue.

Context

C++ saves current health and current powers to characters, then on load recalculates stats/max values and restores saved current health/powers clamped to their new maximums. Rust now handles represented current power correctly for #79, but current health still appears to be initialized from max health during login/stat setup and is not clearly persisted from the canonical/session player state on save.

C++ anchors

  • Player::SaveToDB writes GetHealth() before the class power fields: /home/server/woltk-trinity-legacy/src/server/game/Entities/Player/Player.cpp
  • Player::LoadFromDB reads fields.health, marks zero health as corpse/dead state, runs stat recalculation, then restores SetHealth(min(savedHealth, GetMaxHealth())): /home/server/woltk-trinity-legacy/src/server/game/Entities/Player/Player.cpp
  • The same load block restores fields.powers[] into current powers clamped to max; use this as the sibling behavior, not as a substitute for health.

Current Rust gap

  • Login/stat setup has paths that construct player combat stats with health: max_health.
  • The [02.1 follow-up] Fix SpellPower review issues from PR #78 #79 save snapshot tracks current powers, but current health is not clearly part of the C++-like snapshot/update path.
  • This means a damaged but alive character can plausibly relog as full health, which is not C++ parity.

Do

  • Load characters.health as the saved current health field and keep it distinct from power1 and max-health calculations.
  • After base stats/items/auras recalculate max health, restore current health as min(saved_health, max_health) like C++.
  • Preserve the C++ zero-health/death-state behavior boundary; do not paper over death/corpse flows by forcing max health.
  • Save current health from the authoritative canonical/session player state on logout/disconnect/periodic save where Rust already saves represented current powers.
  • Do not implement offline health regeneration here; offline rest belongs to [follow-up] Rested XP + offline rest-state parity #81 and should not refill resources.

Tests

Add focused positive/negative tests for:

  • damaged alive player relogs with the same current health, not max health.
  • saved health above recalculated max clamps to max.
  • zero saved health keeps the C++ death/corpse boundary intact.
  • health persistence does not overwrite or shift power1..power10 fields.
  • logout/disconnect save snapshot includes current health from the authoritative runtime player.

Related

Done means C++-anchored implementation, focused tests, PROTOC=/home/cdmonio/.local/protoc/bin/protoc cargo check/test, and live validation of damaged-player relog behavior against the running server.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions