NSSTC / sim-ecs

Batteries included TypeScript ECS
https://nsstc.github.io/sim-ecs/
Mozilla Public License 2.0
84 stars 12 forks source link

prefab handle + save file = undefined #29

Open minecrawler opened 3 years ago

minecrawler commented 3 years ago

Given a State, which is possible to create at the moment, which manages its data with a prefab, there currently is no way to clean up prefab-bound entities if the data was loaded from a save.

export class GameState extends State {
    _systems = [...];
    prefabHandle?: TPrefabHandle;

    create(actions: ITransitionActions) {
        if (actions.getResource(MenuSelection).continueLastGame) {
            // no way to fill the prefab handle here!
            loadGameFromSave(actions);
        } else {
            this.prefabHandle = createNewGameFromPrefab(actions);
        }

        actions.maintain();
    }

    destroy(actions: ITransitionActions) {
        // target: remove the `if`, we should always clean up!
        if (this.prefabHandle) {
            actions.unloadPrefab(this.prefabHandle);
        }
    }
}

One idea might be to pass a unique ID to the loadPrefab() method, so it can mark entities and find them when loading a save, but that sounds complex for users. Maybe the ID could be a hash (of the prefab) and a new method (const prefabHandle = world.linkPrefab(prefabObj)) could be used to retrieve the handle, however that sounds bad when it comes to using updated prefabs on an old save. Then there also must be a method to upgrade the prefab handle to the new prefab version.

A completely different way to handle this might be to make it explicit which data is saved, always require a prefab to be loaded, and have saved data overwrite the prefab data. This means a lot more syncing, though, since then a prefab needs to include the necessary information to do such a sync, or the ecs needs an algorithm which can bind the data, which, just like before, sounds like a problem when changing the prefab slightly for a version update.

One more way would be to chunk the data in the save to make extraction possible per chunk, where a chunk could be tied to a state, or anything a user may want, really.

I won't stall v0.3.0 for a fix for this problem, though, since progress is slow as is.

minecrawler commented 3 years ago

Tags landed in v0.3.0, which makes it easy to tag entities with the prefab handle. The logic should work like this:

  1. When loading a prefab, generate a UUID as handle (instead of a number). Tag all new entities with the handle and use a way for the tag which makes it distinguishable as a prefab handle
  2. When loading a save or prefab, fill the prefab-cache (world.entityLinks), too
  3. Unloading will work out of the box

For now, storing and loading the actual handle is left to the user. I am open to ideas to make it simpler