LogoPixi’VN

ink language integration

Learn how to integrate the ink scripting language with Pixi’VN to write interactive narratives, import ink files, and use advanced features in your visual novel projects.

Pixi’VN lets you write interactive narratives using ink, a scripting language designed for branching stories.

What is ink? ink is a simple scripting language for interactive stories, used in games like 80 Days, Heaven's Vault, and Sorcery! Learn more on the ink website.

The ink + Pixi’VN integration uses inkjs and PixiVNJson to parse ink code and generate JSON that Pixi’VN can interpret. This means JavaScript/TypeScript and ink share the same storage and canvas, and you can launch ink knots (or labels) from JavaScript/TypeScript and vice versa. You get the best of both worlds: write narration in ink, and use JavaScript/TypeScript for minigames or advanced animations.

ink/start.ink
=== start ===
We arrived into London at 9.45pm exactly.

* "There is not a moment to lose!"[] I declared.
 -> hurry_outside

* "Monsieur, let us savour this moment!"[] I declared.
 My master clouted me firmly around the head and dragged me out of the door.
 -> dragged_outside

* [We hurried home] -> hurry_outside

=== hurry_outside ===
We hurried home to Savile Row -> as_fast_as_we_could

=== dragged_outside ===
He insisted that we hurried home to Savile Row
-> as_fast_as_we_could

=== as_fast_as_we_could ===
<> as fast as we could.
-> start

Why?

Writing narrative directly in JavaScript/TypeScript can be slow and complex, especially for beginners. ink is much easier to learn and write.

New developers can start with an ink template, then gradually learn JavaScript/TypeScript for advanced features.

Installation

Templates

Starting a new Pixi’VN project? Use a template that already includes ink.

To install the ink package in an existing JavaScript project, use one of the following commands:

npm install @drincs/pixi-vn @drincs/pixi-vn-ink

Initialize

After installing, use importInkText() to load your ink script:

main.ts
import { importInkText } from '@drincs/pixi-vn-ink'

const inkText = `
=== start ===
Hello
-> END
`

importInkText([inkText, ...])

Now you can run an ink knot (or label) using Pixi’VN functions:

main.ts
import { narration } from '@drincs/pixi-vn'

narration.callLabel(`start`, {})

Upcoming features

These features are in development.

Show your interest by liking or commenting on the issues.

Syntax ignored by Pixi’VN

Some ink syntax is ignored by Pixi’VN. You can use these in your ink script (e.g., for testing in Inky editor), but Pixi’VN will ignore them.

INCLUDE

INCLUDE is an ink directive to include another ink file. In Pixi’VN, you should use importInkText() to load multiple ink files instead, so INCLUDE is ignored.

Narration outside the knots

Narration outside the knots (or labels) is ignored, except for variables.

For example:

ink
VAR my_var = false // ✅ This will be handled (because it is a variable)
Hello // ❌ This will be ignored  [!code warning]
-> start // ❌ This will be ignored [!code warning]
=== start === // ✅ This will be handled
My name is John // ✅ This will be handled
-> DONE // ✅ This will be handled

Differences between native ink and Pixi’VN ink

  • in this case:

    ink
    { shuffle:
      -  2 of Diamonds.
        'You lose this time!' crowed the croupier.
    }

    In native ink, you will see two different dialogues, the first one will be 2 of Diamonds. and the second one will be 'You lose this time!' crowed the croupier..

    In Pixi’VN ink, you will not see two different dialogues, but the following dialogue: 2 of Diamonds.\n\n'You lose this time!' crowed the croupier.. In Markdown it will be displayed like this:

    2 of Diamonds.
    'You lose this time!' crowed the croupier.
  • if a weave (in following example shove) is attached to a one time choice, and it is opened with -> shove it will not invalidate the one time choice. To invalidate it you will have to select the choice as usual.

    Here is an example:

    ink
    -> start
    === start ===
    * [1] -> shove
    * (shove) [2] 2
    * {shove} [3] -> END
    -  -> start
    -> DONE

    In case you take choice 1, the second time it will be opened start:

    • if you use native ink, you will only be able to choose choice 3. The choice 2 is hidden because being "one time" native ink will know that you have already made this decision with -> shove.
    • if you use Pixi’VN ink, you will be able to choose choice 2 or 3. The choice 2 is not hidden because Pixi’VN ink doesn't know that shove is paired with a choice.

    To get the same logic as start both in native ink and Pixi’VN ink you will have to write the following code:

    ink
    -> start
    === start ===
    * [1] -> shove
    * (shove) {!shove} [2] 2
    * {shove} [3] -> END
    -  -> start
    -> DONE