# Monogatari > Visual Novel Engine Monogatari is a simple web visual novel engine, created to bring visual novels to the web. > Full content export — 149 documents. --- # Demo > Play with Monogatari live in your browser. Source: https://monogatari.io/demo

Taking you to the Monogatari demo

--- # Contributors > The people who made Monogatari awesome. Source: https://monogatari.io/contributors

Monogatari is not the work of just one person — it's the work of everyone who has shared their experience, time, and knowledge to make it awesome for you. To all of these people: thank you!

Want to see your name here?

Sponsors keep Monogatari free, open source, and growing. Support the project and you'll join the wonderful people below — every sponsor is featured right here on this page.

Become a Sponsor

Prefer another way? You can also support via

PayPal Patreon Ko-fi

Past Sponsors

With heartfelt thanks to everyone who has supported Monogatari over the years — your generosity helped keep it free and open source for everyone.

Alix LepinayAlix LepinayPast SponsorIdea Contributor
Carmen LopezCarmen LopezPast Sponsor
CesarCesarPast SponsorIdea Contributor & Tester
codecodePast Sponsor
Elea Islas OcampoPast Sponsor
eyeteetheyeteethPast Sponsor
JJPast Sponsor
Judy WPast Sponsor
Kazuto SenseiKazuto SenseiPast SponsorDocumentation Contributor & Tester
Michael Jay TuckerMichael Jay TuckerPast Sponsor
Tom NguyenTom NguyenPast SponsorIdea Contributor & Tester
Zhou Cong ArtZhou Cong ArtPast Sponsor
ぷりぷりPast Sponsor

Contributors

Ahmadmanga
AhmadmangaCode Contributor
Anthony Z
Anthony ZCode Contributor & Tester
Bao Nguyen
Bao NguyenIdea Contributor
Biquet
BiquetFrench Translator
Bobokox
BobokoxIdea Contributor & Tester
Darckoune
DarckouneCode Contributor & Tester
Dragoon HP
Dragoon HPIdea Contributor & Tester
Fernando Saavedra
Fernando SaavedraConsultant & Idea Contributor
Filipe Vieira
Filipe VieiraPortuguese Translator
ign1ght
ign1ghtDutch Translator
Izra
IzraTester
Jiun Wei Chia
Jiun Wei ChiaCode Contributor
Josh Anthony
Josh AnthonyCode Contributor
Josh Powlison
Josh PowlisonIdea Contributor
Kagami Hiiragi
Kagami HiiragiCode Contributor & Tester
Isak Grozny
Isak GroznyIdea Contributor & Tester
Lee Yunseok
Lee YunseokKorean Translator
Maxwell P. Brickner
Maxwell P. BricknerCode Contributor
Mdabrowski
MdabrowskiCode Contributor
Medow
MedowRomanian Translator
Mickey Sanchez
Mickey SanchezCode Contributor
M. Nafis Al-Mukhdi
M. Nafis Al-MukhdiIndonesian Translator
Morf
MorfTester
Mr. Two Hand
Mr. Two HandIdea Contributor & Tester
Oluwaseun Ogedengbe
Oluwaseun OgedengbeIdea Contributor & Tester
Patience Daur
Patience DaurRussian Translator
Piiritaja
PiiritajaTester
Remi Autor
Remi AutorCommunity Manager, Idea Contributor, Documenter & Tester
Renoa
RenoaArabic Translator
Ruolin Zheng
Ruolin ZhengChinese Translator
Sergey Kuznetsov
Sergey KuznetsovRussian Translator & Tester
ShinProg (Logan Tann)
ShinProg (Logan Tann)French Translator & Code Contributor
Stephen Lavelle
Stephen LavelleGerman Translator
WaffleMeido
WaffleMeidoArtist commissioned for original characters
Xiony
XionyTester
Yakauleu Uladzislau
Yakauleu UladzislauBelarusian Translator
--- # Monogatari > Built for the modern web — create and distribute visual novels that play anywhere. Source: https://monogatari.io/

Built for the modern web — create and distribute visual novels that anyone can play pretty much anywhere. Free, open source, and designed so you can write your story as easily as if you were just writing it.

Download Monogatariv2.8.0
Join us on Discord Star on GitHub

Features

✍️

Simple Syntax

You don't need to be a developer. Monogatari's friendly language lets you write your story naturally — yet it's powerful enough for anything you imagine.

🎬

Multimedia Support

Images, video, music, sound effects — bring your scenes to life with any kind of media.

🌐

Multi-language

Built-in translation support so players can enjoy your story in their own language.

💾

Feature Full

Save and load, animations, rewind, auto-play, text skipping, and more — out of the box.

🎨

Customizable

Think of your game as a website: anything you've seen on the web is within your reach.

📱

Responsive

Plays beautifully on any screen, on any device, right out of the box.

Progressive Web App

Installable and playable offline, just like a native app.

🔓

Open Source

Released under the MIT License — use it for anything, commercial or not, completely free.

🖥️

Multi-platform

Ship to the web, or build for Windows, macOS, Linux, Android, and iOS.

Get Involved

Monogatari is 100% open source and built collaboratively by people all over the world. Even if you're not a programmer, you can help.

Built on Open Source

Monogatari would not be possible without these awesome open source projects.

Animate.cssEntrance, exit, and attention animations. ArtemisDOM manipulation, storage, and utilities. CSShakeCSS shake animations. FlarumForum software powering the community. Font AwesomeIcons used across the UI. KayrosBase styling for grids, modals, and more. modern-screenshotCaptures the save-slot screenshots. MousetrapKeyboard shortcut handling. PandoraWeb Components for custom elements. tsParticlesParticle systems.

Sponsor

Monogatari is developed and distributed as a completely free product. Every little bit of support helps us keep building new features and maintaining the project.

GitHub Sponsors

Prefer another way? You can also support via

PayPal Patreon Ko-fi

Not what you're looking for?

Monogatari's goal isn't competition — here are some other awesome open source engines worth checking out.

Ren'Py

The most widely used visual novel engine — Python-powered, battle-tested, and behind thousands of released games.

TyranoScript

A free HTML5 engine with a friendly, tag-based script and excellent mobile support.

RenJS

A browser-based engine built on Phaser, with your whole story configured in simple YAML files.

Every story should be told before it's lost forever.

--- # Hide Text Box > Hide the dialog text box to show off the scene behind it. Source: https://monogatari.io/v2/script-actions/hide-textbox Section: Documentation ## Description ```text 'hide textbox' ``` The `hide textbox` action hides the dialog [text box](/v2/components/text-box), leaving only the background, characters and other visuals on screen. It's perfect for letting a dramatic scene, a CG, or an animation breathe without the interface in the way. Bring the text box back with [`show textbox`](/v2/script-actions/show-textbox). **Action ID**: `Hide::TextBox` **Reversible**: Yes **Requires User Interaction**: No ## Behavior When `hide textbox` runs: 1. The `` component's `hidden` state is set to `true`, so the box animates out of view. 2. The engine records `textboxHidden: true` in its game state, so the text box stays hidden across saving and loading. 3. The game automatically advances to the next statement. On rollback, the text box is shown again. ## Usage ```javascript monogatari.script ({ 'Start': [ 'show scene cliff with fadeIn', 'show character e normal at center with fadeIn', 'e Here it is. Everything we worked for.', 'hide textbox', 'wait 2500', 'show textbox', 'e Worth every step.', 'end' ] }); ``` > [!TIP] > The text box is also toggled by the player at any time with the quick-menu **Hide** > button. Use `hide textbox` when *you* want to script that beat, for example during a > reveal or a panning background. > [!IMPORTANT] > `hide textbox` sets a persistent state: the text box stays hidden — even while later > dialog lines run — until you call [`show textbox`](/v2/script-actions/show-textbox). Always show the > box again before the next line you want the player to read, or that dialog will be > set on a box that is still invisible. ## Related Actions - [Show Text Box](/v2/script-actions/show-textbox) - Bring the dialog text box back - [Text Box](/v2/components/text-box) - The dialog component this action toggles - [Wait](/v2/script-actions/wait) - Hold on the scene while the text box is hidden --- # Show Text Box > Make the dialog text box visible again after it was hidden. Source: https://monogatari.io/v2/script-actions/show-textbox Section: Documentation ## Description ```text 'show textbox' ``` The `show textbox` action makes the dialog [text box](/v2/components/text-box) visible again after it has been hidden with [`hide textbox`](/v2/script-actions/hide-textbox). Use it to bring the interface back once the player has had a moment to take in the artwork behind it. **Action ID**: `Show::TextBox` **Reversible**: Yes **Requires User Interaction**: No ## Behavior When `show textbox` runs: 1. The `` component's `hidden` state is set to `false`, so the box animates back into view. 2. The engine records `textboxHidden: false` in its game state, so the text box's visibility is preserved across saving and loading. 3. The game automatically advances to the next statement. On rollback, the previous (hidden) state is restored. ## Usage A common pattern is to hide the text box so the player can admire a scene, then show it again to resume the conversation: ```javascript monogatari.script ({ 'Start': [ 'show scene landscape with fadeIn', 'e Look at this view!', 'hide textbox', 'wait 2000', 'show textbox', 'e ...breathtaking, right?', 'end' ] }); ``` > [!TIP] > Pair `hide textbox` / `show textbox` with [`wait`](/v2/script-actions/wait) or a [choice](/v2/script-actions/choices) > so the player has a beat to enjoy the scene before the dialog returns. > [!NOTE] > Because the hidden state is stored in the game state, a player who saves while the > text box is hidden will see it hidden again when they load that save. ## Related Actions - [Hide Text Box](/v2/script-actions/hide-textbox) - Hide the dialog text box - [Text Box](/v2/components/text-box) - The dialog component this action toggles - [Wait](/v2/script-actions/wait) - Pause before showing the text box again --- # Language Selection Screen > A pre-game screen letting players pick a language, shown for multi-language games that have the language selection screen enabled. Source: https://monogatari.io/v2/components/language-selection-screen Section: Documentation ## Description ```markup ``` The language-selection-screen component lets the player choose a language before the game starts. For [multi-language](/v2/configuration-options/game-configuration/internationalization) games, it shows one button per language detected in your script, each with the language's flag icon and name. Selecting a language saves it as the player's `Language` preference and localizes the engine. **Source Code**: [https://github.com/Monogatari/Monogatari/tree/develop/src/components/language-selection-screen](https://github.com/Monogatari/Monogatari/tree/develop/src/components/language-selection-screen) ## When It Appears The screen only does any work when **both** of these settings are `true`: - `MultiLanguage` - marks the game as having a script in multiple languages. - `LanguageSelectionScreen` - enables this screen before the asset loading screen. Both are configured in `options.js`. When either is `false`, the screen renders no buttons and stays out of the way (players change language from the [Settings Screen](/v2/components/settings-screen) instead). See [Internationalization](/v2/configuration-options/game-configuration/internationalization) for the full setup. > [!NOTE] > You most likely **won't see this screen** if you converted an existing single-language game, because your `Language` preference is already saved. To trigger it, clear the stored settings (for example, with your browser's dev tools). ## How Languages Are Detected The list of languages comes from the keys of your script. By default the `languages` prop is set to `Object.keys (monogatari._script)`, which is the list of language objects you defined in `monogatari.script ()`. For each language, the screen looks up its metadata (registered via `monogatari.languageMetadata ()`) to get the flag `icon`. If a language has no metadata, an error is shown telling you which language is missing it. ## Structure The component renders a heading and a row of language buttons: ```html

Select your language

``` Each button carries a `data-language` attribute with the language name. The icon span is only rendered when the language metadata provides an `icon`. ## Content Areas | Name | Selector | Description | | :--- | :--- | :--- | | `wrapper` | `[data-content="wrapper"]` | The screen content container | | `title` | `[data-content="title"]` | The "Select your language" heading | | `buttons` | `[data-content="buttons"]` | The container holding the language buttons | | `icon` | `[data-content="icon"]` | A language's flag icon (only rendered when metadata provides one) | | `language` | `[data-content="language"]` | A language's name | ## Props | Property | Type | Default | Description | | :--- | :--- | :--- | :--- | | `languages` | `string[]` | `Object.keys (monogatari._script)` | The languages to show, taken from the script's top-level keys | | `timeout` | `number` | `2000` | The interval, in milliseconds, used to cycle the heading translation (see below) | ## State | Property | Type | Default | Description | | :--- | :--- | :--- | :--- | | `open` | `boolean` | `false` | Whether the screen is visible (inherited from the base screen component) | | `index` | `number` | `0` | The index of the language whose translation is currently shown in the heading | ## Cycling Heading To hint that multiple languages are available, the heading cycles through each language's translation of the `SelectYourLanguage` string. After the screen mounts, a timer advances the `index` state every `timeout` milliseconds (2 seconds by default), wrapping back to the first language at the end of the list. Each time `index` changes, the heading text is replaced with that language's translation. > [!NOTE] > This cycling only runs while the screen is visible, and only when both `MultiLanguage` and `LanguageSelectionScreen` are enabled. The timer is cleared automatically when the screen unmounts. ## Selecting a Language Clicking a button reads its `data-language` value and applies it: ```javascript monogatari.preference ('Language', language); monogatari.localize (); ``` This saves the chosen language as the player's `Language` preference and re-localizes the engine so the rest of the game appears in that language. ## Styling ```css language-selection-screen [data-content="wrapper"] { flex-direction: column; padding: 2rem; height: 100%; justify-content: center; } language-selection-screen [data-content="buttons"] { display: flex; flex-wrap: wrap; justify-content: center; } language-selection-screen button { background: transparent; border: 4px solid var(--main-color); border-radius: 10px; padding: 1rem; color: var(--text-color); display: flex; flex-direction: column; align-items: center; } language-selection-screen button [data-content="icon"] { font-size: 3rem; line-height: 1; margin: 1rem 0; } language-selection-screen button [data-content="language"] { font-weight: bold; } ``` ## Related - [Internationalization](/v2/configuration-options/game-configuration/internationalization) - The `MultiLanguage` and `LanguageSelectionScreen` settings and the full multi-language setup - [Settings Screen](/v2/components/settings-screen) - Where players can change their language during play - [Loading Screen](/v2/components/loading-screen) - Shown after a language is selected --- # Help Screen > An in-game screen listing the quick menu buttons and keyboard shortcuts, opened from the Help button in the main menu. Source: https://monogatari.io/v2/components/help-screen Section: Documentation ## Description ```markup ``` The help-screen component shows players how to interact with the game. It explains how to advance through dialogs and lists every quick menu button alongside its keyboard shortcut. It is a screen component, so it is opened and closed like the other screens (Settings, Save, Load, etc.). ![The default help screen|The help screen — quick-menu buttons on the left, their keyboard shortcuts on the right.](https://cdn.restlessdreams.cloud/3bca0648-a68b-440a-9771-427fe62915c2.webp) **Source Code**: [https://github.com/Monogatari/Monogatari/tree/develop/src/components/help-screen](https://github.com/Monogatari/Monogatari/tree/develop/src/components/help-screen) ## Usage The help screen is reached from the **Help** button in the main menu. That button uses the `open-screen` action targeting the `help` screen: ```javascript { string: 'Help', data: { action: 'open-screen', open: 'help' } } ``` The screen is closed with the back button in its top-left corner, which uses the `back` action. ## Structure The help screen renders a back button, a heading, an "advance" hint, and two sections: one for the **Quick Menu** buttons and one for **Keyboard Shortcuts**. Each entry pairs a symbol with an instruction: ```html

Help

To advance through the game, left-click or tap anywhere on the game screen or press the space key

Quick Menu

Go back

Keyboard Shortcuts

H
Hide the text box
``` The `data-screen="help"` attribute is added automatically when the screen mounts (the `-screen` suffix is stripped from the tag name). ## Content Areas | Name | Selector | Description | | :--- | :--- | :--- | | `help` | `[data-content="help"]` | The wrapper holding the help hint and both sections | | `symbols` | `[data-content="symbols"]` | The icon or shortcut key for an item | | `shortcut` | `[data-content="shortcut"]` | A keyboard key rendered as a styled badge | | `instruction` | `[data-content="instruction"]` | The text describing what the symbol does | ## Help Strings All the help text is localized through `data-string` attributes. The strings rendered by the screen are: | String Key | Default | Description | | :--- | :--- | :--- | | `Help` | "Help" | The screen heading | | `AdvanceHelp` | "To advance through the game, left-click or tap anywhere on the game screen or press the space key" | The advance hint | | `QuickMenu` | "Quick Menu" | The quick menu section heading | | `KeyboardShortcuts` | "Keyboard Shortcuts" | The keyboard shortcuts section heading | | `BackButton` | "Go back" | Back button / shortcut | | `HideButton` | "Hide the text box" | Hide button / shortcut | | `DialogLogButton` | "Show the dialog log" | Dialog log button | | `AutoPlayButton` | "Enable auto play" | Auto play button / shortcut | | `SkipButton` | "Enter skip mode" | Skip button / shortcut | | `SaveButton` | "Open the Save Screen" | Save button / shortcut | | `LoadButton` | "Open the Load Screen" | Load button / shortcut | | `SettingsButton` | "Open the Settings Screen" | Settings button / shortcut | | `QuitButton` | "Quit Game" | Quit button / shortcut | The keyboard shortcuts shown next to each instruction are `H` (Hide), `A` (Auto play), `S` (Skip), `⇧ S` (Save), `⇧ L` (Load), `ESC` (Settings) and `⇧ Q` (Quit), plus the back arrow for going back. ## Customizing the Help Content > [!TIP] > The help screen's layout is fixed in the component, but all of its text is driven by translations. To change the wording, override the relevant string keys for your language with `monogatari.translation ()`: > > ```javascript > monogatari.translation ('English', { > 'AdvanceHelp': 'Tap or click anywhere to continue the story.', > 'QuickMenu': 'Controls' > }); > ``` > > See [Internationalization](/v2/configuration-options/game-configuration/internationalization) for the full list of UI strings you can override. If you need a completely different layout, you can register your own component under the `help-screen` tag to replace the built-in one. ## Styling ```css help-screen [data-content="help"] { max-width: 1000px; margin: 0 auto; } help-screen .help__sections { display: flex; flex-direction: column; gap: 2rem; } help-screen .help__section { padding: 2rem; display: flex; flex-direction: column; gap: 1rem; } help-screen .help__section__item { display: grid; grid-template-columns: auto 1fr; gap: 1rem; text-align: left; } /* Keyboard shortcut badge */ help-screen [data-content="symbols"] [data-content="shortcut"] { background-color: var(--text-color); color: #fff; border-radius: 2px; text-align: center; } ``` ## Related - [Quick Menu](/v2/components/quick-menu) - The buttons documented by the help screen - [Settings Screen](/v2/components/settings-screen) - Another screen reached from the main menu - [Internationalization](/v2/configuration-options/game-configuration/internationalization) - How to translate or reword the help text --- # Gallery Screen > A screen that displays unlockable CG images in a grid, with locked entries hidden behind a lock icon. Source: https://monogatari.io/v2/components/gallery-screen Section: Documentation ## Description ```markup ``` The gallery-screen component displays a grid of the images registered as gallery assets. Images the player has unlocked are shown as thumbnails; images that are still locked appear as a card with a lock icon. Clicking an unlocked thumbnail opens a full-size viewer. Unlocking and locking is driven from your script by the [Gallery action](/v2/script-actions/image-gallery). **Source Code**: [https://github.com/Monogatari/Monogatari/tree/develop/src/components/gallery-screen](https://github.com/Monogatari/Monogatari/tree/develop/src/components/gallery-screen) ## Configuring Gallery Assets Gallery images are registered with `monogatari.assets`, using `gallery` as the category. The keys are the names you reference from your script; the values are the file names inside your gallery folder: ```javascript monogatari.assets ('gallery', { 'someImage': 'happy-shine.png' }); ``` By default the files live in `assets/gallery`. That location is controlled by the `AssetsPath` setting (`root` and `gallery` keys). > [!NOTE] > If no gallery assets are defined, the screen removes itself and **no Gallery button is added** to the main menu. The [Gallery button](/v2/components/main-menu) only appears once at least one image has been registered. ## Locking and Unlocking On a fresh game every gallery image starts locked. To reveal an image, your script reaches a `gallery unlock` statement; to hide it again, a `gallery lock` statement: ```javascript "gallery unlock someImage", // shows the image in the gallery "gallery lock someImage" // hides it again behind the lock icon ``` The list of unlocked images is stored in the engine's `Storage` under the `gallery` key, so unlocks **persist independently of save files**. Updating that state re-renders the grid immediately. See the [Gallery action](/v2/script-actions/image-gallery) for the full scripting reference. ## Structure The screen renders a back button, a heading, the image grid, and a hidden full-screen image viewer: ```html

Gallery

``` Each asset is rendered as a `
` inside the gallery grid. The markup differs depending on whether it is unlocked: ```html
``` ### Data UI Keys | Key | Element | Description | | :--- | :--- | :--- | | `gallery` | `
` | The grid that holds one `
` per asset. | | `image-viewer` | `