Feature: refresh current path
mttkay opened this issue · comments
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
:
func refresh():
_ink_player.choose_path(_current_segment.path)
_ink_player.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 thecontinued
signal fired, so that we can feed it back to the player - provide a
refresh
orreload
method that reloads the current knot without affecting visit counts, so that Ink variables and conditionals get re-evaluated.