Appearance
Templates
Template files define how Encore launches and governs game server instances. Each .toml file in template_folder becomes one spawnable server profile.
Where templates are loaded from
Encore reads templates from template_folder configured in server config:
toml
template_folder = "/etc/encore/templates"At startup (and on admin reload), Encore scans that directory for .toml files, parses each template, validates it, and registers valid entries. The directory may be empty at startup — templates can be added later via the admin API or by placing .toml files in the folder and reloading.
Port allocation
Port allocation is a server-level concern, not a template concern. Templates have no port field. Instead, declare port pools in config.toml:
toml
[[port_pool]]
range = "7000-7099"
[[port_pool]]
range = "7100-7249"When any instance needs a port, Encore picks one from whichever pool has one available. Ranges must not overlap.
Minimal template
toml
[template]
name = "Quick Match - Deathmatch"
id = "game_QkMtDm7A2x"
binary_path = "/opt/gameservers/arena/server.x86_64"Full template schema
toml
[template]
name = "Ranked Arena - 3v3"
id = "game_Rnkd3v3B9q"
binary_path = "/opt/gameservers/ranked/server.x86_64"
max_instances = 20
max_lifetime = "35m"
port_liveness_probe = true
working_dir = "/opt/gameservers/ranked"
args = [
"--headless",
"--",
"--port={{port}}",
"--instance-id={{instance_id}}",
"--map={{map_name}}",
"--team-size={{team_size}}"
]
[template.extra_options]
map_name = "string"
team_size = "int"
overtime = "bool"
[template.env]
GAME_ENV = "production"
GODOT_LOG_LEVEL = "warn"
[template.isolation]
enabled = true
clear_env = true
env_allowlist = ["PATH", "HOME", "LANG"]
[template.isolation.cgroup]
enabled = true
memory_max = "2147483648"
memory_high = "1610612736"
memory_swap_max = "0"
cpu_max = "150000 100000"
cpu_weight = 200
pids_max = 384Field reference
name(required): human-readable display name.id(required):game_+ 10 alphanumeric chars.binary_path(required): executable to spawn.max_instances(optional): cap concurrent instances for this template (0means unlimited).max_lifetime(optional): auto-terminate timeout (30m,1h,2h30m).port_liveness_probe(optional): wait for local port readiness before reporting success.working_dir(optional): process working directory.args(optional): argument list with template substitution support.env(optional): environment variables added to process env.extra_options(optional): API whitelist + type validation.isolation(optional): isolation settings; cgroup controls are available now, other path fields are reserved for future use.
Argument substitution
Supported placeholders in args:
{{port}}(always available){{instance_id}}(always available)- keys from validated
extra_options
If extra_options includes unknown keys, they are ignored. If type validation fails for whitelisted keys, create request fails.
Extra options typing
Supported types:
stringintfloatbool
Example:
toml
[template.extra_options]
max_players = "int"
map_name = "string"
friendly_fire = "bool"Security
Templates are also your main security policy. They define what each game server process is allowed to inherit, how much host resource it can consume, and how much blast radius a bad/misbehaving match can have.
In practice, security here has two layers:
- Process boundary (
[template.isolation]): controls how isolated the runtime environment is. - Resource boundary (
[template.isolation.cgroup]): caps CPU, memory, and process count per instance.
How this is applied:
When isolation is enabled, Encore applies these controls during instance spawn. If the configured safety controls cannot be applied (for example, cgroup setup fails when cgroup limits are required), the instance creation fails instead of starting without protection.
Process boundary (environment hardening)
Use [template.isolation] to reduce ambient trust from the host environment:
enabled = true: turns isolation policy on for this template.clear_env = true: starts the process with an empty inherited environment.env_allowlist = [...]: re-add only explicitly approved variables.
This is useful when your host has secrets or operational variables that should not leak into child game server processes by default.
Resource boundary (cgroup v2 limits)
Use [template.isolation.cgroup] to contain runaway or abusive workloads and keep host stability under contention:
memory_max: hard memory ceiling.memory_high: soft pressure threshold before hitting hard cap.memory_swap_max: swap budget (often0for stricter behavior).cpu_max: hard CPU quota ("<quota> <period>").cpu_weight: relative CPU priority when sharing CPU.pids_max: max number of processes/threads an instance can create.
Typical goal:
- prevent one match from starving other matches
- avoid host-wide OOM cascades
- cap fork/thread explosion risk
- keep latency and fairness predictable during peak concurrency
Managing templates via API
Templates can be managed programmatically through the admin API without SSH access to the Encore host.
Upload files
Upload one file (simple binary):
bash
curl -X POST http://localhost:8080/api/v1/uploads \
-H "x-admin-token: $TOKEN" \
-F "file=@server.x86_64"Upload multiple files (e.g. Godot binary + asset pack):
bash
curl -X POST http://localhost:8080/api/v1/uploads \
-H "x-admin-token: $TOKEN" \
-F "file=@game.x86_64" \
-F "file=@game.pck"
# → {"directory": "/var/lib/encore/uploads/upl_xxx", "files": [{"filename": "game.x86_64", "path": "...", "size": ...}, ...]}All files land in the same server-chosen random directory with their original filenames preserved. Filenames are validated — only [a-zA-Z0-9._-] characters are allowed; invalid names are rejected.
Create a template
Use the entry-point file's path from the upload response as binary_path:
bash
curl -X POST http://localhost:8080/api/v1/templates \
-H "x-admin-token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "My Game", "binary_path": "/var/lib/encore/uploads/upl_xxx/game.x86_64"}'
# → {"id": "game_xxx", "name": "My Game", ...}Only name and binary_path are required. All other fields use template defaults. Companion files (.pck, data directories) are co-located in the same upload directory and found automatically by the binary at runtime.
Update a template
bash
curl -X PUT http://localhost:8080/api/v1/templates/game_xxx \
-H "x-admin-token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"max_instances": 5, "max_lifetime": "2h"}'Partial updates are supported — only the provided fields are changed. Running instances keep their original config.
Delete a template
bash
curl -X DELETE http://localhost:8080/api/v1/templates/game_xxx \
-H "x-admin-token: $TOKEN"If the template has running instances, it is marked as spawn-disabled rather than removed. The uploaded binary is not deleted (binaries may be shared across templates).
For full endpoint details, see the HTTP API Reference.
Authoring workflow (file-based)
- Set
public_hostinconfig.tomlto your server's public IP or hostname. - Create a minimal template with
name,id,binary_path. - Add
argsand only theextra_optionskeys you actually need. - Set
max_instancesandmax_lifetimebased on game mode behavior. - Enable
port_liveness_probefor real readiness checks. - Add cgroup limits for competitive/high-density modes.
- Validate before deploy:
bash
encore validate --config-file /etc/encore/config.tomlRepository examples
This repository ships scenario-based templates in /templates:
quick-match-deathmatch.tomlranked-arena-3v3.tomlcoop-raids-4p.toml
