Command line

The worldplane CLI

One binary, worldplane, for studios and for CI. Its studio commands call the control plane's API, so anything they do can also be done in the panel or with curl. worldplane --help and worldplane <command> --help print the same flags as this page; worldplane --version prints its version.

CommandWhat it does
login, logoutSign in to a control plane and keep the session; end it.
tenant createMake an organisation.
project createMake a project (a game).
env create, env updateMake or change an environment.
env secret set|list|deleteAn environment's secrets.
build push, build checkUpload a packaged server; check an archive locally.
deployPut a build on an environment.
checkCheck an Unreal project for what it needs.
coordinator, control, fake-serversRun WorldPlane's own services locally.

Stopping a zone, reading its status, usage, the audit log, members and keys have no command: use the panel or the API.

Install#

Sign in to the panel and download it from Engine integrations on your organisation's overview: Windows or Linux, x86-64. No subscription is needed for it. Put it in a folder on your PATH; on Linux, make it executable first:

chmod +x worldplane && sudo mv worldplane /usr/local/bin/
worldplane --version

CI downloads it with an API key (GET /v1/downloads/cli/{platform}):

curl -fOJ "https://app.worldplane.net/v1/downloads/cli/linux" -H "Authorization: Bearer $WORLDPLANE_KEY"
chmod +x worldplane

Signing in, and CI#

The studio commands find the control plane and their credentials in one of two ways:

  • An API key, for CI: when WORLDPLANE_KEY is set (a wpk_... key from the panel's API keys), the CLI uses it with WORLDPLANE_URL, which must then be set too.
  • A session, for people: otherwise, the session worldplane login kept.
export WORLDPLANE_URL=https://app.worldplane.net
export WORLDPLANE_KEY=wpk_...        # from your CI's secret store
worldplane build push --project mystudio/mygame --label "$CI_COMMIT_SHA" LinuxServer.zip
worldplane deploy mystudio/mygame/test <build id>

The session is kept in session.json in %APPDATA%\worldplane on Windows, or $XDG_CONFIG_HOME/worldplane (else ~/.config/worldplane) elsewhere, readable by its owner only on Unix. WORLDPLANE_CONFIG_DIR names another folder instead. A session lasts 30 days.

A command that the control plane refuses exits non-zero and prints the status and the control plane's reason, such as 402 Payment Required: this needs an active WorldPlane subscription....

worldplane login#

Signs a person in and keeps the session for later commands. It asks for the password without showing it, and for the authenticator's code when the account has one.

worldplane login --url https://app.worldplane.net --email you@studio.example
FlagMeaning
--email <EMAIL> requiredThe account's e-mail.
--url <URL>The control plane. Default: WORLDPLANE_URL; one of them is needed.
--password-stdinRead the password from standard input instead of asking for it. A byte-order mark and the line ending are dropped. With it, the CLI doesn't ask for a code: pass --code.
--code <CODE>The 6-digit code from your authenticator app, if the account has one.

Accounts are made in the panel (or with POST /v1/accounts); the CLI has no sign-up.

worldplane logout#

Ends the session on the control plane and deletes the session file. If the control plane can't be reached, the file is still deleted. No flags.

worldplane tenant create#

worldplane tenant create mystudio --name "My Studio"
Argument / flagMeaning
<SLUG> required2 to 18 lowercase letters, digits or -, starting with a letter.
--name <NAME> requiredIts name in the panel.

You become its owner. Needs a person's session: an API key can't make an organisation.

worldplane project create#

worldplane project create mystudio/mygame --name "My Game"
Argument / flagMeaning
<TENANT/PROJECT> requiredThe organisation and the new project's slug.
--name <NAME> requiredIts name in the panel.

worldplane env create#

worldplane env create mystudio/mygame/test --region us-east-2 --map /Game/Maps/World \
  --max-servers 8 --size plus --budget 2 --sleep-after 15 --server-arg -MyGameFlag
Argument / flagDefaultMeaning
<TENANT/PROJECT/ENV> requiredWhere, and the environment's slug, such as test.
--region <ID> requiredA region the control plane runs zones in (the panel lists them; GET /v1/regions).
--map <PATH> requiredThe map every server opens: an Unreal package path such as /Game/Maps/World. From Git Bash, set MSYS_NO_PATHCONV=1.
--name <NAME>the slugIts name in the panel.
--min-servers <N>1The fewest servers the zone spreads over.
--max-servers <N>4The most.
--size <SIZE>standardstandard (1 vCPU, 2 GiB), plus (2, 4 GiB) or max (4, 8 GiB). A minute of a plus one counts as 2 server-minutes, of a max one 4.
--half-size <METRES>1000How far the zone reaches from the map's origin along x and y.
--warm-servers <N>1Idle servers kept booted, ready to take part of the zone at once. Each is billed like any server; 0 is cheapest, and a split then waits for a boot.
--sleep-after <MINUTES>neverMinutes with no players before the zone sleeps; the wake endpoint starts it again.
--budget <USD>no limitUSD an hour the zone may spend.
--server-arg <ARG>An argument added to every server and the gateway, such as -MyGameFlag. Repeatable; values may start with -. Placeholders: {index}, {role}, {env:NAME} (see server arguments).

Server capacity (the load one server carries) has no flag; it stays at 100 unless changed in the panel or the API.

worldplane env update#

Changes an environment's name, budget or zone; a running zone takes it at its next deploy. Only what you give changes. The region can't change.

worldplane env update mystudio/mygame/test --map /Game/Maps/Other --max-servers 12 --size max
Argument / flagMeaning
<TENANT/PROJECT/ENV> requiredThe environment.
--name, --map, --min-servers, --max-servers, --size, --half-size, --warm-serversAs for env create.
--sleep-after <MINUTES> / --no-sleepSleep after that long with no players, or never.
--budget <USD> / --no-budgetA new hourly budget, or none.
--server-arg <ARG>The servers' arguments, replacing the old ones. Repeatable.

With none of them it stops with nothing to change.

worldplane env secret#

An environment's secrets, which its servers get as {env:NAME} in their arguments. Names are 1 to 64 capitals, digits or _, starting with a letter; names starting with WP_ are WorldPlane's own. Values are up to 4 KiB.

worldplane env secret set mystudio/mygame/test API_TOKEN          # asks for the value, unshown
printf '%s' "$API_TOKEN" | worldplane env secret set mystudio/mygame/test API_TOKEN
worldplane env secret set mystudio/mygame/test API_TOKEN --from-file token.txt
worldplane env secret list mystudio/mygame/test
worldplane env secret delete mystudio/mygame/test API_TOKEN
CommandArguments and flags
set<TENANT/PROJECT/ENV> <NAME>, and --from-file <FILE> to read the value from a file. Otherwise the value comes from standard input: asked for without echo at a terminal, or piped in. Never from an argument, which shell history keeps. A byte-order mark and the final line ending are dropped; lines inside stay.
list<TENANT/PROJECT/ENV>. Names and when each was set, in UTC; never values.
delete<TENANT/PROJECT/ENV> <NAME>. A running zone keeps it until its next deploy.

worldplane build#

build push#

Uploads a zip of the packaged LinuxServer folder as a new build, and waits for its checks.

worldplane build push --project mystudio/mygame --label 0.4.1 LinuxServer.zip
Argument / flagMeaning
<ARCHIVE> requiredThe zip.
--project <TENANT/PROJECT> requiredThe project.
--label <LABEL> requiredYour version label, such as 0.4.1 or a commit.

On app.worldplane.net the archive goes straight to storage in parts (each tried three times); a control plane that takes archives itself gets it in one request. The CLI then waits, up to an hour, while the build is imaged and started once. It prints the build's id and the deploy command when the build is ready, and exits non-zero with the reason when it is rejected or failed.

build check#

Runs the control plane's checks on an archive, on your machine, before you upload it.

worldplane build check LinuxServer.zip
worldplane build check LinuxServer.zip --json

--json prints the decision as JSON (state, reason, digest, plugin). Without it, it prints the plugin version found, or exits non-zero with the reason it would be rejected.

worldplane deploy#

worldplane deploy mystudio/mygame/test 3f2a9c...
ArgumentMeaning
<TENANT/PROJECT/ENV> requiredThe environment.
<BUILD> requiredThe build's id, as build push printed it. An older build rolls back.

It returns once the zone has been started, and prints the zone's status.

worldplane check#

Checks an Unreal project for what it needs before it runs on WorldPlane, from its files only. Exits 1 when it finds errors. See checking a project for what it looks for.

worldplane check path/to/MyGame --fix
Argument / flagMeaning
<PROJECT> requiredThe project's folder or its .uproject.
--fixFirst make the changes that need no judgment (the plugin and settings, Iris support in modules with fast arrays, the line a pawn's TakeDamage needs), then report what is left.
--jsonPrint the findings as JSON.

Local tools#

These run WorldPlane's own services on your machine, for development and testing. Studios on app.worldplane.net don't need them.

CommandFlags
coordinator: run a zone's coordinator.--config <FILE> a TOML zone config (defaults apply without one); --bind <ADDR> overrides its bind.
control: run a control plane.--config <FILE> a TOML config; without one it listens on 127.0.0.1:8080, keeps data in ./worldplane-control and runs zones on this machine.
fake-servers: stream simulated walkers to a coordinator, posing as game servers, so Atlas has something to show.--coordinator <URL> (default http://127.0.0.1:8090), --count <N> servers (2), --entities <N> walkers (200), --hz <N> samples a second per server (5, at most 60), --duration <SECONDS> (until Ctrl-C), --seed <N> (1; the same seed replays the same run).