Skip to content

Conversation

@MistakeNot4892
Copy link
Contributor

@MistakeNot4892 MistakeNot4892 commented Oct 20, 2025

Description of changes

  • Adds /atom/Serialize() to return an assoc list of relevant values suitable for saving out.
  • Adds /atom/Preload() and /atom/PreloadData() and hooks in SSatoms flush to deserialize atoms during flush.
  • Adds /datum/level_data/load_persistent_data() and /datum/level_data/save_persistent_data() as entrypoints for per-level persistence.
  • Adds a fire() override to SSpersistence to do a periodic level data save.
  • Converts the innards of the previous persistence system to use the new save/load handlers and procs.

General flow of level persistence:

  • Saving:
    • SSpersistence periodically iterates the z-level list, finds levels that want to serde, and calls save_persistent_data()
    • Levels return a list of instances to get_persistent_instances(), instances have Serialize() called and return a list of modified fields.
    • Fields are serialized (to JSON with the default handler) and written to disk.
  • Loading:
    • SSmapping initializes and calls preload_persistent_data() and load_persistent_data() on relevant /datum/level_data z-level objects.
    • load_persistent_data() creates the base instances and (for atoms) sets __init_deserialisation_payload with the data loaded from tile.
    • SSatoms flush calls Preload() on all deserialized atoms which pre-populates vars on the atom.
    • Ssatoms proceeds to Initialize() atoms as normal.

TODO

  • Implement area serde.
  • Implement datum serde.
  • Implement non-turf loc for serialized atoms.
  • Test with implementation on tradeship.
  • Test that wall construction serializes.
  • Test that wall removal serializes.
  • Test that removing flooring serializes.
  • Test that adding flooring serializes.
  • Test that roofing turf serializes.
  • Test that changing turf height serializes.
  • Get simplemob serde to work.
  • Test legacy persistence:
    • Graffiti
    • Filth
    • Trash
    • Paper
    • Books
  • Implement some kind of grandfather check to convert old persistence format to new.
  • Test legacy migration.
    • Graffiti
    • Filth
    • Trash
    • Paper
    • Books
  • Implement first-run level generation (suspend level gen if we initialized a level via serde)
  • Test level generator reordering (split into 2nd PR?) Reverted these changes.

Future work

  • Completely integrate /decl/persistence_handler into this system instead of the bespoke serde on SSpersistence. ended up largely doing this in this PR.
  • Add a bespoke system for serializing area changes (blueprints etc) on a z-level.

Why and what will this PR improve

Adds a framework for handling persistence in the future.

Authorship

Myself.

Changelog

Nothing player-facing.

@MistakeNot4892 MistakeNot4892 added has dependencies This PR should not be merged prior to any PRs linked in body or comments. work in progress This PR is under development and shouldn't be merged. labels Oct 20, 2025
@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch 2 times, most recently from 1802990 to 1dd8215 Compare October 20, 2025 14:46
@MistakeNot4892
Copy link
Contributor Author

Depends on #5175

Comment on lines 48 to 50
// Is this actually desirable? People moving around or modifying
// atoms across save could result in inconsistent data.
set waitfor = FALSE
Copy link
Member

@out-of-phaze out-of-phaze Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you'd have to actually add if(_persistent_save_running) return hooks into move and other client-driven/verb things to make it block anyway, is the thing. i'm not sure waitfor = TRUE would be enough. so it'd only be a partial solution either way

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could potentially suspend all subsystems and kick people back to the lobby during saves, maybe? Similar to how DMMS suspends fluids and such until the run finishes.

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch from 1dd8215 to 4d406a4 Compare October 28, 2025 02:47
@MistakeNot4892 MistakeNot4892 added ready for review This PR is ready for review and merge. and removed has dependencies This PR should not be merged prior to any PRs linked in body or comments. work in progress This PR is under development and shouldn't be merged. labels Oct 28, 2025
@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch from 4d406a4 to 96e2512 Compare October 28, 2025 03:50
@MistakeNot4892
Copy link
Contributor Author

MistakeNot4892 commented Oct 28, 2025

I'm going to call datum and area serde out of scope for this PR, I don't have any clue how to handle them in a clean way.

The atom side of this appears to be working fine, I've tested with a debug item and it all seems pretty good.

EDIT: Went ahead and just let it instance datums with the serde data as a list arg, in case it's needed in the future.

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch 6 times, most recently from aa31be7 to 2862dd3 Compare October 28, 2025 08:55
@MistakeNot4892 MistakeNot4892 added has dependencies This PR should not be merged prior to any PRs linked in body or comments. work in progress This PR is under development and shouldn't be merged. and removed ready for review This PR is ready for review and merge. labels Oct 28, 2025
@MistakeNot4892
Copy link
Contributor Author

Slipped and accidentally added turf serde, limited testing on Shaded Hills but needs proper testing before I sign off on it.

@MistakeNot4892
Copy link
Contributor Author

Depends on #5182

@MistakeNot4892
Copy link
Contributor Author

MistakeNot4892 commented Oct 28, 2025

Testing notes:

  • shutter state needs to be serialized on walls
  • fluids need to be serialized on floors
  • flooring is busted

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch 6 times, most recently from f491ffe to 3a905e3 Compare October 28, 2025 23:40
@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch 2 times, most recently from 47f36b1 to ca63ff2 Compare November 28, 2025 02:03
@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch from ca63ff2 to bfb3ca2 Compare December 6, 2025 12:01
Copy link
Member

@out-of-phaze out-of-phaze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs rebase

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch 3 times, most recently from b9679aa to c669cfa Compare December 20, 2025 11:12
@MistakeNot4892
Copy link
Contributor Author

Current outstanding issue with this one is that I cannot for the life of me seem to get map templates placed during init to flag the turfs as changed. Generating on Shaded Hills and restarting leaves template-shaped sections of mask turfs. Not sure what the issue is, it happened even after I made all ChangeTurf() calls and relevant sections of DMMS flag the turfs directly. I am assuming that something is newing /turf directly and not flagging.

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch from c669cfa to 5c195d6 Compare December 20, 2025 11:16
@out-of-phaze
Copy link
Member

Current outstanding issue with this one is that I cannot for the life of me seem to get map templates placed during init to flag the turfs as changed. Generating on Shaded Hills and restarting leaves template-shaped sections of mask turfs. Not sure what the issue is, it happened even after I made all ChangeTurf() calls and relevant sections of DMMS flag the turfs directly. I am assuming that something is newing /turf directly and not flagging.

does /area/fantasy/outside/point_of_interest have AREA_FLAG_ALLOW_LEVEL_PERSISTENCE? it doesn't seem so, that'd mean at least a few non-passthrough templates (chemistry shack etc) would fail to save

@MistakeNot4892
Copy link
Contributor Author

does /area/fantasy/outside/point_of_interest have AREA_FLAG_ALLOW_LEVEL_PERSISTENCE? it doesn't seem so, that'd mean at least a few non-passthrough templates (chemistry shack etc) would fail to save

Genuinely no idea why I didn't think of this. Thank you :(

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch 6 times, most recently from f8bb209 to a8a96a1 Compare December 29, 2025 09:38
@MistakeNot4892 MistakeNot4892 marked this pull request as ready for review December 29, 2025 09:39
@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch from a8a96a1 to f0262df Compare December 29, 2025 09:40
@MistakeNot4892
Copy link
Contributor Author

This is now working as far as I can tell. Main things I am worried about in live testing is accidentally cooking legacy persistence data, but it should at least write out a backup before it does any kind of migration of that data.

I am not committing any changes that actually use this system in full yet, I'm going to save that for after we've done playtesting (probably via Pyrelight or maybe Scav)

@MistakeNot4892
Copy link
Contributor Author

Realised belatedly that I need to get area serde in before this will work as intended, due to map templates setting area, but I will do that in a second PR, I don't want to fiddle with this one further currently.

@MistakeNot4892 MistakeNot4892 added ready for review This PR is ready for review and merge. and removed work in progress This PR is under development and shouldn't be merged. labels Dec 31, 2025
@out-of-phaze out-of-phaze added the has conflicts This PR needs updating and conflict resolution before it can be merged. label Jan 9, 2026
out-of-phaze
out-of-phaze previously approved these changes Jan 9, 2026
Copy link
Member

@out-of-phaze out-of-phaze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i frankly really don't like that we still have the legacy persistence system, it really doesn't work for anything but papers and dirt (the generic 'filth' stuff was extremely annoying). but i guess some maps want a middle-ground re: persistence.

once this is in i'll try to make it faster

/// Used to avoid unnecessary refstring creation in Destroy().
var/tmp/has_state_machine = FALSE
/// Var for holding a unique-to-this-run identifier for a serialized datum.
VAR_PRIVATE/__run_uid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could use /tmp/ possibly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please. I really wish /tmp was used more. It helps make transient vars a whole lot more obvious.

@MistakeNot4892 MistakeNot4892 force-pushed the feature/limited_persistence branch from f0262df to 511b0ee Compare January 9, 2026 23:54
@MistakeNot4892 MistakeNot4892 removed the has conflicts This PR needs updating and conflict resolution before it can be merged. label Jan 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review This PR is ready for review and merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants