Skip to content

Latest commit

 

History

143 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bindery Core

A Kubernetes-native, capability-driven game platform.

⚠️ DISCLAIMER: EXPERIMENTAL HOBBY PROJECT

This project is fully experimental and is not intended for wider consumption or use. The stated goals are intentionally broad and likely unachievable in a real-world product context; however, they serve the purpose of this hobby project.

Note on Authorship: This repository is now public. Please be aware that almost all code and documentation within this repository were generated by AI. It serves as an exploration of AI-assisted development rather than a demonstration of personal coding expertise.

Bindery Core is an open-source platform designed to decouple game logic from infrastructure. It allows game developers to define their game's backend requirements as abstract "Capabilities" (e.g., Physics, Persistence, Messaging), which the platform then resolves and binds to concrete infrastructure implementations at runtime.

Project Goals

  • Decouple Logic from Infrastructure: Game modules declare what they need, not how it's provided.
  • Game-as-Code: Define entire game worlds, shards, and module dependencies via declarative Kubernetes CRDs.
  • Automated Orchestration: Automate the lifecycle of game servers, including sharding, scaling, and storage provisioning.
  • Standardized Contracts: Use strict gRPC contracts and semantic versioning to ensure module compatibility.

Project State

Status: 🚧 Pre-Alpha / Experimental 🚧

The project is currently in active development.

  • Core Controllers (all six registered in main.go):
    • CapabilityResolver: Resolves abstract requirements to concrete providers.
    • RuntimeOrchestrator: Manages the lifecycle of game server workloads (Deployments, Services).
    • StorageOrchestrator: Provisions and binds persistent storage (PVCs) for stateful modules.
    • WorldShard: Creates and removes WorldShard objects to match WorldInstance.spec.shardCount.
    • Realm: Binds realm-scoped global modules shared across worlds.
    • ShardAutoscaler: Adjusts WorldInstance.spec.shardCount within minShards/maxShards.
  • APIs: v1alpha1 CRDs are defined but subject to breaking changes. Nine CRDs ship in k8s/crds/, mirrored byte-for-byte in helm/bindery-core/crds/.
  • Deployment: Supports local development via Kind and Helm.

External Runtime

Alongside the Kubernetes operator, this repository contains the external runtime reference service: a control plane for matches whose simulation runs in game clients Bindery does not own. Bindery hosts the match envelope and the transport; it is not an authoritative game server, and game-specific code stays out of core.

It was developed on a separate line of history and merged into main on 2026-08-26. It shares the module but not the operator's runtime: there are no CRDs or controllers involved, and the two are wired together only by living in one repository with one CI.

  • Service and relay: internal/externalruntime, internal/relay, pkg/relayv1
  • Evidence reconciliation: pkg/evidencev1 (wired into internal/externalruntime/service.go)
  • Capture plane: internal/capture (canonical encoding, content-addressed object store, normalizers) wired into internal/externalruntime — durable batch ingest, a heavy-object lane, completeness manifests, cursor-paged public reads, and versioned derivations
  • Calibrated gates: pkg/gatev1, consumed by internal/externalruntime/capture_gate.go, which evaluates the consequential gate bindery.capture.completeness over every capture before it may contribute to an evidence set
  • Binaries: cmd/bindery-external-runtime, cmd/bindery-udp-relay, cmd/bindery-redaction-scan
  • Promoted contracts: contracts/externalruntime/v1
  • Chart: charts/bindery-external-runtime
  • Image: ghcr.io/bayleafwalker/bindery-external-runtime, built from Dockerfile.external-runtime and published from main and tags

The repository has two chart roots on purpose. helm/bindery-core deploys the operator and ships the CRDs; charts/bindery-external-runtime deploys a standalone service that defines no CRDs and runs no controllers. They have different lifecycles and different install audiences, so they are versioned separately rather than folded into one chart directory. Only helm/ is covered by make verify-crds, because only helm/ carries CRDs.

They also deploy different images, which is worth stating plainly because they briefly did not:

Chart Dockerfile Image
helm/bindery-core Dockerfile ghcr.io/bayleafwalker/bindery-core
charts/bindery-external-runtime Dockerfile.external-runtime ghcr.io/bayleafwalker/bindery-external-runtime

Both are published by the image job in CI, from main and from tags only, with an SBOM and build provenance attestation each. Each chart's image.tag defaults to its own chart appVersion, so a chart cannot drift from the image it deploys.

Keeping these apart matters: until 2026-08-26 both charts named ghcr.io/bayleafwalker/bindery-core, while the only Dockerfile in the repository built the external-runtime binaries. Restoring the publish job unchanged would have meant helm install bindery-core deploying the external-runtime service instead of the operator.

Observation summaries are derived by the broker from persisted events. For any execution with captured streams, client-supplied counts are refused with OBSERVATION_ADJUDICATION_FORBIDDEN. That is deliberate: the one demonstrated RA2 run was scored by an adapter gate that was confidently wrong in both directions across four iterations, and an evidence set built from figures the adapters reported about themselves cannot support a claim of independence. Repeating the run through this control plane is roadmap item ERH-006 and is still pending — the enabler landed, the run has not happened.

The control plane persists identity, session, placement, execution, enrollment, capture, idempotency, and reconciled evidence through a crash-safe single-writer state store. Capture event bodies and heavy artifacts are content-addressed files beside the snapshot rather than inside it, so a snapshot write stays proportional to the number of batches rather than the number of events. That file-backed mode is deliberately not a multi-replica database: the chart refuses to render with more than one replica, and running wider would need a shared relational store.

GET /v1/sessions is intentionally not implemented. Known session IDs are public; discovery is not. The same known-ID rule applies to placements, executions, enrollments, captures, and evidence sets.

make verify-external-runtime      # race tests, vet, chart lint

BINDERY_RELAY_ENDPOINT=127.0.0.1:50001 \
BINDERY_BUILD_REVISION="$(git rev-parse HEAD)" \
BINDERY_STATE_PATH=/tmp/bindery-control-state.json \
go run ./cmd/bindery-external-runtime

That /tmp path is disposable development state; deployments mount a volume.

The RA2 path has been demonstrated end to end once, and the dated result and its limits — including why the pre-hardening run's identifiers must not be backfilled — are recorded in docs/assessments/2026-08-25-ra2-vertical-slice.md. The evidence and gate boundary is described in docs/architecture/evidence-and-gates.md, and remaining work is tracked in docs/roadmap/post-ra2-hardening.yaml. The research pack under docs/research/external-runtime-multiplayer is immutable input, not a committed roadmap.

Documentation

Start at the documentation index, which explains which of the two subsystems each document covers.

Standards & Architecture

External Runtime

Kubernetes Resources

RPC Contracts

Getting Started

Prerequisites

  • Go 1.22+
  • Docker
  • Kind (Kubernetes in Docker)
  • Kubectl

Local Demo

Spin up a local Kind cluster with all CRDs and example resources installed:

make kind-demo

Tear it down:

make kind-down

Development

Testing

  • Unit Tests: make test
  • Integration Tests: make test-integration (Requires envtest)
  • E2E Smoke Test: make test-e2e (Requires Kind and Docker; creates and destroys a cluster, and covers the sharding path end to end — scale out to two shards, per-shard deployments, then scale back)
  • CRD Gate: make verify-crds — asserts every scheme-registered kind has a manifest in k8s/crds/, and that k8s/crds/ and helm/bindery-core/crds/ are identical
  • Pre-push check: make verify (operator) or make verify-external-runtime (external runtime)

All of the above run in CI (.github/workflows/ci.yml), which has four jobs: go-test (fmt, unit, verify-crds, envtest integration, tidy), sample-game-test, e2e-smoke (Kind), and external-runtime (race tests, vet, chart lint, secret scan).

Running Locally

Run the controller manager against your current kubecontext:

make run-controller

Note: make run-controller disables the metrics and health probe listeners to avoid occupying localhost:8080 (often used by the sample game web client port-forward). If you want the default controller-runtime ports (:8080/:8081), run:

make run-controller-with-metrics

Repository Layout

Operator:

  • api/v1alpha1/: Kubernetes API type definitions.
  • controllers/: Kubernetes controllers (Reconcilers).
  • main.go: Controller manager entrypoint.
  • internal/resolver, internal/semver: Resolution logic used by CapabilityResolver.
  • internal/graph: Unused scaffolding. Its own package comment says "no logic is implemented yet", and nothing outside the package imports it.
  • k8s/crds/: CRD manifests (mirrored into helm/bindery-core/crds/).
  • k8s/dev/: Kind demo scripts.
  • helm/bindery-core/: Helm chart for the operator.
  • modules/: Module template (physics-engine-template).
  • examples/booklet-bindery-sample/: Runnable sample game (its own Go module).
  • e2e/: Kind-based smoke test.

External runtime:

  • internal/externalruntime, internal/relay, internal/harness, internal/capture.
  • pkg/evidencev1, pkg/gatev1, pkg/relayv1.
  • charts/bindery-external-runtime/: Helm chart for the standalone service.
  • verification/: Verification context fixtures.
  • adapters/: External-runtime adapter source. bindery-ra2-adapter is the Red Alert 2 adapter; bindery-dedicated-runtime and bindery-openttd-runtime are the two ERH-007 runtimes, the second of them driving an unmodified OpenTTD over its own admin protocol (make openttd-acceptance).

Shared:

  • cmd/: Binary entrypoints for both subsystems.
  • contracts/: proto/ (engine gRPC) and externalruntime/v1 (HTTP + relay).
  • docs/: Documentation — see docs/README.md.
  • config/: RBAC and manager scaffolding.
  • hack/: Verification scripts (verify-crds.sh, fetch-openttd.sh).

About

Modular, Kubernetes-native game simulation platform. Provides capability-based orchestration, reusable engine modules, and CRDs for composing scalable game worlds.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages