> For the complete documentation index, see [llms.txt](https://wiki.aselstudios.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.aselstudios.com/luxdialogues/hooks/betonquest.md).

# BetonQuest

LuxDialogues can render BetonQuest conversations. Your quest logic stays exactly where it is, in your BetonQuest packages, and only the presentation changes: the NPC text types out in a LuxDialogues frame and the player picks answers with the same controls as any other dialogue.

{% hint style="info" %}
Needs BetonQuest 3.1 or newer. There is nothing to enable in `config.yml`. If BetonQuest is installed, the hook registers itself on startup and logs which conversation IOs it added.
{% endhint %}

## Setup

{% stepper %}
{% step %}

### Find the styles folder

On first start the plugin creates `plugins/LuxDialogues/Hooks/BetonQuest/` with two styles in it, `default.yml` and `kingdom.yml`.
{% endstep %}

{% step %}

### Pick a style name

Every `.yml` file in that folder becomes its own conversation IO, named after the file:

| File          | Conversation IO           |
| ------------- | ------------------------- |
| `default.yml` | `luxdialogues_io_default` |
| `kingdom.yml` | `luxdialogues_io_kingdom` |

Copy a file to add more. `tavern.yml` gives you `luxdialogues_io_tavern` after the next restart.
{% endstep %}

{% step %}

### Point a conversation at it

Add `conversationIO` at the top level of the conversation, next to `quester` and `first`.

```yaml
conversations:
  Blacksmith:
    quester: "Rowan"
    conversationIO: "luxdialogues_io_default"
    first: "greeting"
```

{% endstep %}
{% endstepper %}

***

## Applying it everywhere

You do not have to touch every conversation. BetonQuest resolves the IO in two steps, and only two: it uses the conversation's own `conversationIO` if there is one, otherwise it falls back to `default_io` in `plugins/BetonQuest/config.yml`.

```yaml
conversation:
  default_io: luxdialogues_io_default
```

With that set, every conversation on the server uses LuxDialogues, and you only add `conversationIO` to the individual conversations that should look different.

{% hint style="warning" %}
There is no package level setting. A `conversationIO` written directly under `conversations:` is ignored, because BetonQuest only reads it from inside a single conversation's own section.
{% endhint %}

***

## Style files

A style file uses the same sections as a normal dialogue, minus the parts that BetonQuest provides itself. There is no `Pages` section, because the pages come from your conversation, and no `Character` section, because the name plate shows the conversation's `quester`.

```yaml
Settings:
  typing-speed: 1
  range: 5
  effect: Slowness
  answer-numbers: true
  prevent-exit: false
  prevent-skip: false
  character-name: true
  character-image: true
  background-fog: true
  npc-focus: false

Sounds:
  typing:
    id: luxdialogues:luxdialogues.sounds.typing
    source: MASTER
    volume: 1.0
    pitch: 1.0
  selection:
    id: luxdialogues:luxdialogues.sounds.selection
    source: MASTER
    volume: 1.0
    pitch: 1.0

Offsets:
  name: 0
  name-background: 20
  dialogue-background: 0
  dialogue-line: 10
  answer-background: 140
  answer-line: 13
  arrow: -7
  character: -16
  information: 27

Images:
  character-background: character-background
  arrow: hand
  dialogue-background: dialogue-background
  answer-background: answer-background
  name-start: name-start
  name-mid: name-mid
  name-end: name-end
  fog: fog

Colors:
  name: '#4f4a3e'
  name-background: '#f8ffe0'
  dialogue: '#4f4a3e'
  dialogue-background: '#f8ffe0'
  answer: '#4f4a3e'
  answer-background: '#f8ffe0'
  character-background: '#ffffff'
  arrow: '#cdff29'
  selected: '#4f4a3e'
  fog: '#000000'
  information: '#f8ffe0'
```

Every key means the same thing it does in a dialogue file. See [Dialogues](broken://pages/445b4fd5433c7d6e20444734d13ebf03ab867ee4) for the full list.

***

## How a conversation is rendered

{% stepper %}
{% step %}

### NPC text becomes pages

The NPC text of the current step is split across as many LuxDialogues pages as it needs, using the line count from `Pack/Lines/lines.yml`. Extra pages are chained together, so the player advances through them with the normal interaction key.
{% endstep %}

{% step %}

### Answers appear on the last page

The conversation's player options are shown as answers on the final page. Picking one hands the choice back to BetonQuest, which resolves the pointers and sends the next step.
{% endstep %}

{% step %}

### Steps with no answers stay on screen

When a step has no player options, the page stays up until the player advances, instead of closing on its own. That gives farewell lines somewhere to be read.
{% endstep %}

{% step %}

### Closing ends the conversation

Leaving the LuxDialogues frame, by sneaking or by walking out of `range`, ends the BetonQuest conversation as well, so the player is never left with a conversation running invisibly.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
While a LuxDialogues frame is open, clicking the NPC again advances the page instead of restarting the conversation.
{% endhint %}

***

## Example

<details>

<summary>A small conversation</summary>

```yaml
conversations:
  DirtQuest:
    quester: "Villager"
    conversationIO: "luxdialogues_io_default"
    interceptor: "none"
    interceptor_delay: 1

    first: "completeQuest,inProgress,introduction"

    NPC_options:

      introduction:
        text: "How are you, %player%?\nAre you up for doing\nsomething for me today?"
        conditions: "!questStarted,!questDone"
        pointers: "acceptQuest,declineQuest"

      accepted:
        text: "Wonderful!\nDig up 16 dirt for me\nand bring it back."

      declined:
        text: "Very well.\nCome and see me another time."

      inProgress:
        text: "You are not done yet.\nBring me 16 dirt."
        conditions: "questStarted,!questDone"

      completeQuest:
        text: "Wonderful, you did just\nwhat I asked. Thank you."
        conditions: "has16Dirt,!questDone"
        actions: "takeDirt,finishQuest"

    player_options:

      acceptQuest:
        text: "Yes."
        actions: "startQuest,startDirtObjective"
        pointers: "accepted"

      declineQuest:
        text: "No."
        pointers: "declined"
```

</details>

{% hint style="info" %}
Keep your NPC text lines short. BetonQuest line breaks (`\n`) are kept as written, and a line that is wider than the dialogue background is not wrapped for you.
{% endhint %}
