In most games, game state that is not handled by Ink itself can change after an ink knot has already been rendered.
This can render Ink's story state stale.
For example, imagine I can pick up an item on the story scene told by the current knot. This could happen via an external function call from Ink into your game. However, if one of the choices in the current knot is itself dependent on the player owning that particular item (e.g. via conditional diverts), the current scene state is now stale and needs to be refreshed.
I have not found a clean way to do that with inkgd. The primary issue is that inkgd forgets the current path as soon as it has finished playing the current knot (i.e. it current_path always returns null so you cannot remember it). I have to work around this by capturing this state manually in a data structure StorySegment by capturing internal inkgd state such as path pointers before allowing the story to continue:
class StorySegment:
var text: String
var type: int # SegmentType
var path: String
var visit_count: int
var choices: Array
func _init(ink_player):
type = ink_player.get_variable("segment_type")
path = _path_from_player(ink_player)
func _path_from_player(ink_player) -> String:
var story_state = ink_player._story.state
var ink_path = story_state.current_pointer.path
if not ink_path:
ink_path = story_state.previous_pointer.path
assert(ink_path, "no ink path found")
var primary = ink_path.get_head().name
var secondary = ink_path.get_tail().get_head().name
return "%s.%s" % [primary, secondary] if secondary else primary
I use the same mechanism to provide a scene refresh function, which "rewinds" inkgd's state to the current knot by replaying the captured pathname onto InkPlayer#choose_path and then call InkPlayer#continue_story:
However, this is clearly a workaround, and it has some unintended side effects such as incrementing the visit count, when the player really only visited this scene once.
I think it would be helpful to:
provide a getter that returns the current path string from InkPlayer even after the continued signal fired, so that we can feed it back to the player
provide a refresh or reload method that reloads the current knot without affecting visit counts, so that Ink variables and conditionals get re-evaluated.
In most games, game state that is not handled by Ink itself can change after an ink knot has already been rendered.
This can render Ink's story state stale.
For example, imagine I can pick up an item on the story scene told by the current knot. This could happen via an
external
function call from Ink into your game. However, if one of the choices in the current knot is itself dependent on the player owning that particular item (e.g. via conditional diverts), the current scene state is now stale and needs to be refreshed.I have not found a clean way to do that with
inkgd
. The primary issue is that inkgd forgets the current path as soon as it has finished playing the current knot (i.e. itcurrent_path
always returnsnull
so you cannot remember it). I have to work around this by capturing this state manually in a data structureStorySegment
by capturing internal inkgd state such as path pointers before allowing the story to continue:I use the same mechanism to provide a scene refresh function, which "rewinds" inkgd's state to the current knot by replaying the captured pathname onto
InkPlayer#choose_path
and then callInkPlayer#continue_story
:However, this is clearly a workaround, and it has some unintended side effects such as incrementing the visit count, when the player really only visited this scene once.
I think it would be helpful to:
InkPlayer
even after thecontinued
signal fired, so that we can feed it back to the playerrefresh
orreload
method that reloads the current knot without affecting visit counts, so that Ink variables and conditionals get re-evaluated.