Narrative Markup Language (.nar) Documentation #
Overview #
The .nar file format is designed to script narrative events in your Game Maker projects. With this format, you can define scenes, dialogue, choices, variable assignments, conditional branching, background transitions, and actor actions such as creation, removal, sprite changes, and animations.
This documentation is the definitive guide to writing .nar
files, covering every command and option available to ensure you can create immersive and dynamic narratives.
File Structure #
A typical .nar
file is a plain text document where each line represents a command or piece of narrative content. Indentation is used to indicate nested blocks (for example, within conditionals or loops).
Tips:
- Use consistent indentation (spaces or tabs) for clarity.
- Avoid excessive nesting to keep the file maintainable.
- The order of lines is critical, as the parser processes them sequentially.
Comments #
Comments document your narrative and are ignored by the parser. They can be on their own line or inline with other commands.
Start a comment with the symbol #
(outside of string literals):
# This is a full line comment
Some narrative text # This is an inline comment
Meta Blocks #
Meta blocks allow you to define metadata such as the title, author, or date of your narrative file. They are enclosed by the tags and
. Each line inside should begin with a meta keyword (in curly braces) followed by its value and an optional comment.
Below is an expanded meta block example with syntax highlighting:
# Author name
Title # The title of your story
Description of the story # A short description of your story
1 # Version number
08/01/2025 # Creation or last modified date
Horror, Mystery # Story genre classification
16+ # Content rating/age recommendation
English # Story language
Acre Shore # Series name if part of one (optional)
1 # Episode/chapter number in series (optional)
# Content tags/themes
© Author name 2025 # Copyright information
# Additional credits/acknowledgments (optional)
Name
Scenes #
Begin a new scene with the command @scene
followed by the scene name. Scenes help segment your narrative into manageable parts.
@scene Introduction
You can also jump between scenes using destination tags and goto commands (covered below).
Dialogue #
Dialogue lines start with a character’s name enclosed in square brackets, followed by the dialogue text. This automatically sets the speaker
and dialogue
variables in the engine.
[Alice] Hello there, welcome to our story!
[Bob] Thanks, Alice. Glad to be here.
You can insert variables into dialogue using the syntax ${variable_name}
.
Character Name Colors #
You can assign colors to character names to make them visually distinct in dialogue. Use the @name_color
command:
@name_color Alice, #0000FF
@name_color Bob, #FF0000
[Alice] My name will appear in blue!
[Bob] And mine will be red!
The syntax is: @name_color character_name, color_code
The color code should be in the format #RRGGBB
(hexadecimal RGB values).
Once a color is assigned to a character name, it will be applied automatically whenever that character speaks.
Choices #
Use the command @choice
to present multiple narrative options. After this command, list each option on a new line using the format:
Option text > destination_tag
Example:
@choice
Go left > left_path
Go right > right_path
This lets the player choose which narrative path to follow.
If Statements #
The .nar
format supports conditional branching using if
statements. Conditions can compare variables or literal values with operators like =
, <
, >
, <=
, and >=
.
Example:
if ${score} > 10
[Narrator] You have achieved a high score!
else
[Narrator] Keep trying to beat the high score.
Important Formatting Rules:
- The
if
statement must start at the beginning of the line (no indentation) - The content inside the if block must be indented (with spaces or tabs)
- The
else
statement must be at the same indentation level as theif
statement (no indentation) - The content inside the else block must be indented
Incorrect Format (Will Not Work):
if ${score} > 10
[Narrator] You have achieved a high score!
else
[Narrator] Keep trying to beat the high score.
Tips:
- Logical operators such as
and
,or
, andnot
can be used for compound conditions. - Always define your variables before referencing them in conditions.
- The indentation must be consistent throughout your if/else blocks.
Background System #
The .nar
format provides a powerful background system that supports multiple layers, animations, and transitions. This allows you to create dynamic scenes with parallax effects, scrolling elements, and other visual enhancements.
Basic Background Commands #
The simplest way to change the scene background is with the @background
command:
@background scene1.png
@background scene2.png transition: true
The background images are loaded from the res/img/background/
directory. Set the transition parameter to true
if you want a fade effect.
Layered Backgrounds #
For more complex scenes, you can create multiple background layers with different depths and anchor points:
@background_layer sky, sky.png, 1100
@background_layer mountains, mountains.png, 1050
@background_layer foreground, trees.png, 1000, true, 50%, 100%
The parameters for @background_layer
are:
layer_id
: A unique identifier for the layersprite_file
: The filename of the background imagedepth
: Drawing depth (higher values are drawn behind lower values)visible
: Optional visibility parameter (true/false)anchor_x
: Optional horizontal anchor point (pixel value or percentage, default: “50%”)anchor_y
: Optional vertical anchor point (pixel value or percentage, default: “50%”)
The anchor point determines the origin of the background image. By default, backgrounds are anchored at their center (50%, 50%). You can use percentages (e.g., “0%”, “100%”) or pixel values (e.g., “150”, “200”) to set the anchor point.
Background Anchor Points #
You can change the anchor point of an existing background layer:
@background_anchor mountains, 0%, 50%
@background_anchor foreground, 100%, 100%
The parameters for @background_anchor
are:
layer_id
: The identifier of the layer to modifyanchor_x
: Horizontal anchor point (pixel value or percentage)anchor_y
: Vertical anchor point (pixel value or percentage)
Changing the anchor point affects how the background is positioned and how animations are applied. For example:
0%, 0%
: Anchors at the top-left corner100%, 0%
: Anchors at the top-right corner0%, 100%
: Anchors at the bottom-left corner100%, 100%
: Anchors at the bottom-right corner50%, 50%
: Anchors at the center (default)
Background Animations #
You can animate background layers to create dynamic effects:
@animate_background mountains, parallax, 20
@animate_background clouds, scroll_horizontal, 1.5
@animate_background water, sway, 5
@animate_background train, train_effect, 3
The parameters for @animate_background
are:
layer_id
: The identifier of the layer to animateanimation_name
: The type of animation to applyspeed_or_amount
: Controls the speed or intensity of the animation
Available animations include:
scroll_horizontal
: Scrolls the background horizontally (positive = right, negative = left)scroll_vertical
: Scrolls the background vertically (positive = down, negative = up)parallax
: Creates a parallax effect based on mouse positionsway
: Gentle side-to-side swaying motionbounce
: Subtle up-and-down bouncing motionshake
: Random shaking effectzoom_pulse
: Pulsing zoom effecttrain_effect
: Specialized effect simulating train movement
To stop an animation:
@stop_background_animation clouds
Changing Background Layers #
You can change a specific background layer with optional transition:
@change_background sky, night_sky.png, true
The parameters are:
layer_id
: The identifier of the layer to changesprite_file
: The new background imagetransition
: Optional fade transition (true/false)
Background Groups and Crossfading #
You can group multiple background layers and crossfade between groups:
@background_group day_scene, day_sky, day_mountains, day_foreground
@background_group night_scene, night_sky, night_mountains, night_foreground
@crossfade_backgrounds day_scene, night_scene, 3.0
The parameters for @background_group
are:
group_id
: A unique identifier for the grouplayer_id1, layer_id2, ...
: The identifiers of the layers in the group
The parameters for @crossfade_backgrounds
are:
from_group_id
: The identifier of the starting groupto_group_id
: The identifier of the ending groupduration
: Optional crossfade duration in seconds (default: 1.0)
Removing Background Layers #
To remove a background layer:
@remove_background mountains
Example: Train Scene with Scrolling Landscape #
@background_layer sky, blue_sky.png, 1100
@background_layer landscape, countryside.png, 1050
@background_layer train, train_interior.png, 1000
@animate_background landscape, scroll_horizontal, -2
@animate_background train, train_effect, 3
[Conductor] Welcome aboard the express train to Meadowvale!
@wait 2s
[Passenger] The countryside is beautiful this time of year.
Fading Background Layers #
You can fade individual background layers in or out:
@fade_background clouds, in, 2.0
@fade_background rain, out, 3.5
The parameters for @fade_background
are:
layer_id
: The identifier of the layer to fadefade_type
: Either “in” to fade in or “out” to fade outduration
: Optional fade duration in seconds (default: 1.0)
When fading in, the layer will be made visible but with zero opacity, then gradually increase to full opacity. When fading out, the layer will gradually decrease to zero opacity, then be hidden.
Actor Commands #
The .nar
format includes several commands for managing actors in your scenes. The system supports both single-sprite actors and layered actors with multiple components.
Single-Sprite Actors #
Use the command @actor
with the following parameters:
actor_id
: A unique identifier for the actor.sprite_file
: The filename of the actor’s sprite.x
andy
: The starting coordinates (can be pixels or percentages like “50%”).depth
: Drawing depth (actors with higher values are drawn behind those with lower values).- Optional:
visible
– eithertrue
orfalse
(default istrue
). - Optional:
breathing
– a number for intensity (0.02 is default),0
orfalse
to disable.
@actor hero, hero_sprite.png, 50%, 80%, 10, true, 0.03
@actor statue, statue.png, 75%, 80%, 20, true, 0
Layered Actors #
For more complex characters with multiple layers, use the @actor_begin
and @actor_end
block format:
@actor_begin character_id
body_base: character_body.png
body_layer: character_clothes.png
head_base: character_head.png
face: character_neutral.png
blink: character_blink.png
head_layer: character_hat.png
x: 50%
y: 80%
depth: 0
visible: true
breathing: 0.03
expressions: {happy:happy.png,sad:sad.png,angry:angry.png}
@actor_end
All layers are optional. The system will automatically handle parent-child relationships between layers. Set breathing
to 0
or false
to disable the breathing animation, or set it to a number to control the intensity (default is 0.02).
Changing Expressions #
For layered actors with defined expressions, use @expression
to change the face:
@expression character_id, happy
Changing Individual Layers #
Update a specific layer of a layered actor using @change_layer
:
@change_layer character_id, head_layer, new_hat.png
Toggling Layer Visibility #
Show or hide specific layers with @toggle_layer
:
@toggle_layer character_id, head_layer, false
Removing an Actor #
Remove an actor with the command @remove_actor
followed by the actor ID:
@remove_actor hero
Changing an Actor’s Sprite #
For single-sprite actors, change the sprite with @change_sprite
:
@change_sprite hero, hero_happy.png
Animating an Actor #
Animate an actor with @animate
followed by the actor ID, animation name, and an optional “wait” parameter:
@animate hero, bounce
@animate villain, shake, wait
Available animations include:
slide_in_right
,slide_in_left
,slide_in_top
,slide_in_bottom
slide_out_right
,slide_out_left
,slide_out_top
,slide_out_bottom
bounce
,shake
fade_in
,fade_out
slide_in_right_fade
,slide_out_right_fade
If the “wait” parameter is included, the narrative will pause until the animation completes.
Actor Entrance and Exit #
Simplified commands for actor entrances and exits:
@enter hero, slide_in_right, wait
@exit villain, fade_out, remove, wait
The @enter
command takes an actor ID, optional animation name (default: “fade_in”), and optional “wait” parameter.
The @exit
command takes an actor ID, optional animation name (default: “fade_out”), optional “remove” parameter to delete the actor after exit, and optional “wait” parameter.
Audio System #
The .nar
format includes commands for playing music and sound effects to enhance your narrative experience.
Playing Music #
Use the @play_music
command to play background music with the following parameters:
track_id
: The identifier of the music track (without file extension)loop
: Optional boolean to specify if the music should loop (default: true)volume
: Optional volume level from 0.0 to 1.0 or as a percentage (default: 1.0)fade_in
: Optional boolean to enable fade-in effect (default: false)fade_duration
: Optional duration of the fade in seconds (default: 1.0)
@play_music main_theme
@play_music battle_music, true, 0.8, true, 2.0
@play_music ambient, true, 50%
Music files should be placed in the res/sound/music/
directory as WAV files.
Playing Sound Effects #
Use the @play_sound
command to play sound effects:
sound_id
: The identifier of the sound effect (without file extension)loop
: Optional boolean to specify if the sound should loop (default: false)volume
: Optional volume level from 0.0 to 1.0 or as a percentage (default: 1.0)
@play_sound door_open
@play_sound rain_ambience, true, 0.5
@play_sound explosion, false, 75%
Sound effect files should be placed in the res/sound/fx/
directory as WAV files.
Stopping Sounds #
Use the @stop_sound
command to stop a specific sound effect:
@stop_sound rain_ambience
@stop_sound rain_ambience, true, 2.0
The parameters are:
sound_id
: The identifier of the sound to stopfade_out
: Optional boolean to enable fade-out effect (default: false)fade_duration
: Optional duration of the fade in seconds (default: 0.5)
Stopping Music #
Use the @stop_music
command to stop the currently playing music:
@stop_music
@stop_music true, 3.0
The parameters are:
fade_out
: Optional boolean to enable fade-out effect (default: false)fade_duration
: Optional duration of the fade in seconds (default: 1.0)
Crossfading Music #
Use the @crossfade_music
command to smoothly transition between music tracks:
@crossfade_music new_theme
@crossfade_music calm_music, 3.0, true, 0.7
The parameters are:
track_id
: The identifier of the new music trackfade_duration
: Optional duration of the crossfade in seconds (default: 2.0)loop
: Optional boolean to specify if the new music should loop (default: true)volume
: Optional volume level for the new track (default: 1.0)
Setting Volume #
Use the @set_music_volume
and @set_fx_volume
commands to adjust the master volume levels:
@set_music_volume 0.5
@set_fx_volume 75%
Volume can be specified as a decimal between 0.0 and 1.0, or as a percentage.
Waiting for Audio #
Use the @wait_for_audio
command to pause the narrative until a sound effect completes:
@play_sound long_effect
@wait_for_audio long_effect
This is useful for synchronizing narrative progression with audio cues.
UI Commands #
The .nar
format includes several commands for creating UI elements and notifications.
Toast Notifications #
Display temporary notifications that slide in from the top-right of the screen using the @toast
command:
@toast This is a simple notification
@toast This will display for 5 seconds, 300
@toast This has a title, 180, Important Message
@toast This has a colored title, 180, Warning, red
@toast Custom color with hex code, 180, Custom, #FF00FF
The syntax is: @toast message, [duration], [title], [color]
message
: The main text to display (required)duration
: How long the toast stays visible in steps (optional, default: 180)title
: An optional title displayed above the messagecolor
: The color for the title, can be a named color or hex code (optional, default: white)
Named colors include: red, blue, green, yellow, orange, purple, pink, cyan, black, white, and gray/grey.
Advanced Options & Debugging #
This section covers advanced features and tips to help you debug your .nar
files:
- Debugging Output: The parser logs detailed messages for each processed line. Use these logs to troubleshoot and refine your narrative.
- Indentation Consistency: Ensure that nested blocks (such as within
if
statements) use consistent indentation to avoid errors. - Error Handling: The parser will log errors when files are missing or commands fail. Use these messages to resolve issues.
- Variable Replacement: Variables are replaced dynamically. Ensure variables are defined before use.
- Conditional Branching: Test all branches of your logic. Use the
else
clause as a fallback.
Best Practices #
To create robust and maintainable narratives, consider these best practices:
- Organize your files with clear scene breaks using the
@scene
command. - Document your narrative logic with comments.
- Maintain consistent formatting and indentation.
- Test all narrative branches and actor commands for smooth transitions.
- Review debugging output to catch issues early.
Conclusion #
This guide is your comprehensive reference for writing .nar
files in Game Maker. It covers everything from basic syntax and scene setup to advanced actor manipulation and debugging techniques. Use it to craft rich, dynamic narratives that bring your stories to life.
Happy scripting! 😊🚀