Repository navigation
Conversation
Loading a snapshot into the story it was taken from threw "Invalid
container id reference." or "tracked containere are not allowed to
move" for many stories: any with a sequence ({a|b}, {stopping:},
{cycle:}, {shuffle:}), and some with a labelled gather inside a choice.
globals_impl::snap_load() re-derived every tracked container from the
name hash stored with its visit count, even when not migrating. That
lookup is not one-to-one: a sequence's container is tracked but has no
name of its own, so its hash is 0 and resolves to nothing, and named
containers below an indexed one are hashed without the index, so two
containers can share a hash and resolve to the other one.
When not migrating the counts are loaded in container order, so the
lookup is not needed: compare the stored hash with the container's own
instead, which still catches a snapshot from a different story. The
migration path is unchanged.
Found by snapshotting at every choice of 70 stories and restoring 1-4
choices back (32,031 restores): 3 stories threw before, none after,
and every replay matched the original run.
Ink Proof ResultsThese results are obtained by running the Ink-Proof Testing Suite on the compiled binaries in this pull request.
|
This branch has not been deployed
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.
The bug
Loading a snapshot back into the story it was taken from throws for many stories:
It happens for any story with a sequence (
{a|b},{stopping: ...},{cycle: ...},{shuffle: ...}), and for some with a labelled gather inside a choice. Seven lines are enough:Play to the first choice,
create_snapshot(),new_runner_from_snapshot(): it throws.Why
When not migrating,
globals_impl::snap_load()looked every tracked container up again from the name hash stored with its visit count, and asserted that it found the same id. That lookup is not one-to-one:0andfind_offset_for()finds nothing.build_container_hash_map()names the named children of an indexed container without the index, so two containers can end up with the same name and hash, and the lookup returns the other one.The fix
When not migrating, the visit counts are already loaded in container order and nothing needs looking up. The stored hash is now compared with the container's own hash at the same index, which still catches a snapshot from a different story. The lookup moves into the migration branch, which is otherwise unchanged.
Tests
inkcpp_test/Fixes.cppwith the story above (inkcpp_test/ink/SnapshotVisitCounts.ink): it throws without the fix, and with it the restored runner carries on the sequence ("Later visit.")..pre-commit-config.yaml.Not in this PR
From reading the code (not tested), the migration path still resolves containers through the same lookup, so migrating a story with sequences would drop their visit counts (hash
0finds nothing) or put a count on the wrong container (shared hash). Fixing that means giving those containers unique names inbuild_container_hash_map(), which changes the file format, so it seemed better as a separate discussion. Happy to open an issue for it.