NQNStudios / hank

Portable narrative scripting language based on Ink.
MIT License
13 stars 3 forks source link

Story state serialization #4

Open NQNStudios opened 5 years ago

NQNStudios commented 5 years ago

One way to avoid edge cases caused by some things not being serialized properly... might be to REPLAY the CHOICES the player made in their last transcript! That would trip all the right logic (except for any external gameplay stuff) although it feels kind of medieval.

zicklag commented 5 years ago

The Inky editor seems to do that whenever you change the code on the left side of the screen. To update the view on the right, it just re-runs the game selecting all of the same options. The biggest thing I notice is that all of the shuffled alternatives that I used get new random values, which may or may not be a problem. It could be a big deal if the random results effect something major in the story, though.

NQNStudios commented 5 years ago

To avoid that scenario I could make the transcript log the random number seed that was used. That way the unit tests could also deterministically test stories that include randomness.

zicklag commented 5 years ago

That's good idea! I think that would pretty much handle it.

NQNStudios commented 5 years ago

In addition to serializing the random seed, we'll want to serialize the initial state of every object the storywriter passes to the story's interpreter--i.e. custom objects. For that to work, I may create/use an existing a Serializable interface and lock down across to interp.variables except through a function accepting only Serializable objects.

So the transcript would have a header something like this:

path: STORYFILE_PATH
random: Random(SEED)
custom: CustomObject(CREATION_ARGS...)
---
NQNStudios commented 5 years ago

I discovered a problem with this approach while using Hank and HaxeFlixel during the Global Game Jam: Hank tends to encourage putting game logic directly into the scripts, i.e. state.add(sprite) type stuff. A save state system that depends on replaying Hank scripts would need to intelligently skip over embedded Haxe lines that depend on UI, images, and other things we don't want flashing in front of the player's eyes whenever they load their save.

Maybe a better approach would be parsing out a dictionary of labels and knots, saving all the state of the story's execution, and just diverting to the last section the player encountered. idk.

NQNStudios commented 5 years ago

A save state system that depends on replaying Hank scripts would need to intelligently skip over embedded Haxe lines that depend on UI, images, and other things we don't want flashing in front of the player's eyes whenever they load their save.

For this, tags (#25) would be useful. Story.FromSaveFile() could accept certain code block tags that it should ignore. Then it becomes the developer's responsibility to tag graphics/audio to not be replayed. This might cause problems if logic and display are not kept separate, but really it'd just be encouraging better code organization.