A visual-novel engine · MIT

Saga

A small, dependency-free visual-novel engine for the browser.

Plain JavaScript · one stylesheet · no build step · works offline

Free & fully offline — nothing to install. The Android .apk is sideload-only (allow installs from unknown sources).

Version 1.0.2 License: MIT Zero dependencies No build step Works offline GitHub stars
Zero dependencies No build step Works offline Keyboard play Seven endings Web Audio music

What it does

A whole visual novel, in plain files

Saga runs from a static file server with nothing installed. It reads your story from plain .scene text, keeps the state, and plays it — and it was built to make Aethelgard — The Books.

Branching dialogue

A per-line speaker, ten expressions and a portrait that changes with the mood of the line. Choices branch, and @label/@goto let a branch rejoin the main line.

Gates you can see

Options with a requirement like [Bonds 2] are shown greyed-out with the reason, never hidden. You always know what you missed.

Four axes, seven endings

Every choice moves one of four hidden counters — Mercy, Truth, Bonds or Conviction. The ending is their shape, resolved from Dawn to Hollow.

The Diary & the Backlog

The Diary fills itself as you play — people, places, lore, decisions and deeds. The Backlog scrolls back through everything said. Intro cards greet a character the first time they appear.

Music, synthesised

The score is generated with the Web Audio API — there are no audio files at all. Save to localStorage, and export or import a run as a JSON file.

Mods with five safety rules

Drop a folder in mods/ and the engine finds it. Mods add chapters, cast and regions — and can never break a running game: every load is wrapped, conflicts are refused visibly, and order is deterministic.

Achievements Save & export Tested from 360×640 Full keyboard play prefers-reduced-motion honoured Dialog semantics & focus outlines

How it works

Three files and a folder

The engine ships no story of its own. To make a game you replace three things and nothing else changes.

01 · Serve it

Nothing to install

Scene files are read over http, so serve the folder. Any static server works — no install, no build, no dependencies.

# from the project folder
python3 -m http.server 8000
# open http://localhost:8000
02 · Write a chapter

Plain text, one line each

A chapter is a .scene file you could write in a notebook. Add one line to scenes/manifest.js and it appears.

@bg road
narrate A road at dusk.
keeper warm "I am."

choice
* "Tell the truth." => truth+1
03 · Make it yours

Replace your data

Your cast and regions in js/chars.js, your chapters in scenes/, your art in assets/sprites/. The engine never needs to know your chapter ids.

js/chars.js      your cast
scenes/          your chapters
assets/sprites/  your art

See it

The stage

portrait The Keeper "You're doing it again." "The fire had been out for an hour." Tell the truth. [Bonds 2] Say you knew her mother.

Illustrative mock of the engine's stage — background, portrait, dialogue box and choices. Not a screenshot.

Play the demo, or the game it was built for

The engine ships with a short demo story — two chapters and all seven endings — so you can see the format and the shape resolver at work.

  • Advance with Space/Enter, pick choices with Tab + Enter.
  • D opens the Diary, B the Backlog, S saves, Esc closes.
  • Mouse and touch work throughout; tested from 360×640 up.

The demo is MIT, like the engine. Aethelgard — The Books — a visual novel in three books, 36 chapters and seven endings — is the game Saga was built to make; its artwork and story are © Dr. Sohil Momin, all rights reserved.

Get started

Clone it and serve the folder

# 1. clone
git clone https://github.com/drsamonline/saga-vn-engine.git
cd AethelgardVN

# 2. serve (nothing to install)
python3 -m http.server 8000

# 3. open http://localhost:8000

If you change any scene, regenerate the embedded bundle so the engine still boots from file://:

python3 tools/make-bundle.py

FAQ

Questions

Is Saga a game?
No — Saga is an engine. It ships no story of its own. The two chapters and seven endings in this repo are a demo, MIT-licensed like the code, so you can see the format. The game it was built for, Aethelgard — The Books, is a separate work.
What do I need installed to run it?
Nothing. It is plain JavaScript with one stylesheet, no build step and no dependencies. Serve the folder with any static server — python3 -m http.server, npx serve, nginx or GitHub Pages.
Does it work offline, or from a file:// page?
Yes. Scenes, mods and the sprite list are embedded as plain script, so the engine boots from file:// as well as over http. The classic path is still to serve the folder over http.
How do I make my own game on it?
Replace three things: your cast and regions in js/chars.js, your chapters in scenes/ (with a manifest.js listing them), and your art in assets/sprites/. Nothing else needs to change.
How do the endings work?
Every choice moves one of four hidden counters — Mercy, Truth, Bonds or Conviction. The ending is the shape: which axis led and how far the four spread. Seven endings resolve from that, from Dawn to Hollow. The resolver in js/endings.js is pure data — rewrite it freely.
What is the licence?
Two licences, clearly split. The Saga engine — code, stylesheet, tools, the demo story and placeholder art — is MIT: use it, fork it, ship it. The Aethelgard — The Books game's artwork, story and characters are © Dr. Sohil Momin, all rights reserved — free to play, not open source, and not contained in this repository.