Skip to content

CGSP v1.1 Specification

Status: v1.1 — backward-compatible with v1.0. This page is the spine of the protocol: architecture, concepts, the surface inventory, and the versioning rules. Per-endpoint request/response detail lives in the Protocol Reference.

CGSP is the contract between Cloud1x2 (Launcher + Platform + Wallet API + Back Office, sharing the cloud1x2_platform database) and each game service. A service that satisfies this contract plugs into Cloud1x2 with no further platform code changes.

Two optional endpoints, both consistent with the data-ownership model:

  • Per-engine pause/resume (Platform → Service) — admin-triggered. The pause state lives in the service’s own database; the platform only triggers the action. The current round finishes, then the engine moves to paused. See Control Plane.
  • round-start-check (Service → Platform) — called at the start of each round; returns the suspended partner/operator list. The service disconnects players from suspended operators at round end. See Config + Ledger.

A v1.1 release also adds a per-round bet template refresh endpoint (GET /internal/bet-templates). v1.0 services keep receiving bet limits in the verify-launch response as a session-level snapshot — all three v1.1 additions are optional. Without them, LiveOps pause, round-based operator-suspend, and round-by-round limit refreshes simply do not function; the game service falls back to its session-start snapshot.

CGSP separates two worlds sharply.

flowchart LR
subgraph cloud1x2[Cloud1x2 Monolith]
Launcher
Platform[Platform Server]
Wallet[Wallet API]
Admin[Back Office]
PDB[(cloud1x2_platform DB)]
Launcher --- PDB
Platform --- PDB
Wallet --- PDB
Admin --- PDB
end
subgraph gs[Game Service]
SApp[HTTP + WebSocket server]
SDB[(service-owned DB)]
SApp --- SDB
end
Platform -->|control plane| SApp
SApp -->|config + ledger + wallet| Platform
Browser[Player Browser] -->|visits operator site| Op[Partner Operator]
Op -->|embeds Launch URL in iframe| Launcher
Browser -->|WebSocket inside iframe| SApp

There is no physical link between a service’s database and the cloud1x2_platform database — no cross-DB foreign keys, no shared schema, no shared views. Every cross-side data flow happens over HTTP. IDs that reference the other side (such as games.external_id on a ledger row) are application-level references only.

This buys independence (a service deploys, scales, and recovers on its own), stability (the platform can refactor its schema without breaking any service), and isolation (no service can reach another’s data). For the full ownership split, see Data Ownership.

Every engine has a deterministic identity, so the platform and the service converge on the same string for the same logical engine, even after a restart:

engineId = "{service_uid}:{bucketKey}"
bucketKey = "p:{runtimeProfileId}" // preferred
| "g:{gameExternalId}" // when no profile exists

For example wp9dvdgp4wfqmxq4:p:42.

  • Bucket — games that share one runtime_profile_id share one engine instance. Players on different skins of the same bucket sit in the same round.
  • Canonical game external ID — the smallest external_id in a bucket; the ID a service uses when writing the ledger for that bucket.
  • Service UID — a 16-character Crockford Base32 prefix, assigned by the platform, immutable, sent on every desired-state push, and prepended to every bet UID. The service does not invent it; it self-discovers it from the first push. See Bet UID Format.

The platform decides bucketing. The service reads the memberGames list from the desired-state payload and routes those games to one engine.

#SurfaceDirectionWho hosts itAuth header
1Control PlanePlatform → Servicethe servicex-internal-control-secret
2Config + LedgerService → Platformthe platformx-internal-config-secret (config), x-internal-wallet-secret (ledger)
3WalletService → Platform → Operatorthe platformx-internal-wallet-secret
4GameplayBrowser → Service (WebSocket)the servicelaunch verified via x-internal-verify-launch-secret

Only one HTTP surface — the control plane (/internal/engines/*) — is hosted by the service; the platform calls into it. Everything else is a platform endpoint that the service calls as a client. The round-start-check endpoint is the one exception in the engines namespace that the service calls (Service → Platform), guarded by x-internal-control-secret.

Surfaces map to reference pages as:

SurfaceReference page
Control PlaneControl Plane
Config + LedgerConfig + Ledger
Launch verificationLaunch Verification
WalletWallet API
GameplayGameplay Protocol

CGSP carries a protocolVersion field. It is currently "1.1".

Minor bump (1.0 → 1.1) — backward-compatible changes: new optional fields, new endpoints (without breaking existing ones), new event types, new optional query parameters. v1.0 services keep working; they just do not use the new features.

Major bump (1.x → 2.0) — breaking changes: removing or renaming a field, changing endpoint semantics, adding a required field, or changing auth. On a major bump the platform runs old and new versions in parallel for a transition period, and breaking changes are announced in advance.

Reserved fields — a minor bump can introduce response fields that older services should accept but not act on yet. Such fields are ignored but preserved — schema validation must not reject unknown fields.

Each side migrates its own database. The platform owns the cloud1x2_platform schema (partners, operators, games, transactions, …); the game service owns its own schema (round/bet tables). Because there are no cross-DB foreign keys, the two sides migrate independently and migration order does not matter — only the API contract must hold.

When the platform adds an optional field, older services are unaffected (they ignore it). When a service adds a field, the platform is unaffected (it never reads the service DB).