Candy Logo Copyright © 2025-2026 Candy Arts

Live Dialogue Editing
A Dialogue can be edited while it runs: your code can change, add or remove Lines of a Dialogue an Engine is running. This isn't officially supported. It works incidentally, because of how Dialogues are run: no feature is built for it. This page covers what is needed to begin, and the precautions to take. Why It Works When an Engine loads a Dialogue, the whole Dialogue is stored in its running_dialogue dictionary. The Engine then reads a single Line at a time from it, right when that Line is about to run. A Line that hasn't run yet can therefore be changed, and the Engine runs the new version. Before you edit a Dialogue live, check whether a supported feature covers the need: a CandyRef expression in place of a value, a Condition Command, or Variations. They're safer, and supported. Editing A Block's Lines are the Array in its Text key. Each Line is a Dictionary, whose key is the Command's name and whose value is the Command's data:
var lines: Array = engine.running_dialogue["Shop"]["Greeting"]["Text"] # Change the text of the third Line: lines[2]["Spoken_Line"]["Variations"][0]["Default"]["Text"] = "We're closed." # Add a Line at the end of the Block: lines.append({"Jump": {"Conversation": "", "Block": "Farewell", "Line": "0"}})
Write Lines the way Candy Dialogue Creator does: every value is a String, including numbers ("0"). To write a Line correctly, write it in Candy Dialogue Creator, export it, and copy it from the exported file. The keys of each Command are listed under Commands. Edits can be made from anywhere in your code, such as a hook function, or a function a Call command runs. Precautions Edits aren't saved They only change the Dialogue in memory, in that one Engine. The Dialogue file isn't changed, and loading it again restores the original. Another Engine that loaded the same file has its own copy. Edit in place Change the existing dictionaries and Arrays, rather than replacing them: the Engine retains a reference to the Block it's running. Don't assign a new dictionary to running_dialogue during a Dialogue, and don't load another file: load_scripted_dialogue() is refused while a Dialogue runs. The running Line The Line that is running has already been read. Changing it has no effect, or an unpredictable one: only edit Lines that haven't run yet. Line indexes shift The Engine records its position by index, and moves on to the next index. Adding or removing a Line above the running Line, in the same Block, shifts every Line below it: a Line is skipped, or runs twice. Adding or removing Lines below the running Line is safe. For the same reason, a Jump, a Bridge or a choice that targets a Line by its index points to a different Line once Lines are added or removed above it. Target Line Marks instead of indexes: they're found by name, wherever they are. Bridges A Bridge stores the Line it returns to, by index too. While a Bridge is running, don't add or remove Lines above that point in the Block it came from, and don't remove or rename that Block or its Conversation. Running Blocks Never remove or rename the Block that is running, or its Conversation. Open choice menus A choice menu is built from its Line when it opens. Editing a Choice_List while its menu is open doesn't update the menu, and may leave the two out of step. Edit it before it opens, or change the open menu with the Choice_Status and Timer_Status commands. Conditions and loops The Command an If, For or While runs is part of that Line. Once the Line has started, it follows the same rule as the running Line. Mistakes aren't reported in advance A Line with a misspelled Command, a missing key or a wrong value is only reported when it runs. A Block left with an empty or malformed Line ends the Dialogue there. Saved positions If your game saves where a Dialogue was (for example, from the Engine's conversation_tracker, block_tracker and line_tracker), a position saved before an edit may not match the Dialogue afterwards, and never matches the original file.