Skip to main content
Version: v4 (current)

Configuration and Plugins

The game-ci CLI can read options from .game-ci.yml and load plugins from command-line flags or config. Those plugins can add engine detection, build commands, test commands, custom commands, options, and provider-backed job execution.

Config File

The CLI looks for .game-ci.yml in the current working directory. You can also pass an explicit config path:

game-ci --config ./ci/game-ci.yml build ./my-project

Options live under cliOptions.

cliOptions:
plugin:
- '@game-ci/orchestrator-plugin'
verbose: true
targetPlatform: StandaloneLinux64
buildsPath: dist

The config file uses the same option names as the CLI's parsed options. In practice, that means camelCase names such as targetPlatform, providerStrategy, customImage, and buildsPath.

Plugin Sources

Plugins can provide engine detectors, build or test command handlers, custom commands, options, and provider implementations.

Source typeExample
NPM package--plugin @game-ci/orchestrator-plugin
Local file/path--plugin ./plugins/my-plugin.ts
Executable--plugin executable:./my-provider
GitHub shorthand--plugin github:game-ci/example-plugin

Direct GitHub loading is reserved for future plugin loader work. Publish the plugin to npm or use a local path for now.

Orchestrator as a Plugin

The Orchestrator ships provider implementations for the public CLI.

game-ci \
--plugin @game-ci/orchestrator-plugin \
orchestrate ./my-project \
--provider-strategy aws

You can also add the plugin to .game-ci.yml:

cliOptions:
plugins:
- '@game-ci/orchestrator-plugin'
providerStrategy: local-docker
targetPlatform: StandaloneLinux64

Then run:

game-ci orchestrate ./my-project

Provider strategies loaded through the Orchestrator plugin can also be config-defined providers:

cliOptions:
plugins:
- '@game-ci/orchestrator-plugin'
providerStrategy: config:./.game-ci/providers/local-shell.yml

Use this when YAML or JSON can describe how to call your existing provider scripts or automation APIs. See Config-defined providers.

Built-In Engine Support

The CLI includes built-in plugins for:

EngineDetection signalBuilt-in command surface
UnityProjectSettings/ProjectVersion.txtEngine command options
GodotGodot project filesEngine command options
Unreal.uproject filesEngine command options

External plugins can add new engine support or replace command behavior without changing the CLI core.

Plugin API

A plugin exports a GameCIPlugin object. It can provide any combination of engine detectors, build commands, test commands, option registration, providers, and an onLoad hook.

export default {
name: 'my-engine',
version: '1.0.0',
engineDetectors: [
{
name: 'my-engine',
detect(projectPath) {
return { engine: 'my-engine', engineVersion: '1.2.3' };
},
},
],
commands: [
{
engine: 'my-engine',
createCommand(command, subCommands) {
if (command === 'build') return new MyBuildCommand(command);
if (command === 'test') return new MyTestCommand(command);
return null;
},
},
],
providers: {
'my-provider': MyProvider,
},
};

Provider plugins register provider strategy names. game-ci orchestrate then creates the provider selected by --provider-strategy. game-ci remote run and game-ci remote build are kept as compatibility aliases for older workflows.

Provider implementations can also live outside the public CLI. The Orchestrator supports configuration-driven providers, executable providers, and TypeScript/JavaScript provider modules. Use the public CLI plugin API when you are adding command surface or engine behavior to game-ci itself; use the Orchestrator provider extension points when you are changing where jobs run.

Plugin Catalog

Beyond the built-in Unity/Godot/Unreal engine plugins and the built-in Orchestrator, a growing set of plugins add engine support and cross-cutting capabilities. steam-deploy and runtime-test-framework are shipped and in the CLI's default load list, the same way Orchestrator is. Everything else below is a draft - load it explicitly with --plugin @game-ci/<name> (or a plugins: entry in .game-ci.yml) once it's real.

PluginKindStatus
@game-ci/steam-deployDeploy commandShipped. game-ci deploy steam <buildPath> - VDF generation, local/Docker SteamCMD execution.
@game-ci/runtime-test-frameworkCommandShipped. game-ci test-runtime <buildPath> - see below for the results contract.
@game-ci/gamemakerEngineDraft - registration shape only, build logic not yet implemented.
@game-ci/rpg-makerEngineDraft.
@game-ci/renpyEngineDraft.
@game-ci/itch-deployDeploy commandDraft - mirrors steam-deploy's shape.
@game-ci/steam-workshopDeploy commandDraft - mods/maps via workshop_build_item.vdf, distinct from steam-deploy's full-game upload.
@game-ci/github-release-deployDeploy commandDraft - mirrors steam-deploy's shape.
@game-ci/code-signingCommandDraft - command not yet registered in core either.
@game-ci/crash-symbol-uploadCommandDraft - command not yet registered in core either.
@game-ci/screen-captureCommand, GPUDraft - command not yet registered in core either.
@game-ci/live-showCommandDraft - command not yet registered in core either.
@game-ci/dedicated-server-provisioningCommandDraft - command not yet registered in core either.
@game-ci/anti-cheatOptionsDraft - hooks into an existing build, not a new command.
@game-ci/pseudo-localizationCommandDraft - command not yet registered in core either.
@game-ci/save-data-compatCommandDraft - command not yet registered in core either.
@game-ci/dev-tunnelCommandDraft - command not yet registered in core either.

"Draft" means a real, correctly-typed plugin skeleton exists (conforming to the plugin interface above), but its actual domain logic is a documented TODO rather than an implementation - see each plugin's own README.md under plugins/<name>/ in the game-ci/cli repo for exactly what's real versus planned. Several of the command-based drafts also need a small core change to register their command name with the CLI at all (the same kind of change deploy itself needed - see the PR that added steam-deploy) before they can be invoked even once their logic is implemented.

Runtime Test Framework

game-ci test-runtime <buildPath> is a real, distinct capability from game-ci test: it launches the actual built player your build step produced (not the Editor, and not Unity's own Test Framework's specialized test player, which game-ci test's -runTests path uses) and reports on whatever tests its own in-game harness ran.

game-ci test-runtime ./build/StandaloneLinux64 --timeout 60000

buildPath can point directly at the executable, or at a directory containing it - the plugin looks for the single matching candidate (one .exe on Windows, one .app bundle on macOS, one executable-bit file on Linux) and errors clearly if it finds none or more than one, rather than guessing.

This plugin never runs test code itself. A game project's own in-game test harness does, against a small results contract:

  1. The plugin launches the player with GAME_CI_RUNTIME_TEST_MODE=1 and GAME_CI_RUNTIME_TEST_RESULTS_PATH=<path> set.

  2. Your in-game harness checks for GAME_CI_RUNTIME_TEST_MODE, runs whatever tests it wants, and writes a JSON file to GAME_CI_RUNTIME_TEST_RESULTS_PATH before exiting:

    {
    "schemaVersion": 1,
    "tests": [
    { "name": "player spawns at origin", "passed": true, "durationMs": 12 },
    {
    "name": "inventory persists across scene load",
    "passed": false,
    "message": "expected 3 items, got 2"
    }
    ]
    }
  3. The plugin reads that file after the process exits (or kills it and fails the run if it doesn't exit within --timeout) and fails the CI step on any passed: false entry, or if the file was never written at all.

The results file, not the process exit code, is authoritative - a player that writes valid results but happens to exit non-zero for an unrelated reason still has its real test results honored.

Local Config Folder

Use config open to open the local GameCI folder:

game-ci config open

The CLI stores its user-level files under ~/.game-ci.