A composable dialogue system for Cobblemon NPCs. Two base behaviours handle the conversation itself: Simple Dialogue for one of two lines, and Long Dialogue for one of two 1–10 line sequences. A suite of optional "quest addons" (battles, item trades, currency trades, and Pokémon trades) attach to the end of any compatible dialogue. A server owner can quickly build a talking npc, quest giver, or battler entirely from in-game editor variables, without writing any scripts.
The system is permission-driven, with every branch and every addon reading from and writing to LuckPerms. As such, dialogue state is visible to admins, scriptable from outside the NPC, and scoped per-player with no extra bookkeeping.
The two base dialogues
Simple Dialogue displays one of two configured lines. The active line is gated by a line_switch_perm. If the player has the perm, they see the alt line. Otherwise they see the default. After the line is shown, a seen_perm is granted. By default, this is the same perm that flips the switch, so the second visit reads as a follow-up:
First visit: "Hello, I'm Mary. Nice to meet you!" (perm granted on close)
Second visit: "Hey . How's it going?"
Long Dialogue does the same thing with 1–10 lines per branch. The lines are clicked through one at a time, default and alt branches are gated the same way, and a separate seen_perm per branch tracks completion. Empty line slots mark the end of the conversation, so if line 4 is empty, the conversation ends after 3 lines.
Both support {{npc}} and {{player}} placeholders everywhere, and both write through the same set_dialogue_interaction hook. As such, the optional quest addons treat them interchangeably.
The quest addons
Each addon is a separate behaviour added to an NPC that already has a dialogue behaviour. When the dialogue runs, the addon's button can appear at the end of it. The four addons available:
- Optional Battle: adds a "Battle" button. Has an optional
required_permgate, a configurable confirm dialogue, and hooks into the standard battle resolution callbacks. - Optional Item Trade: adds a "Submit Items" button. Configurable required item (or defined item), amount, completion command, completion script, completion perm, and a post-trade dialogue line.
- Optional Currency Trade: same shape, but takes Impactor currency instead of items. Defaults to
impactor:dollars. - Optional Poke Trade: same shape, but takes a Pokémon matching a configured species/aspect string.
Every addon shares the same three completion outputs: a perm is granted, an optional command runs, and an optional Molang script runs. As such, quest chains are straightforward to build. Completing a poke trade can grant a perm that unlocks the alt dialogue branch on a different NPC, which offers an item trade, which grants another perm, and so on.
After-dialogue extensions
Three additional behaviours fire after a long dialogue concludes, regardless of whether any quest addons were triggered:
- After Dialogue Command: runs a vanilla
/-command. - After Dialogue Script: runs a Molang script.
- After Dialogue Forced Battle: starts the standard force-battle flow as soon as the dialogue closes.
These are independent of the optional trades. A single NPC can offer a Pokémon trade and always run a command after the conversation, in either order.
Use cases
- Shopkeepers: long dialogue plus optional currency trade with a
givecommand on completion. - Quest givers: long dialogue with a perm-gated alt branch, plus an optional item trade that grants the next quest's perm.
- Battlers: simple dialogue plus an after-dialogue forced battle, plus a
battle_won_permthat switches the alt branch for next time. - Branching state across NPCs: chain seen-perms so a conversation on the other side of the map opens up new dialogue at home.
Why permissions
The dialogue system is intentionally permission-driven. Every branch and every quest addon reads from and writes to LuckPerms. This has three big advantages:
- State is visible to admins via
/lp user X permission info. - State is scriptable from outside the NPC. A Journey task completion can grant the perm that flips a dialogue branch, and vice versa.
- State is scoped per-player by default, and located in LuckPerms where it can be easily fixed if anything breaks.
It should be noted that the addons are also designed to be additive. An NPC can offer a battle and a trade and run a command afterward, and each one renders as its own button at the end of the dialogue. Composing rather than configuring keeps the variable surface for each addon focused on just that addon's behaviour.
Techy stuff
- Built on Cobblemon's dialogue, behaviour, and Molang systems, configured in JSON.
- Each addon is a standalone behaviour file declaring
add_variables. The "compatible with dialogue X" wiring lives in the dialogue init scripts, which checkq.npc.config.optional_<addon>_enabledand call the addon'scan_offer_dialogue_*script before adding the corresponding option. - Permission writes go through a shared
cobblemon:give_permhelper. Placeholder substitution usescobblemon:replace_placeholdersandcobblemon:replace_placeholders_var. - The
{{npc}}placeholder in perm defaults resolves to the NPC's identifier at runtime. As such, the same behaviour config produces unique perms per NPC instance without the server owner having to type them by hand.
Built for the Callisto and Cobblewilds Cobblemon servers, but available for commission.