Supported Ink Syntax
This page documents what the current Ink converter supports when authoring stories for NovyJump.
NovyJump uses standard Ink syntax plus a set of multimedia extensions via Ink’s tag (#) syntax.
Standard Ink Features
Text and Dialogue
Narration and speaker dialogue:
You walk into the room.ALICE: Hello there.Speaker detection: a line starting with ALL_CAPS_NAME: (letters, digits, underscores, spaces) is treated as a character speaking. Anything else is narration.
Glue (<>) suppresses line breaks:
The answer is <>42.Knots and Stitches
=== start ===-> chapter_one
=== chapter_one ===Opening narration.
= scene_twoA new scene begins.=== knot_name ===— a knot (major section)= stitch_name— a stitch (sub-section within a knot)-> target— a divert to a knot or stitch
Choices
* [Be friendly] ALICE: Thanks for being kind! -> next_scene
+ [Ask again] ALICE: Still here.*— non-sticky choice (removed after selection)+— sticky choice (remains available)- Nested choices:
**,***(depth tracking) (label)— optional label on a choice for divert targeting[bracketed text]— choice label shown to the player- Guarded choices:
* {condition} [text]
Diverts
-> knot_name-> knot_name.stitch_name-> END-> DONE-> END/-> DONE— terminal (end of story or chapter)- Inline diverts at end of choice body are resolved to direct connections
Tunnels
-> side_quest ->->->-> target ->— tunnel call (enter a section and return)->->— tunnel return (return from current tunnel)
Gathers
* Option A* Option B- You made a choice.-> END- gathers collect flow from all branches and continue.
Gather labels: - (label_name) — creates a named gather point.
Variables
VAR score = 0CONST MAX_SCORE = 100LIST moods = (happy), sad, angry~ score = score + 10~ temp greeting = "Hello"VAR— global variable declarationCONST— immutable constantLIST— enumeration with active/inactive items. Active items are listed in parentheses.~— assignment (supports=,+=,-=,*=,/=,%=)~ temp— temporary variable (scoped to current flow)
Expressions
Full expression support in conditions, assignments, and inline conditionals:
| Operator type | Operators |
|---|---|
| Arithmetic | +, -, *, /, % |
| Comparison | ==, !=, <, >, <=, >= |
| Boolean | and, or, not |
| LIST | has, hasnt |
| Grouping | () |
Conditionals
Multiline:
{ score >= 10: Great score!- else: Keep trying.}With elif:
{ score >= 10: Great score!- score >= 5: Medium score.- else: Low score.}Inline:
You feel {score > 5: confident|nervous}.Tags
# chapter_one# unlocked_endingTags appear in JumpTree metadata. NovyJump multimedia directives use the tag syntax (see below).
Comments
// This is a commentNovyJump Multimedia Directives
NovyJump extends Ink with multimedia directives using tag syntax. These produce NovyScript blocks in the output JumpTree.
Background image
# background: bg_tavern.pngSets the background image asset.
Image (standalone sprite)
# image: overlay_frame.pngDeclares an image asset without placing it on screen. Used to preload or reference assets.
Scene
# scene: tavern_nightSets the current scene by name (must reference a scene defined via # background: or configured in assets).
Clear scene
# clear_sceneRemoves all scene elements from the screen.
Music
# music: ambient.mp3# music: ambient.mp3, channel=bgm, fade=2, loop=true| Param | Default | Description |
|---|---|---|
channel | bgm | Audio channel name |
loop | true | Loop the track |
fade | — | Fade-in duration in seconds |
volume | — | Volume (0.0–1.0) |
Use a supported audio format (
.mp3,.opus,.wav,.flac, …). Avoid.ogg— the converter currently treats it as video. See Media and Resolution Specs.
Sound effects
# sfx: footstep.wav# sfx: footstep.wav, loop=falseDefaults to channel=sfx, loop=false.
Voice
# voice: line_001.mp3Defaults to channel=voice, loop=false.
Stop audio
# stop_audio: bgm# stop_audio: bgm, fade=1Stops playback on the named channel, with optional fade-out.
Character sprite
# sprite: alice, alice_happy.png, happy, x=540, y=960# sprite: alice, alice_sad.png, sad, x=540, y=960, xscale=0.8| Position arg | Description |
|---|---|
| 1 | Character id |
| 2 | Asset filename |
| 3+ | Tags (for sprite selection) |
| Named param | Description |
|---|---|
x | Horizontal position in pixels (default: 540, center) |
y | Vertical position in pixels (default: 960, center) |
xscale | Horizontal scale (default: 1) |
yscale | Vertical scale (default: 1) |
Clear character
# clear_characterRemoves all character sprites from the screen.
Display sprite (standalone)
# display_sprite: frame.png# display_sprite: frame.png, x=100, y=200, xscale=0.5Displays an image on screen without binding it to a character. Useful for overlays, UI frames, etc.
Tween (animation)
# tween: character/alice, opacity, 0, 1, 0.5, easeOutCubic# tween: scene/background, opacity, 1, 0, 1, linear| Position | Description |
|---|---|
| 1 | Target path: character/<id> or scene/<name> |
| 2 | Property to animate: opacity, xPos, yPos, xScale, yScale |
| 3 | Start value |
| 4 | End value |
| 5 | Duration in seconds |
| 6 | Easing type |
Supported easing types: linear, easeInCubic, easeOutCubic, easeInElastic, easeOutElastic, easeInOutElastic, easeInBack, easeOutBack, easeInOutBack.
4-argument form omits start value (uses current value):
# tween: character/alice, opacity, 1, 0.5, linearWith delay:
# tween: character/alice, opacity, 0, 1, 0.5, easeOutCubic, delay=0.2Style
# style: color=#ef7855, fontSize=24Applies a style to the next dialogue node. Multiple # style: directives are merged.
Supported style properties: color, opacity, fontSize, font, textAlign, backgroundColor, backgroundOpacity, wordWrap, borderColor, borderRadius, borderWidth, padding, margin, width, height.
What’s NOT Supported
The following standard Ink features are not yet converted:
- Sequences, cycles, and shuffles (
{&...},{!...},{~...}) - Named functions (
== function_name ==) - External functions (
EXTERNAL) - Multiple files /
INCLUDE(multi-file projects are concatenated before parsing) - Threads (
<- thread_name) - Advanced label addressing (beyond
knot.stitch) - LIST helper functions —
LIST_COUNT,LIST_MIN,LIST_MAX,LIST_RANDOM,LIST_VALUE,LIST_INVERTare rejected with an error.
Minimal Example
VAR trust = 0
=== start ===# background: bg_city.png# music: city_ambience.mp3, channel=bgm, loop=true# sprite: alex, alex_neutral.png, neutral, x=540, y=960
ALEX: Welcome to the city.
* Be friendly ~ trust = trust + 1 # sprite: alex, alex_happy.png, happy, x=540, y=960 ALEX: Good to meet you! -> ending
* Stay quiet -> ending
=== ending ==={ trust > 0: ALEX: I think we'll get along.- else: ALEX: Maybe next time.}-> END