gameplane / docs
REFERENCE

GameServer and GameTemplate schema

Map server intent to template compatibility, configuration, workload resources, storage, networking, lifecycle, and placement.

API & Referencev0.22 MIN

A GameServer is a single running game server instance. A GameTemplate is a cluster-scoped blueprint defining the container image, ports, console protocol, and configuration schema that servers instantiate.

Every GameServer references exactly one GameTemplate by name (spec.templateRef.name). The template provides sensible defaults for compute resources, storage layout, networking, probes, and lifecycle. A server’s spec then overrides or specializes those defaults for its own workload — pinning a version, setting config values, requesting specific CPU/memory, or tuning placement.

GameServer desired state

The GameServer spec has two layers: identity (which template and version to run) and overrides (what to change from the template’s defaults).

FIELD TYPE DEFAULT DESCRIPTION
spec.templateRef.name string required Template name this server instantiates. Immutable; delete and recreate to switch templates.
spec.version string template default Selects a GameTemplate.spec.versions[].id, pinning that version’s image and env. Empty selects the template’s default version.
spec.image string template Image Overrides GameTemplate.Spec.Image. Useful for pinning a specific build or running a fork.
spec.config map[string]string Validated values from the template’s configSchema. Each key maps to a ConfigField.Name.

Configuration and resources

FIELD TYPE DEFAULT DESCRIPTION
spec.resources object template defaults CPU and memory requests and limits (Kubernetes ResourceRequirements).
spec.storage object template defaults PVC class, size, volume mount path, and additional data volumes.
spec.env []EnvVar (template env) Appended to (and overrides) the template’s env vars.
spec.probes object template probes Overrides the template’s readiness/liveness/startup probes.

Networking

FIELD TYPE DEFAULT DESCRIPTION
spec.networking.expose string “ClusterIP” Service type: ClusterIP, NodePort, LoadBalancer, or Hostport.
spec.networking.hostname string — Optional DNS name advertised via ingress / external-dns annotations.
spec.networking.serviceAnnotations map[string]string Merged into the Service’s annotations (for LoadBalancer config, external-dns hooks, etc.).
spec.networking.portOverrides []PortOverride (none) Pins a specific NodePort or overrides the Service port for a named template port.
spec.networking.sourceRanges []string (allow all) IP allow-list (CIDRs) for the fronting Service (LoadBalancer only).
spec.networking.addressPool string — Load-balancer address pool to request this server’s external address from (LoadBalancer only).
spec.networking.address string — One specific external address to request (LoadBalancer only). Overrides addressPool if both set.
spec.networking.tunnel object disabled Relay-based connectivity (frp, Tailscale, or playit) for installs with no public IP.

Lifecycle and placement

FIELD TYPE DEFAULT DESCRIPTION
spec.suspend bool false When true, scales the underlying StatefulSet to zero. Data is preserved. Transitions to Suspended phase.
spec.stopGracePeriodSeconds int 30 Soft-stop timeout while the template’s lifecycle.stop sequence runs over RCON. Range: 0–600.
spec.nodeSelector map[string]string Kubernetes node selection labels passed to the pod spec unchanged.
spec.tolerations []Toleration (none) Kubernetes pod tolerations for tainted nodes.
spec.affinity object (none) Kubernetes pod affinity/anti-affinity rules.

Mods, backups, idle, and capture

FIELD TYPE DEFAULT DESCRIPTION
spec.mods object (none) For games that manage mods by ID (see GameTemplate capabilities.mods.idList). Maps to mod providers.
spec.backupPolicy object (none) Inline BackupSchedule for this server. When set, the operator creates a managed BackupSchedule owned by this server.
spec.idle object disabled Auto-sleep configuration: enabled flag, minutes until sleep, wake windows (cron), and wake-on-connect.
spec.capture object disabled Packet-capture configuration: opt-in enabled flag and retention window (seconds). (v0.3.0)
spec.serviceAccountName string auto-created Overrides the ServiceAccount the pod runs as. Default is per-server <name>-agent with minimal RBAC.

GameTemplate blueprint

A GameTemplate defines the reusable container image, ports, console protocol, and configuration schema that all servers instantiating it inherit.

FIELD TYPE DESCRIPTION
spec.displayName string Human-friendly label shown in the dashboard (e.g., “Minecraft Java Edition”).
spec.game string Canonical game identifier (e.g., “minecraft-java”, “valheim”). Grouping key in the UI catalog.
spec.categories []string Marketing categories like “Survival”, “Sandbox”. The dashboard builds its filter from distinct values across installed templates.
spec.version string Template revision (e.g., “1.0.0”). Bump when changing defaults existing servers should opt into.
spec.icon string Optional URL or data URI shown in the catalog.
spec.accentColor string Optional CSS hex color (e.g., “#3b82f6”) the dashboard uses to tint the game’s icon and accents.
spec.description string Free-form markdown describing the template.
spec.image string Default container image (e.g., “itzg/minecraft-server:2025.1.0”). Fallback when a server selects no version and sets no override.
spec.versions []GameVersion Optional catalog of selectable game versions. Each maps a user choice to a concrete image and optional per-version env/loader. At most one entry should set default=true; otherwise the first entry is the default.
spec.command / spec.args []string Override the container image entrypoint when set.
spec.env []EnvVar Default environment for the game container.
spec.ports []GamePort Exposed ports: name, container port, protocol (TCP/UDP), advertise flag, wake protocol.
spec.storage object Default persistent storage layout: size, storage class, mount path, extra volumes.
spec.resources object Default compute resources (requests and limits).
spec.rcon object Remote-console protocol: “source” (Minecraft/Valve), “telnet”, “websocket”, “battleye”, “satisfactory”, “palworld”, “nuclearoption”, “rest”, “cli”, or “none”.
spec.consoleMode string How the Console tab attaches: “rcon” (line-based commands), “pty” (stdin/stdout), or “none”.
spec.logPath string File holding the game’s primary log, as seen from inside the pod (e.g., “/data/logs/latest.log”). Must live under the data volume so the agent can tail it.
spec.probes object Default readiness/liveness/startup probes for the game container.
spec.configSchema []ConfigField User-tunable fields surfaced in the Create Server wizard. Resolved values are set as env vars or rendered into config files.
spec.configFiles []ConfigFile Files the operator renders from resolved config values and places under storage.mountPath before the game starts.
spec.agent object Tunes the sidecar deployed alongside the game: image override, resource limits.
spec.capabilities object Game-specific console commands (player moderation, backup quiesce, lifecycle stop, custom actions, live metrics, mod management).
spec.security object Pod/container security: runAsUser, runAsGroup, fsGroup. For games whose image refuses root or expects a specific uid.

Status and conditions

The operator populates status fields after reconciliation:

FIELD TYPE DESCRIPTION
status.phase string High-level state: Pending, Starting, Running, Stopping, Stopped, Suspended, or Failed.
status.observedGeneration int64 The generation of spec that the operator last observed (for detecting stale status).
status.conditions []Condition Detailed state transitions. Standard Ready, Progressing, and Healthy conditions are surfaced in the UI.
status.endpoints []GameServerEndpoint Externally reachable addresses (host, port, protocol, pool) once the Service is reconciled.
status.tunnelEndpoints []GameServerEndpoint Per-port addresses reported by the tunnel pod when spec.networking.tunnel.enabled is true (frp/tailscale computed at reconcile time; playit populated asynchronously).
status.agent AgentStatus Runtime info from the in-pod sidecar: version, heartbeat time, players online, CPU/memory usage, disk usage.
status.startedAt timestamp Wall-clock time the game container was last observed as Ready.
status.lastBackupTime timestamp Completion time of the most recent successful backup.
status.idle object Observed idle auto-sleep state: empty since when, asleep flag, sleep/wake times, reason.
status.capture object Capture system state: ready flag, active capture name, last capture time, sidecar restart count. (v0.3.0)
Verification best practice

Use status.observedGeneration and status.conditions to confirm the operator has applied the latest spec generation. A condition’s status, reason, and message fields explain blockers (e.g., image pull failure, insufficient resources, invalid config).

Configuration field schema

Each entry in configSchema declares a single user-tunable field surfaced in the Create Server wizard:

FIELD TYPE DESCRIPTION
name string Field identifier (also used as env var when target is “env”).
displayName string Shown in the UI.
description string Explains the field to end users.
type string Input widget: “string”, “int”, “bool”, “enum”, or “password”. Passwords are stored in a per-server Secret.
default string Default value rendered in the wizard.
enum []string Valid values when type is “enum”.
required bool When true, blocks wizard submission if unset.
target string “env” (default) sets an env var; “file” makes the value available to configFiles templates.
autoFromMemoryLimit object Derives the value from the game container’s memory limit (e.g., floor(limit × percent / 100)).
min / max int64 Inclusive bounds for int-typed fields.
minLength / maxLength int32 Inclusive bounds for string and password fields.

Port definitions

Each entry in ports declares an exposed port:

FIELD TYPE DEFAULT DESCRIPTION
name string required DNS-label port identifier (e.g., “game”, “query”, “rcon”).
containerPort int required Port the game listens on inside the pod (1–65535).
protocol string TCP TCP or UDP.
advertise bool true When true, exposed to users via GameServer.Spec.Networking. RCON/query ports typically set this to false.
wakeProtocol string generic Parser for the wake sentinel while the server sleeps: “minecraft” (real Minecraft join detection), “terraria”, “generic” (plausible traffic), or “none” (never wake).

Storage specification

The storage spec (both template and server-level overrides) defines persistent volumes:

FIELD TYPE DEFAULT DESCRIPTION
size string (none) Default PVC size (e.g., “10Gi”).
storageClassName string (none) Pins the PVC to a specific StorageClass when set.
mountPath string “/data” Where the persistent volume mounts inside the game container.
dataSource object (none) Seeds the PVC from a CSI VolumeSnapshot (for restore-from-snapshot).
extra []ExtraVolume (none) Additional persistent volumes beyond the primary data volume (max 4).

Tunnel configuration

When spec.networking.tunnel.enabled is true, connectivity routes through a relay instead of relying on cluster ingress:

FIELD TYPE REQUIRED DESCRIPTION
enabled bool true Enables the tunnel for this server.
provider string yes Relay backend: “frp” (static public address), “tailscale” (private tailnet), or “playit” (dynamic public address).
credentialsSecretRef object yes (if enabled) Secret in the GameServer’s namespace with provider-specific credentials.
frp object yes (if provider is “frp”) frp config: serverAddr, serverPort, remotePorts.
tailscale object no Tailscale config: MagicDNS hostname, ACL tags.
playit object no Playit config: optional tunnel name.

Idle auto-sleep configuration

When spec.idle.enabled is true, the operator scales the server down once it reports no players for a threshold:

FIELD TYPE DEFAULT DESCRIPTION
enabled bool false Turns idle auto-sleep on for this server.
afterMinutes int 30 Minutes of continuous zero players before sleep (5–1440).
wakeWindows []string (none) Cron expressions (cluster timezone) at which a sleeping server wakes up. Max 8 entries.
wakeOnConnect bool false Arms the wake sentinel: while asleep, a small pod holds the advertised ports and wakes the server on a genuine join attempt.
Coming in v0.3.0

spec.capture / status.capture and the packet-capture sidecar are not yet available in v0.2.0-beta.8; they ship in the upcoming v0.3.0 release.

Capture configuration

When spec.capture.enabled is true, the operator injects a packet-capture ephemeral container into the pod:

FIELD TYPE DEFAULT DESCRIPTION
enabled bool false Opts into packet-capture capability for this server.
retentionSeconds int cluster default Per-server override of the cluster-wide retention window (60–604800 seconds).

Real-world example

apiVersion: gameplane.local/v1alpha1
kind: GameServer
metadata:
  name: survival-world
  namespace: game-servers
spec:
  templateRef:
    name: minecraft-java
  
  version: "1.21.4-paper"
  config:
    eula: "true"
    difficulty: "3"
    pvp: "true"
    max-players: "20"
  
  resources:
    requests:
      cpu: "1000m"
      memory: "3Gi"
    limits:
      cpu: "4000m"
      memory: "6Gi"
  
  storage:
    size: "50Gi"
    storageClassName: "fast-ssd"
  
  networking:
    expose: LoadBalancer
    addressPool: us-west-2
    sourceRanges:
      - "203.0.113.0/24"
      - "198.51.100.0/24"
  
  nodeSelector:
    disktype: ssd
  
  tolerations:
    - key: game-servers
      operator: Equal
      value: "true"
      effect: NoSchedule
  
  backupPolicy:
    schedule: "0 2 * * *"  # Daily at 2 AM
    repoRef:
      name: primary-backup-repo
      key: credentials
    retention:
      keepDaily: 7
      keepWeekly: 4
  
  idle:
    enabled: true
    afterMinutes: 60
    wakeWindows:
      - "0 8 * * *"      # Daily at 8 AM
      - "0 18 * * *"     # Daily at 6 PM
    wakeOnConnect: true

For detailed CRD field validation rules, Kubernetes defaults, and immutability constraints, see the operator/api/v1alpha1/gameserver_types.go and operator/api/v1alpha1/gametemplate_types.go source files in the main repository.