Pardon our dust while we move our docs here. The Godot (GDScript) docs are on this site, and the Yarn language, Unity, Godot (C#) and Unreal docs are still at docs.yarnspinner.dev.

This sample replaces the standard Options Presenter with a custom one, TimeoutOptionsPresenter. When a group of options is set up for it, a white bar appears under the options and shrinks towards its centre. If the player hasn’t picked an option by the time the bar is empty, the Presenter picks one for them.

The sample shows three ways of deciding which option gets picked. When you run it and talk to Alice, she asks which one you’d like to see:

  • A hidden fallback option. The option tagged #fallback isn’t shown, and it’s picked if time runs out.
  • A default option. The option tagged #default is shown like the others, and it’s picked if time runs out.
  • The last highlighted option. The <<auto_opt>> Command turns this on, and whichever option was selected last is picked if time runs out.

Alice’s first set of options has no tags and no Command, so it has no countdown.

A 3D arena with a green capsule character in the foreground and a blue capsule character further back. At the bottom, two options, Option 1? and Option 2?, sit above a white countdown bar. The controls hint runs across the top.
Options counting down in the Default example.

Running it

Open samples/options_that_timeout/options_that_timeout.tscn and click Run Current Scene.

  • Move with WASD or the arrow keys.
  • Press E near Alice to talk to her.
  • Press Enter or Space, or click, to show the whole line or go to the next one.
  • Click an option to pick it, or move between options with the arrow keys and press Enter or Space to pick the selected one.

Alice’s second line has a link to the custom Presenter. Clicking it opens timeout_options_presenter.gd, using the LinkOpener node under the Line Presenter.

How it works

OptionsThatTimeoutNode3D
YarnDialogueRunner
Alice
DialogueInteractableNode3D
UILayerCanvasLayer
LinePresenter
LinkOpener
OptionsPresenterControl
PanelPanelContainer
VBoxVBoxContainer
OptionsContainerVBoxContainer
TimeoutBarControl
FillPanel
HintLabel
The UI part of options_that_timeout.tscn. The Dialogue Runner’s Presenters are LinePresenter and OptionsPresenter.

LinePresenter is an instance of the sample’s scenes/line_presenter.tscn, which uses the standard Line Presenter script. OptionsPresenter uses timeout_options_presenter.gd, a YarnDialoguePresenter that only handles options. Its Auto Select Duration is set to 5 seconds in the scene. To see how a Presenter like this fits together, read Building Your Own Presenter.

Tagging the options

In the Yarn Script, the options in FallbackExample and DefaultExample each have one option with a tag:

-> Option 1?
    Alice: option 1 was selected
-> Option 2?
    Alice: option 2 was selected
-> Option 3? #fallback
    Alice: The hidden fallback option was selected
Lines 1–4 These two options are shown, with the countdown bar under them.
Lines 5–6 This option isn’t shown. If the bar runs out, it’s picked, and Alice says this line.
The options in the FallbackExample node of Timeouts.yarn.
-> Option 1? #default
    Alice: option 1 was selected
    Alice: this is the default.
-> Option 2?
    Alice: option 2 was selected
Lines 1–3 This option is shown like any other. If the bar runs out, it’s picked.
The options in the DefaultExample node of Timeouts.yarn.

The LastHighlightExample node uses a Command instead of a tag:

<<auto_opt>>
-> Option 1?
    Alice: option 1 was selected
-> Option 2?
    Alice: option 2 was selected
===
Line 1 Turns on last highlighted mode for the next group of options.
Lines 2–5 When the bar runs out, whichever of these was selected last is picked.
The end of the LastHighlightExample node of Timeouts.yarn.

The Presenter registers <<auto_opt>> itself, the first time a dialogue starts, by calling dialogue_runner.add_command("auto_opt", _arm_last_highlighted). The Command sets a flag, and the Presenter clears it once the options are done. See Commands.

Choosing the mode

Each time the Presenter gets a group of options, it works out which mode to use from the Command flag and the options’ tags:

func _resolve_mode() -> TimeoutMode:
	if _auto_opt_armed:
		return TimeoutMode.LAST_HIGHLIGHTED
	for option in _options:
		if not option.is_available:
			continue
		for tag in _metadata_for(option):
			if tag == HIDDEN_FALLBACK:
				return TimeoutMode.HIDDEN_FALLBACK
			if tag == VISIBLE_DEFAULT:
				return TimeoutMode.VISIBLE_DEFAULT
	return TimeoutMode.NONE
Lines 2–3 <<auto_opt>> ran before these options.
Lines 4–6 Look at the tags on each option the player could pick.
Line 7 _metadata_for() returns the option’s tags. If the option doesn’t have any, it looks them up by line ID in the compiled Yarn Project.
Lines 8–11 HIDDEN_FALLBACK is "fallback" and VISIBLE_DEFAULT is "default".
Line 12 No tags and no Command. The options work as normal, with no countdown.
Part of timeout_options_presenter.gd.

The Presenter then checks that the options make sense. A #default or #fallback group must have exactly one tagged option, and an <<auto_opt>> group must have none. If the check fails, it prints an error and returns -1, so it doesn’t show those options.

It makes each button from its Option Button Scene, which is set to the shared option_item.tscn in the Inspector. When it makes the buttons, it leaves out the option tagged #fallback, and connects each button’s focus_entered signal to track which option was selected last. It gives focus to the first button, so last highlighted mode always has an option to pick.

Running the countdown

After the options fade in, the Presenter starts the countdown. TimeoutBar shrinks its Fill child from full width to nothing over Auto Select Duration seconds. When it’s empty, the Presenter picks an option:

func _run_timeout(mode: TimeoutMode, default_index: int) -> void:
	await timeout_bar.shrink(auto_select_duration)
	# shrink() also returns when cancelled; bail if a click already won.
	if not _is_showing:
		return
	var index := default_index
	if mode == TimeoutMode.LAST_HIGHLIGHTED:
		index = _last_highlighted_index
		if index < 0:
			index = _first_available_index()
	if index < 0:
		return
	_select(index)
Line 2 Wait for the bar to empty.
Lines 3–5 shrink() also returns early when the bar is stopped. If the player already picked an option, there’s nothing to do.
Line 6 In the default and fallback modes, pick the tagged option.
Lines 7–10 In last highlighted mode, pick the option that had focus last, or the first option the player could pick.
Line 13 Pick it, the same as if the player had clicked it.
Part of timeout_options_presenter.gd.

When the player clicks an option before the bar runs out, the Presenter stops the bar, fades the options out, and returns the option’s index to the Dialogue Runner.

The Dialogue Runner has its own time limit for options, Option Timeout. When that runs out, the dialogue carries on after the options without picking one. This sample picks an option instead, so the dialogue goes down that option’s branch. See Time limits.

Things to try

  • Select OptionsPresenter and change Auto Select Duration from 5 to a larger number. The bar shrinks more slowly.
  • Remove the <<auto_opt>> line from LastHighlightExample in Timeouts.yarn. Those options then have no countdown.
  • Add #default to Option 2? in DefaultExample, so two options have the tag. The Presenter prints an error and doesn’t show those options.
Next step Phone Chat One custom Presenter that shows lines and options as message bubbles in a phone screen.