Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: refresh current path #73

Open
mttkay opened this issue Apr 9, 2023 · 0 comments
Open

Feature: refresh current path #73

mttkay opened this issue Apr 9, 2023 · 0 comments

Comments

@mttkay
Copy link

mttkay commented Apr 9, 2023

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 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant