Posts

Monogatari v2.8.0

Download Link: monogatari-v2.8.0.zip

v2.8.0 is the largest release since v2.6.0. Under the hood, the entire engine has been rewritten in TypeScript and broken apart into focused modules; on the surface, you get explicit asset management, save screenshots, native desktop storage, a big library of dialogue text effects, and a long list of fixes. Here’s everything that changed and how to take advantage of it.

πŸ“° Release Change Log

🌟 New Features

🧠 A Full TypeScript Rewrite

The core engine, every built-in action, and every component have been migrated to TypeScript. The @monogatari/core package now ships its own type definitions, so whether you’re writing custom actions and components or just scripting your game in an editor, you get full autocomplete and type-checking for the engine API, game settings, and the new typewriter effects.

🧩 The Engine, Split Into Modules

The old ~3,500-line monogatari.ts “god object” has been split into focused modules β€” assets, characters, i18n, input, lifecycle, persistence, and ui. The build now produces two clearly separated targets:

Nothing changes about how you write a game, but the engine is now far easier to maintain and to load from a bundler.

πŸ“¦ Preload & Unload Actions

Two new script actions give you explicit control over when assets live in memory. preload pre-caches music, sounds, voices, scenes, images, and character sprites before you need them; unload frees them when you don’t.

// Single assets
'preload music main_theme',
'preload scene classroom',
'preload character y happy',

// Wait until the asset is ready before continuing
'preload scene boss_room blocking',

// Free memory again
'unload scene classroom',
'unload music',            // a whole category
'unload all permanent',    // memory *and* the IndexedDB cache

You can also group assets into named blocks and load or free them in a single statement β€” great for per-chapter management:

monogatari.action('Preload').blocks({
    'Chapter1': {
        music: ['theme_song', 'battle_music'],
        scenes: ['school_gate', 'classroom'],
        characters: { 'y': ['happy', 'sad', 'normal'] },
    },
});

// ...later in your script
'preload block Chapter1 blocking',
// ...and at the end of the chapter
'unload block Chapter1',

Audio is decoded once and persisted in IndexedDB, so re-preloading across sessions is instant β€” unless you unload ... permanent, which clears the persistent cache too.

πŸ“Έ Save Screenshots

Save slots can now show a screenshot of the exact moment a save was made instead of a generic scene image. Turn it on with a single setting:

monogatari.settings({
    'Screenshots': true,
});

When enabled, the engine captures the game screen (via modern-screenshot) as you save and stores it in a dedicated IndexedDB database, kept separate from your save data so it never bloats the save object. Slots then render that screenshot as their thumbnail. ⚠️ Screenshots have a couple of requirements around CSP and cross-origin assets β€” see the upgrade notes below and the Saving documentation.

πŸ’Ύ File System Storage

For games packaged as desktop apps (Electron / Electrobun), there’s a new FileSystem storage adapter that writes saves straight to disk through a desktop bridge instead of the browser’s IndexedDB:

monogatari.settings({
    'Storage': {
        'Adapter': 'FileSystem',
        'Store': 'SaveData',
    },
});

If the same build is opened on the web (no desktop bridge present), it automatically falls back to IndexedDB, so it keeps working everywhere.

πŸ™ˆ Show & Hide Textbox

Two tiny but frequently requested actions to get the dialog UI out of the way β€” perfect for showing off a CG or a scene:

'show scene cg_sunset with fadeIn',
'hide textbox',
'wait 2000',
'show textbox',
'e ...beautiful, right?',

Visibility is part of the saved state, so it survives save/load and rollback. One thing to remember: once hidden, the box stays hidden for every following line until you show textbox again β€” so always bring it back before a line you want the player to read. Docs: show textbox Β· hide textbox.

✨ A Big Library of Text Effects

Dialogue now supports inline text effects with a simple {effect}…{/effect} markup. Open with {effect} and close with {/effect}:

'y I am {angry}absolutely furious{/angry}! {pause:500}{whisper}...but I will be okay{/whisper}.',
'narrator The {glitch}corrupted{/glitch} signal pointed somewhere {mysterious}strange{/mysterious}.',

There are 40+ effects across several families:

Effects nest, so you can combine them:

'{shake}{angry}STOP{/angry}{/shake} right there!',

…and they’re all driven by CSS custom properties, so you can re-tune them globally without touching the engine:

type-character[data-component] {
    --effect-shake-intensity: 4px;
    --effect-wave-amplitude: 0.5em;
    --effect-wave-speed: 0.6s;
    --effect-glitch-color-1: #ff00ff;
    --effect-glitch-color-2: #00ff00;
}

The full list and details live in the Dialogs and Type Writer docs.

⏩ Semi-Instant Skipping

If you keep InstantText off β€” so finishing a line rushes the typewriter while keeping its effects, rather than dumping the whole line at once β€” you can now also let players make that rush genuinely fast. Set the min value of the text-speed slider in your settings screen below 0:

<input type="range" min="-100" max="50" step="1" data-action="set-text-speed">

Players who drag the slider into the negative range get a near-instant fast-forward that still respects formatting and effects.

🚦 A Proper Action-Blocking API

Actions that need to pause the story until they finish β€” waiting on a choice, a notification permission, an async load β€” now declare a static blocking flag and a shouldProceed() check instead of toggling a global. The old block / executing sub action globals still work for now but are deprecated; if you maintain custom actions, see the upgrade notes below.

πŸ› Bug Fixes

πŸ“¦ Misc

How To Upgrade

If you’re on a v2.x.x version

For most games, upgrading is the usual drill: replace the files in your engine directory with the new ones from the download. A few things are worth double-checking:

If you’re on v1.4.1 (stable) or below

If you’re upgrading from a game built on v1.4.1, we recommend reading the Upgrade Guide first β€” the jump to v2 is a big one.