Narrat is a game engine for making interactive narrative RPGs packed with features.. Create your game by editing with a Simple scripting syntax. It supports Skills with skill check rolls, an Items inventory, and has a Quests System. The script system is very powerful and allows branching choices, functions, variables and conditions.
Go to the Getting Started Guide.
Try the engine directly in your browser (experimental, only works on desktop):
Or try editing the default narrat game easily:
With Codeflow you can test Narrat quickly without setting up an IDE
More info on the narrat website. There is an online demo available to try in the browser.
Note: Narrat is a monorepo using pnpm
as package manager. The packages
folder contains the individual packages, including the main narrat
package.
Narrat is written in TypeScript. It uses the Vue framework for front-end development. It also uses pinia for state management
- node.js (Downloading LTS is fine)
- pnpm. This Narrat repo is a monorepo using pnpm workspaces to easily manage the different packages.
- A text editor capable of editing a TypeScript and Vue.js project. Recommended: VSCode and the extension Volar for Vue.
- Install dependencies
pnpm install
- Run the demo
pnpm dev
This starts the engine on the demo page with the example.narrat
demo script loaded for testing.
If developping on the narrat package, it's better to go inside the narrat package folder and run commands there.
There are multiple demo games and it's possible to add new ones. For example npm run rpg
will run the rpg
demo. Demos are in the examples
folder.
Running a specific demo is done by changing an environment variables. See the scripts in package.json
for how to run a specific demo.
start
: Start the demo for developmentbuild
: The main build command, builds the library in a state ready to use or publish.test
: Unit tests, used in CIdev
: Same as startgenerate-types
: Generates.d.ts
type declaration files for the library (auto run on builds)fix-type-aliases
: Uses tsc-alias to auto-replace path mappings in the built files, as the TypeScript compiler doesn't do it. (auto run at the end of builds)lint
: Runs the linter on the code (used in CI)check-types
: Validates TypeScript types.
The following tasks run on CI, and CI is required to pass for pull requests to be merged:
- Linting
- Engine build
- Unit tests (currently only the parser is unit tested)
- TypeScript type checking.
Please make sure your code passes lint/tests/build/type checks before opening a PR.
The narrat codebase isn't currently documented, outside of the usage docs. The code is fully written in TypeScript though and should be clearly separated enough to be approachable.
The narrat engine runs primarily as a Vue app. All the UI in the game is made of Vue components, and when a game uses narrat it effectively creates a Vue app.
The engine's state is stored in pinia. It is split in separate pinia modules for different areas of the engine. They can all be found in the src/stores folder.
audio
: handles playing and stopping audio and musicdialog
: Receives and stores all lines of dialogue created by game scripts which appear at the right of the game in the main interactive narrative view.hud
: Stores stats which are displayed on the hudinventory
: Manages the player's item inventorymain
: Manages app-level logic and other generic systems like startup/reset/load/savenotifications
: Manages notifications which appear at the top of the screenquests
: Manages quests and objectivesrendering
: Manages the layout's state for dynamically placing and resizing the game UIskills
: Manages player skills and xp. Also store skill check statesvm
: Manages the virtual machine which runs the scripting language and controls the game flow.
All stores can be accessed anywhere in the code with the use
hooks (example: useVM()
).
The scripting language for narrat runs in a virtual machine which has its state stored in the Vue app with Pinia.
The narrat scripting language relies on the parser and the vm. The code for the parser is mainly in src/vm/vm-parser.ts. The parser is in charge of taking the .narrat
files as input, and returning a tree of parsed expressions that the engine can use.
The actual VM is what runs narrat games, and generally controls the flow of the application. The general logic for the vm is in the vm
store, but there is also some logic sprinkled in the src/vm
file.
All the actual operations available to the scripting language (like talk
) are defined as Command plugins. The built-in commands included in the language by default are in the src/vm/commands folder. More command can be added by games by registering plugins.
Language commands are defined in the vm/commands
folder. It should be easy to add new commands to the game engine by looking at the existing commands as an example. New command plugins are included in the vm/commands/index
file.
The main config file has a type defined in src/config.ts
. The vast majority of the config options for narrat are passed in this config files, which games must provide to the engine when starting. New options for the engine should be added to the type for the config file, and also have their default value included in the src/defaultConfig.ts
file.
Engine code can access the config with the getConfig()
function.
There is now a plugin system developers can use to add new functionality to narrat (more documentation soon). See the narrat-bitsy plugin for an example.
(Note: The narrat-bitsy plugin hasn't been updated for 2.0.0 and might be a bit out of date).
The documentation website uses Vitepress. Files are in markdown and can be edited. Making a pull request or pushing to master will deploy the change.
To run the docs, open a terminal at the root of the monorepo (not in the docs folder) and run:
pnpm run docs:dev
The docs also use:
highlight.js
for custom syntax highlightingcode-input
to turn syntax highlight editable for the live narrat preview in the docs
- Pointing arrows from OpenGameArt
- UI button from OpenGameArt
- 10 Basic RPG enemies
- RPG Battle backgrounds from OpenGameArt
- 3D City from OpenGameArt
- Input Prompts by Kenney (Creative Commons CC0)
- OpenDyslexic font by Abbie
- Other fonts from Google fonts
The rest is handmade.