ephread / inkgd

Implementation of inkle's Ink in pure GDScript for Godot, with editor support.
MIT License
305 stars 33 forks source link

Loading a story state doesn't rollback the error stack #29

Open paulloz opened 3 years ago

paulloz commented 3 years ago

Hey 😄

Let's consider the following code.

var state = self.story.state.to_json()
# any action resulting in an error being stacked for interruption 
self.story.state.load_json(state)
if self.story.can_continue:
    self.story.continue()

The expected behavior would be for everything after the new state is loaded to go on smoothly. But at the moment, story execution will stop when continue() is called and the stacked error will be displayed. The error stack needs to be cleared out and InkRuntime.should_interrupt should be reset.

The tricky part would be to determine if some errors are from before the state was saved or not.
E.g.

var state1 = self.story.state.to_json()
# any action resulting in an error being stacked for interruption 
var state2 = self.story.state.to_json()
# any action resulting in an error being stacked for interruption 
self.story.state.load_json(state1|state2)

Depending on which state (state1 or state2) is loaded on the last line, the rollback should probably not be the same.


Environment:

ephread commented 3 years ago

That's a very good catch, thanks for raising it!

I've made error reporting more explicit in the latest version. Now, in debug, the execution is interrupted immediately when the runtime encounters an error.

The error stack needs to be cleared out and InkRuntime.should_interrupt should be reset.

Good idea, setting the state should clear everything and restore the story. I'll make it happen!

I originally didn't want to allow the story to continue because of the lack of exceptions in GDScript. I'm not certain that my home-cooked logic based on InkRuntime.should_interrupt preserves a workable state when an exception is raised. But restoring a state should provide a clean slate. I'll mention this in Differences with the C# API.

The tricky part would be to determine if some errors are from before the state was saved or not.

I think it would be nearly impossible to do properly in inkgd. Resetting InkRuntime.should_interrupt is probably enough, but I'll monitor this.

paulloz commented 3 years ago

I think it would be nearly impossible to do properly in inkgd. Resetting InkRuntime.should_interrupt will probably be enough, but I'll monitor this.

Yes, imho the only right way would be to embed that information into the state itself and use it during restoration.