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:
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.

The file can also define a profiles map alongside cliOptions, selected with --profile <name> to layer profile-specific overrides on top of the base options. See Named Profiles for the merge order and an example.

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/example-plugin
Local file/path--plugin ./plugins/my-plugin.ts
Executable--plugin executable:./my-provider

Orchestrator (Built-In)

The Orchestrator ships provider implementations for the public CLI, and it is registered as a built-in plugin — the same way the built-in Unity, Godot, and Unreal engine plugins are. You don't need to load it with --plugin; it's already available:

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

You can set the provider strategy in .game-ci.yml too:

cliOptions:
providerStrategy: local-docker
targetPlatform: StandaloneLinux64

Then run:

game-ci orchestrate ./my-project

Provider strategies can also be config-defined providers:

cliOptions:
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 set of plugins add engine support and cross-cutting capabilities.

Every plugin below is experimental

None of them are published to npm, and each one warns at runtime when used. Two of them (steam-deploy, runtime-test-framework) are implemented and loaded by default, but their options may still change without a major version bump. The rest are structural drafts: the plugin shape is real, but the domain logic is not written, so any command they claim will throw. Load a draft only with an explicit --plugin @game-ci/<name> (or a plugins: entry in .game-ci.yml).

PluginKindStatus
@game-ci/steam-deployDeploy commandImplemented, loaded by default. game-ci deploy steam <buildPath> - VDF generation, local/Docker SteamCMD.
@game-ci/runtime-test-frameworkCommandImplemented, loaded by default. game-ci test-runtime <buildPath> - see below.
@game-ci/gamemakerEngineDraft - registration shape only, build logic not 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 a full-game upload.
@game-ci/github-release-deployDeploy commandDraft - attaches artifacts to a GitHub/GitLab Release.
@game-ci/code-signingCommandDraft - command not yet registered in core either.
@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/screen-captureCommand, GPUDraft - visual-regression comparison is real and tested (digest-based, not perceptual), the capture command is not.
@game-ci/dedicated-server-provisioningCommandDraft - docker-compose/systemd/firewall generation is real and tested, the provision-server command is not.
@game-ci/dev-tunnelCommandDraft - the exposed-service directory (with public/private disclosure rules) is real and tested, the tunnel command is not.
@game-ci/anti-cheatOptionsDraft - hooks into an existing build rather than adding a command; no vendor SDK integration written yet.

Several of the command-based drafts also need a small core change to register their command name with the CLI at all (the same change deploy itself once needed) before they can be invoked, even once their logic exists. Each plugin's own README.md under plugins/<name>/ in the game-ci/cli repo states exactly what is real versus planned.

Crash-symbol collection is not on this list - unlike the plugins above, it lives in the Orchestrator itself as a built-in output type, since debug symbols have to be captured at build time or they're gone for good. See Output Collection.

Runtime Test Framework

game-ci test-runtime <buildPath> is a 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 player, which game-ci test's -runTests path uses) and reports on whatever tests its in-game harness ran.

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

buildPath can point 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 several, rather than guessing.

This plugin never runs test code itself. Your project's own in-game 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 harness checks for GAME_CI_RUNTIME_TEST_MODE, runs whatever tests it likes, 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 does not exit within --timeout) and fails the step on any passed: false entry, or if the file was never written.

The results file, not the exit code, is authoritative - a player that writes valid results but happens to exit non-zero for an unrelated reason still has its real 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.