PrismatiXEngine
Story and assets

Your first complete story

Write dialogue, narration, branches, and an ending using the starter's existing artwork and character.

繁體中文

This chapter assumes you ran prismatix create my-game and kept the starter's guide character, smile expression, and background registration. Back up Story/main.pxstory. The following is a complete replacement for that Story file only; do not clear your other project files.

1. Complete example: First Light

; First Light — keep the starter's assets and character registration
*start
[bg asset=10000000-0000-4000-8000-000000000001]
[show guide expression=smile position=center scale=0.8]

[id main.welcome]
@guide
Welcome! This is the first scene we are writing together.
[id main.question]
What would you like to do this evening?

[id main.choice.stars]
[choice text="Watch the stars by the window" goto=stars]
[id main.choice.story]
[choice text="Stay and listen to a story" goto=story]
[choice.wait]

*stars
[id main.stars.narration]
The sky outside slowly grows darker.
[id main.stars.dialogue]
@guide
Look, the first star has appeared.
[jump target=finish]

*story
[id main.story.narration]
The book on the desk opens to a fresh page.
[id main.story.dialogue]
@guide
Once, someone decided to turn the story in their head into a game.
[jump target=finish]

*finish
[id main.finish]
@guide
And this is where that story begins.

[hide guide]
[end]

Save, run prismatix validate my-game, and play with prismatix dev my-game. If the watcher is already running, let it process the change rather than opening another session. The two choices should lead to different passages before reaching the same ending.

2. Dialogue and narration

@guide selects a character alias. Subsequent ordinary text lines belong to that speaker until a blank line. Each text line is a Story operation, not a Markdown paragraph-layout instruction.

@guide
This is the guide's first line.
The guide is still speaking here.

This line is narration.

An alias is not the display name. guide comes from the character registration; the on-screen name comes from the character document. Do not assume @小光 is an alias registered by the starter. Selecting a speaker also does not place a character sprite on the Stage; use [show ...] for that.

3. Choices and jumps

*stars declares a label. A choice's text is shown to the player, and goto names a label in the same Story document. [jump target=finish] unconditionally moves execution to the shared ending.

Keep options in one group adjacent, followed by the starter's [choice.wait] marker. The current compiler does not emit a separate operation for that marker: consecutive choice operations and the runtime implement selection waiting. Do not put narration or other executable commands between options belonging to one group.

A label does not stop execution from falling through. Without the jump after the stars branch, the script could continue into the story branch. That is why each branch explicitly jumps to finish.

4. Stable Story identities

[id main.welcome] pins the identity of the next observable operation. Comments and speaker declarations do not consume it, so an ID before @guide still applies to the next dialogue line. A label does emit an operation, however: do not put an ID before a label while expecting it to identify a later line.

Keep the ID when rewriting the same logical line. Give a genuinely new line a new ID. Never duplicate a passage together with all its IDs. Without explicit IDs, fallback identities depend on source position and content; moving prose can therefore change its identity.

Story IDs, scene document IDs, operation types, and save versions all affect compatibility. Stable IDs do not make arbitrary story edits compatible with old saves. See Saves and compatibility.

5. Reusable passages with call and return

Use call when a shared passage should return to its caller:

*start
[call target=greeting]
[id after.greeting]
We continue our journey.
[end]

*greeting
[id greeting.shared]
@guide
Good morning!

[return]

End the main flow before the shared passage so normal execution cannot fall into it. Use return for a passage entered by call, not as a general replacement for every story ending. The current author compiler validates labels within the same document; do not invent cross-file jump syntax.

6. Test the chapter

Start a new game for each branch and verify that the two endings are not played consecutively. Temporarily change one goto to a nonexistent label: validation should report it. Repair and save the file, then confirm Preview updates again. Finally, check that every explicit ID is unique and followed by an operation.

Continue with Variables and control flow, or consult the complete Story command reference.

Sources: Story parser/compiler, Author cookbook.

On this page