Skip to content

Repository files navigation

NilVN engine

CI npm

A small visual-novel (ADV / galgame) engine for the browser. Scripts read like a story — yuki: Hi! plus a few bracket commands — and everything expressive (screen shake, text effects, sprite animation, choice styling, camera moves, the in-game menu) is a plugin you can write in plain JavaScript. The engine is the mechanism — parser, stage, audio, saves, languages, a capability-sandboxed plugin host — and ships no plugins of its own; the first-party set is the sibling repository nilvn-plugins (@nilvn/plugins), written against the same public surface as any third-party plugin. TypeScript, DOM + CSS rendering, no framework, one runtime dependency that the single-file build drops.

This repository is the open, MIT-licensed part of NilVN. The visual "director" editor that produces games for this engine (NilVN Studio, web and desktop) is a separate closed-source product; what it exports runs on the packages here.

Package What it is
@nilvn/engine The runtime: parses and plays scripts, renders the stage, hosts plugins, saves and restores. Ships an ESM build and a self-contained IIFE.
@nilvn/core The contract layer: the project document model, command and plugin-manifest schemas, the script-package format, serializers. No DOM, no dependencies.
@nilvn/plugin-sdk Plugin authoring: manifest types and validator, the extension-point and permission catalogs, runtime types, a starter package and the generated plugin-spec.json contract.

The three are versioned and released together (engine-v* tags → npm).

Quick start

pnpm add @nilvn/engine @nilvn/plugins
import { createEngine } from '@nilvn/engine'
import { withFirstParty } from '@nilvn/plugins'

const engine = createEngine({ ...withFirstParty(), container: document.getElementById('app')! })
await engine.loadConfig('./nilvn.config.toml')   // plugins, actors, aliases, macros, defaults
await engine.start()
[use textfx screenfx]
[bg assets/bg/classroom.jpg]
[char yuki smile]
yuki: {wave:Hi!} Want to make a game together?
[shake strength=10]
[choice Sure -> yes]
[choice Maybe later -> later]

A game exported by the studio is a script package; engine.load('./my-game/') plays it, streaming scenes on demand. The content language defaults to en; a multi-language game passes lang, defaultLang, languages and per-language catalogs.

Try it: the demo game built from the first-party plugins runs at nilzx.github.io/nilvn-plugins.

Documentation

Writing a plugin

// engine.js — the runtime half named by plugin.json "entries.engine"
export default {
  id: 'com.example.neon',
  permissions: ['stage.write'],
  textEffects: { neon: (span) => span.addClass('fx-neon') },
  commands: {
    async boom({ num, plugin }) {
      await plugin.stage?.animate('camera', [{ x: -8 }, { x: 8 }, { x: 0 }], { durationSec: 0.3, compose: 'offset' })
    },
  },
}

A plugin declares permissions and receives capability objects for exactly those; it never sees the engine or the DOM, and everything it registers is released when it is deactivated, so plugins can be enabled, disabled and reloaded while a game runs. Start from packages/plugin-sdk/template; the first-party plugins in nilvn-plugins are worked examples of every extension point, held to the same rule by a boundary check.

Repository

packages/
  core/         @nilvn/core
  engine/       @nilvn/engine   src/ · docs/ · scripts/ (the bare IIFE builder)
  plugin-sdk/   @nilvn/plugin-sdk
scripts/        pack-smoke.mjs
pnpm install
pnpm test              # vitest across the three packages, including a boot of the built IIFE
pnpm typecheck         # every package
pnpm typecheck:test    # the test suites themselves
pnpm build             # dist/ for the three packages (ESM + .d.ts + the engine IIFE)
pnpm spec:check        # the generated plugin contract matches its source
pnpm pack:smoke        # pack the tarballs and consume them from a throwaway project

This repository is a mirror of the packages' home in NilVN's private monorepo: every change arrives as a sync commit, and an engine-v* tag mirrored onto one releases the three packages to npm (CONTRIBUTING.md).

The demo game and the single-file game bundler live in nilvn-plugins, next to the plugins they show off.

Requires Node 22+ and pnpm. Contributions welcome — see CONTRIBUTING.md; open an issue first for anything beyond a fix, so the change can be discussed against the studio that consumes these packages. Release history: CHANGELOG.md.

License

MIT — see LICENSE.

About

NilVN visual-novel engine: @nilvn/core (contracts), @nilvn/engine (runtime), @nilvn/plugin-sdk (plugin authoring)

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages