Ralith / Ralith/hypermine

Finish up incomplete serialization work

Open
#428 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
202
Forks
22
Avg merge
6h 8m
Merged PRs (30d)
7

Description

I'm filing a separate issue from #397 for this to better track the work I have left for later while working on inventory code.

I plan to try to keep the below sections up-to-date to serve as a living design document that I or someone else will be able to reference while implementing the above.

Decision status

Disconnection vs deactivation

The concept of "player disconnecting" and "player character becoming inactive", while generally simultaneous, should not be baked in as fundamentally the same in the engine. Keeping them separate would allow for more options, such as a "battle royale" game mode, where disconnected players stand there doing nothing (like a sitting duck) to prevent cheating while also preventing disqualification from accidental disconnection.

Whether a player is active or inactive is included when serializing. Although all active players will be immediately logged out if a server is rebooted, we don't necessarily want to enforce that their characters should be deactivated as well.

Serialization of inactive characters

Each inactive player should have its own EntityNode-like data structure but keyed by their player ID instead of NodeId (in a different redb table from the EntityNodes in the graph). The inactive players can keep track of where they would be in if they were active (probably with a new component than the way position is tracked for active entities), but since they're inactive, they're not part of the Graph at all.

This way, they would only need to be stored in disk and never loaded into memory until they log on. An EntityNode that is part of the Graph will only contain active players, so with this idea, it would be safe to save changes to it without taking inactive players into account.

Deactivating entities not associated with players is not handled by the above logic if the key is PlayerId, but there is no clear use case for this, and we should be able to support it with some adjustments if it comes up.

Open questions

How to better represent characters in ECS

The current split between Character and InactiveCharacter is a little clunky. For instance, some existing code has to extract the name field from both for serialization.

I had expressed uncertainty about this in https://github.com/Ralith/hypermine/pull/414#discussion_r1694277120.

I'm hopeful that we will be able to bypass this issue completely and get rid of the InactiveCharacter component after we update the way InactiveCharacters are serialized to no longer be part of the Graph. Since there will be no clear reason we need inactive characters to be loaded into memory at all, we might not need to have any way to represent that active/inactive state.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Begin with the existing save/load serialization logic and the redb EntityNode table described in the issue. Separate the three unchecked design tasks, resolve the open questions about PlayerId, inactive-character storage, and Character components, and consider the work complete when each unchecked item has a settled design and implementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, databases
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.