Scene Flow
As your story grows longer, you’ll quickly face a problem:
How do you organize scenes without writing repetitive code?
NovaMark provides two key mechanisms to solve this:
- Scene Labels — Break scenes into smaller segments
- @call / @return — Call a scene like a function, then return after it finishes
1. Review: Scenes and Labels
You already know scenes are defined with #scene_xxx:
#scene_forest "Misty Forest"Inside a scene, you can use labels (starting with .) to create sections:
#scene_forest "Misty Forest"
> You walk into thick fog.
.look_around
> You look around, but can't see anything clearly.
.call_help
> You shout, but only your echo responds.Labels serve two purposes:
- Let choices jump to specific positions within a scene
- Break long narratives into manageable segments
2. Simple Jumps: ->
Use -> to jump to another location:
-> scene_towerThis means “jump directly to scene_tower and don’t come back.”
This type of jump is suitable for:
- Chapter transitions
- Linear story progression
- Entering a new area with no return
3. Call and Return: @call / @return
But sometimes what you want is:
Execute a segment of story, then return to where you were.
This is what @call and @return are for.
Basic Usage
#scene_main "Main Flow"
> You enter a small hut.
? What do you want to do?
- [Talk to the shopkeeper] -> .talk
- [Open the shop] -> .shop
- [Leave] -> scene_village
.talk
Shopkeeper: How can I help you?
-> .back
.shop
@call shop_scene
.back
> You leave the shop.
#scene_village "Village"
> You return to the village square.What Happens
When the player chooses “Open the shop”:
- Execution reaches
@call shop_scene - Jumps to
shop_scene, starts executing that content - When
shop_scenereaches@return - Returns to the line after
@call, which is the.backlabel
4. How to Write a Callable Scene
A scene that can be called with @call typically looks like this:
#shop_scene "Shop"
> The shopkeeper smiles and shows you the goods.
? What do you want to buy?
- [Healing Potion - 20 gold] -> .buy_potion if item_count("gold") >= 20
- [Leave] -> .leave
.buy_potion
@take gold 20
@give healing_potion 1
Shopkeeper: Here's your potion.
-> .continue
.leave
Shopkeeper: Come again soon.
-> .continue
.continue
@returnKey Points
- The scene ends with
@return - All branches eventually flow to
@return - This way the caller can correctly return to the original position
5. Difference Between @call and Simple Jump
| Method | Behavior | Use Case |
|---|---|---|
-> scene_xxx | Jump there, don’t come back | Chapter transitions, entering new areas |
@call scene_xxx | Jump there, return when done | Shops, battles, reusable segments |
You can think of it as:
->is “go there and stay there”@callis “go there to handle something, then come back”
6. When to Use @call
Good Use Cases for @call
Shop / Trading System
@call shop_sceneThe shop logic is the same in every town and chapter.
Battle Subroutines
@call battle_wolvesAfter the battle ends, return to the main story.
Common Events
@call random_encounterRandom encounter events, return to main story after handling.
Rest / Recovery Points
@call inn_restRest at an inn, recover health, then continue adventuring.
Not Suitable for @call
Main Chapter Transitions
-> scene_chapter_2This is a permanent scene change, no need to return.
Entering a New Map
-> scene_dungeonThe player will explore the new map for a while, it’s not “finish something and return.”
7. A Complete Example
---
title: Example Game
---
@var gold = 100
@item healing_potion
name: "Healing Potion"
default_value: 0
@end
#scene_start "Beginning"
> You stand in the village square.
? Where do you want to go?
- [Go to the shop] -> .go_shop
- [Rest at the inn] -> .go_inn
- [Leave the village] -> scene_forest
.go_shop
@call shop_scene
-> .back
.go_inn
@call inn_scene
-> .back
.back
> You return to the square.
-> scene_start
#shop_scene "Shop"
Shopkeeper: Welcome!
? What would you like to buy?
- [Healing Potion - 30 gold] -> .buy if item_count("gold") >= 30
- [Leave] -> .leave
.buy
@take gold 30
@give healing_potion 1
Shopkeeper: Here's your potion.
-> .done
.leave
Shopkeeper: Come again soon.
.done
@return
#inn_scene "Inn"
> You enter a cozy inn.
Innkeeper: 10 gold for a night. Would you like to stay?
?
- [Stay] -> .stay if item_count("gold") >= 10
- [Leave] -> .leave
.stay
@take gold 10
> You have a good night's sleep and wake up refreshed.
-> .done
.leave
> You decide not to stay.
.done
@return
#scene_forest "Forest"
> You leave the village and head into the unknown forest.This example demonstrates:
- Main scene calls shop and inn with
@call - Shop and inn scenes return with
@return - All branches eventually reach
@return
8. Nested Calls
@call can be nested, meaning:
#scene_a
@call scene_b
#scene_b
@call scene_c
#scene_c
@return -- returns to scene_b
@return -- returns to scene_a (requires @return in scene_b too)However, it’s recommended not to nest too deeply to maintain code readability.
9. Summary
Just remember these points:
#scene_xxxdefines a scene.labeldefines a label within a scene-> targetpermanent jump, no return@call scenecall a scene, return when done@returnreturn from a called scene
Using these well, your script can:
- Avoid repetitive code
- Keep structure clear
- Be easy to maintain and extend
What’s Next
Now you know how to organize scenes and reuse story segments.
The natural next questions are:
- How do you mark key player choices?
- How do you trigger different endings?
Next page: