Durable mod metadata cache + ghost mods (allowGhostMods)#87
Open
tomjn wants to merge 4 commits into
Open
Conversation
Mods previously kept their hash, options and sides only in the in-memory %cachedMods hash, lost on restart - unlike maps which persist full info via mapInfoCache.dat and mapHashes.dat. Mirror the map machinery for mods: - modHashes.dat: version-keyed mod checksums (fast table), dumped in dumpDynamicData alongside mapHashes - modInfoCache.dat: mod options and sides (Storable), version-independent - accessors getCachedModInfo/cacheModInfo/getModHash/saveModHash - persist mod hash and info on first archive load in loadArchivesPostActions Foundation for ghost mods (hosting a game whose archive is absent).
getModHash/getModOptions/getModSides only consulted the in-memory %cachedMods,
so a mod whose archive is absent returned no hash/options/sides. Mirror the map
accessors (getMapHash/getMapOptions): prefer live in-memory data, then fall back
to the durable mod cache (getModHash/getCachedModInfo) keyed by spring version.
No behavior change on existing installs until the cache is populated (empty
modHashes.dat/modInfoCache.dat still yield 0/{}/[]).
A dedicated host can now host a configured game whose archive is absent, using the durable mod cache, mirroring allowGhostMaps for maps. - new allowGhostMods preset setting (etc/spads.conf template + spadsSectionParameters) - canUseGhostMod(): gated on allowGhostMods + dedicated server, and requires BOTH a version-matching cached hash AND cached info (options+sides) so a battle is never opened with incomplete mod metadata (fail-loud) - updateTargetMod() falls back to the ghost mod when the configured mod is not found among locally available mods - loadArchivesPostActions() resolves to the ghost mod on initial load when the configured mod archive is absent Existing configs must add allowGhostMods (handled by the normal config update flow, as with any new setting). Setting docs (doc/*.html) are generated and not updated here.
Adds the settings-help entry for the new allowGhostMods preset setting, mirroring allowGhostMaps. The generated doc/*.html is produced by 'spads.pl --doc' at release time and is not regenerated here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SPADS persists full map metadata durably (
mapInfoCache.datfor startpositions/dimensions/options,
mapHashes.datfor version-keyed hashes), butmod metadata (hash, options, sides) only ever lived in the in-memory
%cachedModsand was lost on restart. As a result there was no "ghost mod"equivalent to ghost maps: a dedicated relay host always required the game
archive locally, even though it never simulates.
This PR mirrors the existing map machinery for mods and adds a
allowGhostModssetting so a dedicated host can host a configured game whose archive is absent,
using previously-cached metadata.
Changes
SpadsConf.pm):modHashes.dat(version-keyedchecksums, dumped in
dumpDynamicDataalongsidemapHashes.dat) andmodInfoCache.dat(Storable: options + sides). New accessorsgetCachedModInfo/cacheModInfo/getModHash/saveModHash.loadArchivesPostActions): a mod's hash and info arewritten to the durable cache the first time its archive is loaded.
getModHash/getModOptions/getModSidesnow fall back to the durable cache, mirroring
getMapHash/getMapOptions.allowGhostModssetting (preset setting, mirrorsallowGhostMaps) pluscanUseGhostMod()and ghost-mod resolution inupdateTargetMod()and oninitial load.
Design notes
The data splits cleanly by version-sensitivity: the checksum is
engine-version-sensitive (kept keyed by
springMajorVersion, like map hashes),while options and sides are intrinsic to the archive (version-independent).
canUseGhostMod()requires both a version-matching cached hash andcached info (options + sides) before a ghost mod is used, so a battle is never
opened with incomplete mod metadata.
Existing configs need
allowGhostModsadded tospads.conf(handled by thenormal config update flow, as with any new setting). Generated setting docs
(
doc/*.html) are not updated in this PR.Testing status (please read)
This is compile-checked only, not runtime-tested. The repo has no automated
tests, and I was not able to run SPADS in my environment (no Spring/unitsync
install), so I verified each change with
perl -conly. The open-battle path inparticular should be exercised on a real dedicated host before this is relied
on. Feedback on correctness and on anything I've missed is very welcome.
Scope is the "complete the cache" half of the work; an optional external
metadata import/export/fetch layer is intentionally left out of this PR.