# CultLib CultLib is GameCult's shared state, transport, and runtime substrate. It started as reusable C# game infrastructure, but the useful thing now is larger: typed `.cc` persistence, schema-stable wire formats, ergonomic reliable-UDP networking, distributed database sync, simulation witness consensus, streaming surfaces, and UI/runtime affordances that can be used from C#, TypeScript, Rust, Python, and Kotlin without each runtime inventing its own local folklore. The stack is less a single product than a set of capabilities: - logging primitives and implementations - CultCache typed documents, `.cc` persistence, and SoA memory access - CultNet schema-v0 messages over TCP and LiteNetLib adapters, a bounded ASP.NET Core WebSocket host adapter, and CultLib's native cross-runtime RUDP pipe - CultMesh distributed realtime database, Verse discovery, authority leases, shard replication, and witness-authoritative simulation consensus - typed geometry domain/chunk documents for distributed CSG and LOD streaming - low-latency stream catalogs and frame-handle negotiation for media, tensors, and runtime-native buffers - Eve/CultUI daemon-published surfaces that lower into GUI, TUI, web, native, overlay, or agent-facing clients - declarative Unity UI composition and reflective runtime inspector tooling The practical pitch: a runtime can persist typed state, exchange it with peers, discover compatible schemas, join a Verse, publish observations, reconcile canonical state, and expose an operator surface without translating through a bespoke JSON bridge at every boundary. A frontend is just another CultMesh client: the daemon publishes a typed Eve/CultUI surface, and any compatible runtime can lower that surface where it needs to live. ## Entry Points - C# reference runtime: `src/` (`GameCult.Caching`, `GameCult.Networking`, `GameCult.Mesh`, `GameCult.Geometry`, `GameCult.Unity`). Build and test with `dotnet build CultLib.sln` and `dotnet test CultLib.sln`. - Other runtimes, wire-compatible with the C# CultCache: `packages/cultcache-ts`, `cultcache-py`, `cultcache-rs`, and the CultNet and CultMesh packages beside them under `packages/`; portable math in `packages/cultmath`. - Smallest working path: `src/GameCult.Mesh/docs/durable-node-quickstart.md`. Application path: `src/GameCult.Mesh/docs/getting-started/README.md` and `samples/eve-two-runtime`. ## Live And Planned Live: typed CultCache persistence, CultNet schema-v0 transports and native RUDP, CultMesh nodes with Verse discovery, shard replication and authority leases, the geometry documents, and CultUI for Unity. The browser client boundary (`packages/cultmesh-browser`, `GameCult.Networking.WebSockets`) is proven on loopback under an explicit `local-development` trust policy by `samples/eve-browser-network`. Planned: a complete public Verse proof over deployed infrastructure; the remaining gates are listed in `src/GameCult.Mesh/docs/browser-verse-transport.md`. ## Which Package Do I Want? If the job is shared game state, start here before inventing a fourth drawer and pretending the label makes it furniture. | Job | Start With | Owns | Use When | Do Not Use It For | | --- | --- | --- | --- | --- | | Local typed state | `GameCult.Caching` / CultCache | Document identity, schema compatibility, record keys, indexes, globals, and local persistence | You need a typed cache, file-compatible save data, local reactive reads, or a stable domain document model | Peer discovery, transport security, shard routing, or mesh consensus | | Portable math | `GameCult.Math` / CultMath | Shader-shaped numeric primitives, deterministic random, noise, and CPU/GPU parity helpers | Shared simulation and geometry code must not depend on an engine's math or RNG types | Domain-specific geometry, rendering, or world authority | | Procedural geometry | `GameCult.Geometry` / CultGeometry | Isosurface extraction plus CultCache-native domains, LOD requests, selected cuts, and mesh artifacts | C#, Rust, Godot, or remote workers need shared geometry algorithms and typed results | Transport policy, peer discovery, or gameplay authority | | Network transport and database plumbing | `GameCult.Networking` / CultNet | Native RUDP sessions, LiteNetLib/TCP adapters, an authenticated WebSocket host adapter, schema-v0 wire contracts, shard authority, raw document replication, snapshots, and subscriptions | You need a client/server pipe, login/session flow, schema discovery, reliable UDP, or a low-level distributed CultCache lane | Gameplay-facing mesh ergonomics, Verse policy, mod branches, or simulation consensus composition | | Distributed realtime gameplay state | `GameCult.Mesh` / CultMesh | Public mesh entrypoints, Verse discovery, peer exchange, shard replication defaults, authority leases, client prediction, and witness consensus | You want the game to treat clients and servers as one reactive database for persistent state, input state, and simulation facts | A tiny local-only tool, a bare transport client, or a storage format contract | | Realtime media/frame streams | `GameCult.Mesh` / CultMesh streaming mode | Stream identity, authority, clock metadata, body transport negotiation, frame cursors, and backpressure state | Audio/video/tensor frames need to move between runtimes through shared memory, GPU handles, platform buffers, or CultCache page refs | Durable document mutation, mesh consensus facts, or pretending inline bytes are zero-copy | | Daemon-published UI | Eve / CultUI | Typed operator and user-facing surfaces over CultMesh state | A daemon should expose controls, inspection, or workflow UI that can lower into GUI, TUI, web, native, overlay, or agent clients | One-off vendor dashboards, untyped debug panels, or runtime-local UI that cannot travel with the daemon | Quick rule: - Choose CultCache when the problem is "how do I model and persist typed state?" - Choose GameCult.Math when the problem is "which portable numeric and random semantics do these runtimes share?" - Choose GameCult.Geometry when the problem is "how do geometry workers build and share engine-neutral geometry?" - Choose CultNet when the problem is "how do peers exchange authenticated, schema-aware database messages?" - Choose CultMesh when the problem is "how does a game join a Verse and share realtime state across a mesh?" - Choose CultMesh streaming mode when the problem is "how do these runtimes move audio/video frames while the mesh owns identity, clocks, cursors, and pressure?" - Choose Eve/CultUI when the problem is "how does this daemon publish its own operable surface instead of waiting for a hosted admin console?" CultMesh sits on CultNet, and CultNet distributes CultCache documents. That is the stack. If a design needs another peer-to-peer category, first check whether it is really Verse policy, peer exchange, or shard authority wearing a fake mustache. If you want to build an application rather than tour the component drawer, start with the maintained [`CultMesh And Eve Getting Started`](src/GameCult.Mesh/docs/getting-started/README.md) series. Its first executable package-consumer checkpoint is [`samples/eve-two-runtime`](samples/eve-two-runtime/README.md). The real-process browser continuation is [`samples/eve-browser-network`](samples/eve-browser-network/README.md). One documented command runs both layers: ```powershell pwsh -File ./scripts/verify-eve-getting-started.ps1 ``` The implemented browser client boundary and remaining deployed-infrastructure gates are mapped explicitly in [`browser-verse-transport.md`](src/GameCult.Mesh/docs/browser-verse-transport.md). If you want only the smallest durable "open node -> put typed doc -> get typed doc" path, use [`src/GameCult.Mesh/docs/durable-node-quickstart.md`](src/GameCult.Mesh/docs/durable-node-quickstart.md). If you want the lower-level "typed local document -> raw wire document -> mesh/runtime watch surface" handoff, follow it with [`src/GameCult.Mesh/docs/typed-document-path.md`](src/GameCult.Mesh/docs/typed-document-path.md). ## Repository Scope The solution includes: - `GameCult.Logging`: common logging abstraction plus console and file implementations - `GameCult.Caching`: `DatabaseEntry`-based cache, indexes, global entries, and backing-store abstractions - `GameCult.Caching.MessagePack`: MessagePack-backed persistence for the cache - `GameCult.Math` / CultMath: portable numeric primitives, deterministic random, noise, and shader-parity helpers - `GameCult.Geometry` / CultGeometry: engine-neutral geometry algorithms plus CultCache-native domain, selected-cut, and mesh artifact documents - `GameCult.Networking`: encrypted login/register/verify flows, schema-v0 contracts, transport adapters, and native RUDP sessions - `GameCult.Networking.WebSockets`: bounded ASP.NET Core binary WebSocket host adapter for browser CultMesh clients - `GameCult.Mesh`: CultMesh package home for distributed realtime database, shard replication, client prediction, Verse discovery, and mesh witness consensus - `GameCult.Caching.Tests`: NUnit tests for cache and backing-store behavior - `GameCult.Networking.Tests`: NUnit tests for networking behavior - `GameCult.Unity`: CultUI, a Unity runtime UI composition framework with reflective inspector generation, prefab-backed field resolvers, reusable controls, and a demo project packaged for UPM-style consumption - `packages/cultcache-ts`: TypeScript CultCache with MessagePack persistence and inspector tooling - `packages/cultnet-ts`: TypeScript CultNet schema-v0 contracts, framing, discovery, raw document replication, and interop tests - `packages/cultmesh-ts`: TypeScript CultMesh local node and mesh catalog surface for local runtimes such as VoidBot - `packages/cultmesh-browser`: browser-safe, read-only CultMesh document leases and typed operations over an Odin-resolved WebSocket route - `packages/cultcache-py`: Python CultCache with CultCache v1 wire parity - `packages/cultnet-py`: Python CultNet contracts, framing, RUDP transport, replication, and interop peer - `packages/cultmesh-py`: Python CultMesh local node, discovery, sessions, local server, and daemon - `packages/cultcache-rs`: Rust CultCache and derive macro - `packages/cultnet-rs`: Rust CultNet contracts, framing, discovery, and interop peer - `packages/cultmesh-kotlin`: Kotlin/JVM CultMesh and CultNet surface for Android-adjacent runtimes ## Repository Layout ```text package.json src/ GameCult.Logging/ GameCult.Caching/ GameCult.Caching.MessagePack/ GameCult.Geometry/ GameCult.Networking/ GameCult.Networking.WebSockets/ GameCult.Mesh/ GameCult.Unity/ tests/ GameCult.Caching.Tests/ GameCult.Geometry.Tests/ GameCult.Networking.Tests/ packages/ cultmath/ cultcache-ts/ cultnet-ts/ cultmesh-ts/ cultmesh-browser/ cultmesh-kotlin/ cultcache-py/ cultnet-py/ cultmesh-py/ cultcache-rs/ cultnet-rs/ ``` ## Build ```powershell dotnet build CultLib.sln ``` ## Test ```powershell dotnet test CultLib.sln ``` TypeScript package tests: ```powershell npm test --workspace packages/cultcache-ts npm test --workspace packages/cultnet-ts npm run test:interop --workspace packages/cultnet-ts npm test --workspace packages/cultmesh-ts npm test --workspace packages/cultmesh-browser ``` Measured reactive, retained-session, and shared-memory hot-body gates: ```powershell pwsh -File ./scripts/measure-reactive-document-performance.ps1 -Quick pwsh -File ./scripts/verify-eve-getting-started.ps1 ``` The first command measures the same 16 KiB document workload in C#, TypeScript, and Python and includes a mapped hot-body probe with explicit copy telemetry on Windows named maps and Unix file-backed maps. The second includes 10,000 real WebSocket operations on one retained identity-owned C# session after provider route replacement. Rust package tests: ```powershell cargo test --manifest-path packages/cultcache-rs/Cargo.toml cargo test --manifest-path packages/cultnet-rs/Cargo.toml ``` Kotlin package build: ```powershell .\packages\cultmesh-kotlin\build.ps1 ``` ## Common Concepts ### `DatabaseEntry` The cache-centric libraries revolve around `DatabaseEntry`. Every entry has a stable `Guid` identifier and can optionally: - expose a human-readable name through `INamedEntry` - participate in generic indexes registered at runtime - be treated as a global singleton entry through `GlobalSettingsAttribute` Typical entry shape: ```csharp using GameCult.Caching; public class ItemData : DatabaseEntry, INamedEntry { public string Name = string.Empty; public int Value; public string EntryName { get => Name; set => Name = value; } } ``` ### `CultCache` and Backing Stores `CultCache` is an in-memory index over `DatabaseEntry` objects. It can operate entirely in memory, or it can be attached to one or more backing stores for persistence and synchronization. - the cache is the query surface - backing stores are persistence adapters - indexes and name maps are maintained inside the cache, not inside the store ### Multiple Backing Stores Every document type has exactly one home store. There are no mirrors. ```csharp cache.AddBackingStore(catalogStore, typeof(ItemData), typeof(Faction)); cache.AddBackingStore(runStore, typeof(SavedGame)); ``` - the home is chosen by the document's runtime type: the most derived routed type wins, otherwise the untyped store - at most one untyped store; a type claimed by two stores is an error - a write with no home is an error once any store is attached - attaching a store reads it; attach routed stores first and the untyped store (if any) last, because a record's home cannot move after it is loaded - loading never writes: opening and flushing without a mutation leaves every file byte-identical - a read-only store refuses writes and is skipped by flush The contract is `src/GameCult.Caching/Contracts/cultcache-store-composition.md`. Until the C# cache implements it, `AddBackingStore` takes no home types and every attached store receives every record; attach one store per cache. ## Example: Cache + Networking ```csharp using GameCult.Caching; using GameCult.Logging; using GameCult.Networking; var cache = new CultCache { Logger = new ConsoleLogger() }; var server = new Server(cache) { Logger = new ConsoleLogger() }; server.Start(); ``` ## Secrets and Runtime Configuration `GameCult.Networking` uses two pieces of deployment configuration: - `GAMECULT_CONNECTION_KEY` - `GAMECULT_SESSION_SIGNING_SECRET` Production guidance: - set both values before starting the server - treat `GAMECULT_CONNECTION_KEY` as shared client/server protocol configuration - treat `GAMECULT_SESSION_SIGNING_SECRET` as a server-only secret - generate high-entropy random values and store the server-side value in your platform's secret store - do not rely on local-development defaults in production - partial configuration is rejected at startup Recommended value format: - at least 32 random bytes per value - encode as Base64 or Base64Url if you want a portable text representation Example secret generation in PowerShell: ```powershell [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 })) ``` Typical production setup patterns: - inject `GAMECULT_SESSION_SIGNING_SECRET` and the server copy of `GAMECULT_CONNECTION_KEY` as environment variables from Docker secrets, Kubernetes secrets, systemd environment files, or your cloud secret manager - ship the matching `GAMECULT_CONNECTION_KEY` to the client through a build-generated config asset, code-generated constants, or another explicit client configuration mechanism - scope them per environment so development, staging, and production do not share values - rotate `GAMECULT_SESSION_SIGNING_SECRET` operationally - treat `GAMECULT_CONNECTION_KEY` as versioned protocol config; changing it requires a coordinated client/server rollout Example server startup with strict environment validation: ```csharp using GameCult.Caching; using GameCult.Networking; var cache = new CultCache(); var security = ServerSecurityOptions.FromEnvironment(); var server = new Server(cache, security); ``` Example local-development server startup: ```csharp using GameCult.Caching; using GameCult.Networking; var cache = new CultCache(); var security = ServerSecurityOptions.Development(); var server = new Server(cache, security); ``` Example shipped-client startup with explicit client configuration: ```csharp using GameCult.Networking; var security = new ClientSecurityOptions(""); var client = new Client(security); ``` ## Project Docs Each subproject has a local README with package-specific detail: - [GameCult.Logging](src/GameCult.Logging/README.md) - [GameCult.Caching](src/GameCult.Caching/README.md) - [GameCult.Caching.MessagePack](src/GameCult.Caching.MessagePack/README.md) - [GameCult.Geometry](src/GameCult.Geometry/README.md) - [GameCult.Networking](src/GameCult.Networking/README.md) - [GameCult.Mesh](src/GameCult.Mesh/README.md) - [Durable Node Quickstart](src/GameCult.Mesh/docs/durable-node-quickstart.md) - [Typed Document Path](src/GameCult.Mesh/docs/typed-document-path.md) - [GameCult.Unity](src/GameCult.Unity/README.md) - [GameCult.Caching.Tests](tests/GameCult.Caching.Tests/README.md) - [GameCult.Networking.Tests](tests/GameCult.Networking.Tests/README.md)