Create a plugin
A plugin is a bundle of files that ships with your novel. It usually includes a script that runs when the novel starts. That script can add new features, or extend and override the behavior of other plugins, including the bundled ones. Anything Inkweaver’s own plugins can do, yours can too.
Scaffold a plugin
Section titled “Scaffold a plugin”The quickest way to start is to let the CLI create a plugin for you. Make a folder for your plugin, open a terminal there, and run:
ink init-pluginnpm installProject structure
Section titled “Project structure”my-plugin/├── .build/├── .release/├── assets/│ └── plugin.json├── src/│ ├── commands/│ │ ├── greet.ts│ │ └── index.ts│ ├── selectors/│ │ └── index.ts│ ├── index.ts│ └── plugin-types.ts├── package.json└── tsconfig.jsonassets
Section titled “assets”The files that ship with your plugin, other than scripts.
This folder must include plugin.json, and it can hold anything else too, like .psd artwork, .fountain or .fdx screenplays, and audio. Everything in it is available to your novel.
plugin.json
Section titled “plugin.json”Your plugin’s name, version, and entry point:
{ "name": "my-plugin", "version": "1.0.0", "main": "index.js"}main is a path relative to the .build folder, not your source folder. See the plugin.json reference for every field.
src/index.ts
Section titled “src/index.ts”Your plugin’s entry point. It must export a createPlugin function:
import { bindContext, ContextKey, onInitState, Plugin,} from "@inkweaverdev/inkweaver-sdk";import * as commands from "./commands";import * as selectors from "./selectors";
export function createPlugin(key: ContextKey): Plugin { bindContext(key);
onInitState({ default: { greetingCount: 0 }, });
return { commands, selectors, };}createPlugin runs once, when the novel starts. It returns the commands and selectors your plugin provides.
bindContext connects your plugin to its own private state and services. It’s required, and it must run before anything else in your plugin uses the SDK.
onInitState sets your plugin’s starting state. See State and settings for more.
src/plugin-types.ts
Section titled “src/plugin-types.ts”The TypeScript types for your plugin’s public API. Your plugin’s commands and selectors are declared here by extending the SDK’s Commands and Selectors interfaces:
import "@inkweaverdev/inkweaver-sdk";
declare module "@inkweaverdev/inkweaver-sdk" { interface Commands { greet: (ctx: GreetArgs) => Promise<GreetResult>; } interface Selectors { getGreetingCount: () => GetGreetingCountResult; }}
export interface GreetArgs { name: string;}
export interface GreetResult { greeting: string;}
export interface GetGreetingCountResult { count: number;}
export {};decorateCommand and decorateSelector are typed against these interfaces. Until you declare a command or selector here, no code can decorate it, including your own.
src/commands and src/selectors
Section titled “src/commands and src/selectors”Your command and selector implementations. Keeping them in separate folders is a convention, and it keeps createPlugin tidy as your plugin grows.
package.json
Section titled “package.json”A standard npm manifest for your plugin.
tsconfig.json
Section titled “tsconfig.json”The TypeScript configuration. It compiles everything in src into the JavaScript your plugin ships.
.build
Section titled “.build”A temporary folder with your compiled scripts and a copy of assets. Look here to see what your plugin will contain.
.release
Section titled “.release”Where your finished .inkb file goes. It’s a zip archive of the .build folder.
Bottle your plugin
Section titled “Bottle your plugin”Before you can use a plugin in a novel, you need to bottle it. Run:
npm run bottleThis compiles your TypeScript and packages your plugin as an .inkb file in the .release folder.
Test your plugin
Section titled “Test your plugin”You can try a plugin in a novel without copying it into the novel’s workspace. Bottle your plugin, then add its path to the externals entry in the novel workspace’s .env file:
externals=../../plugins/my-plugin/.release/my-plugin.inkb,../../plugins/my-plugin/.release/another-plugin.inkbexternals is a comma-separated list of paths, relative to the novel’s workspace. Inkweaver includes each one whenever it builds the novel.