Skip to main content
A NanoForge game is made of apps (a client, a server), and each app uses engine libraries: @nanoforge-dev/ecs, @nanoforge-dev/graphics-2d, @nanoforge-dev/network… A plugin for the ECS means nothing in an app without it.

Say what the plugin needs

  • required: an app must have these libraries (in these version ranges) for the plugin to apply to it.
  • optional: libraries the plugin can use when they are there.
The plugin is still loaded in a project where no app has them: it decides what to show.

Apps the plugin applies to

Each app has its id, name, type (client, server, or lib for a shared library) and engineLibs (name to installed version). missingEngineLibs(manifest, app) lists what an app lacks, and isEligible(manifest, app) answers yes or no.

In when clauses

The running game

RuntimeServiceToken is the game the editor plays.
Commands: runtime.play, runtime.pause, runtime.resume, runtime.step, runtime.restart, runtime.stop. The session also says which apps play, in which mode, and whether the game can be paused (controllable). Context keys: runtime.active, runtime.state, runtime.controllable.

Asking the engine for data

The engine sends nothing unless asked. A plugin asks for features, and gets events while the game runs.
  • Requests of every plugin are merged; the most demanding one wins. Dispose your request when your panel is hidden: ask in an effect on instance.visible, not when the plugin starts.
  • An older engine ignores features it does not know: handle the absence of events.
  • The game only runs in a local editor. A hosted editor never builds or runs project code.

Game output

Everything the game prints goes to the editor’s logger, under the sources game:client and game:server. A plugin’s own context.logger lines show under Plugins.