From bc8270ecc3ad29dfa6af76d42ecb4535bd24ad8e Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 12 Jul 2026 20:52:43 +0100 Subject: [PATCH] Start CultMesh and Eve getting started series --- .../getting-started/01-persist-typed-state.md | 22 +++++++ .../getting-started/02-connect-by-identity.md | 57 +++++++++++++++++++ .../03-publish-an-eve-surface.md | 49 ++++++++++++++++ .../docs/getting-started/README.md | 36 ++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 src/GameCult.Mesh/docs/getting-started/01-persist-typed-state.md create mode 100644 src/GameCult.Mesh/docs/getting-started/02-connect-by-identity.md create mode 100644 src/GameCult.Mesh/docs/getting-started/03-publish-an-eve-surface.md create mode 100644 src/GameCult.Mesh/docs/getting-started/README.md diff --git a/src/GameCult.Mesh/docs/getting-started/01-persist-typed-state.md b/src/GameCult.Mesh/docs/getting-started/01-persist-typed-state.md new file mode 100644 index 00000000..b2fce2a0 --- /dev/null +++ b/src/GameCult.Mesh/docs/getting-started/01-persist-typed-state.md @@ -0,0 +1,22 @@ +# 1. Persist Typed Application State + +Start with a typed CultCache document and a durable CultMesh node. The complete +sample is [the durable node quickstart](../durable-node-quickstart.md). + +At the end of that guide you should have: + +- a document type with a stable schema id; +- a `CultMeshNode` whose database owns the live local document; +- a `.cc`/CultCache-backed durable state path; +- a restart proof that reads the same typed document. + +Do not create an Eve-shaped copy of this state. The Eve surface published in +chapter 3 points at typed records and commands owned by the provider. + +Verification: + +```powershell +dotnet test tests/GameCult.Networking.Tests/GameCult.Networking.Tests.csproj --filter FullyQualifiedName~CultMeshNode_CanRoundTrip_DurableTypedDocument_Through_PublicDatabaseSurface +``` + +Next: [connect a client by stable identity](02-connect-by-identity.md). diff --git a/src/GameCult.Mesh/docs/getting-started/02-connect-by-identity.md b/src/GameCult.Mesh/docs/getting-started/02-connect-by-identity.md new file mode 100644 index 00000000..8dec4c63 --- /dev/null +++ b/src/GameCult.Mesh/docs/getting-started/02-connect-by-identity.md @@ -0,0 +1,57 @@ +# 2. Connect A Client By Stable Identity + +Clients address a provider or Verse by stable identity. Discovery owns the +current physical candidates and the session manager owns connection reuse, +path rotation, and transport failure state. + +```csharp +using GameCult.Mesh; + +using var discovery = new CultMeshDiscoveryService(new ICultMeshLookupSource[] +{ + odinLookupSource +}); + +using var sessions = new CultMeshSessionManager( + discovery, + new ICultMeshTransportConnector[] + { + new CultMeshSchemaTransportConnector() + }); + +var provider = CultMeshEndpointId.Parse("aetheria.daemon"); +var session = await sessions.ConnectAsync( + provider, + CultMeshProtocols.Documents, + cancellationToken); + +using var client = session.OpenSchemaClient(); +``` + +Keep `discovery` and `sessions` for the application lifetime. Do not construct +them per request. `session` is the logical connection: when Odin advertises a +new physical route after a partition, the same session migrates and retains its +typed handler registrations. + +Watch connection state for presentation and diagnostics: + +```csharp +using var stateWatch = session.WatchState().Subscribe(state => + Console.WriteLine($"{state.Status}: {state.Path?.Endpoint}")); +``` + +Application code does not reconnect, sleep, rank endpoints, or replace the +session. Those decisions belong to CultMesh. + +Verification: + +```powershell +dotnet test tests/GameCult.Mesh.Tests/GameCult.Mesh.Tests.csproj --filter FullyQualifiedName~CultMeshSessionManagerTests +``` + +The explicit organ construction above is the current low-level API. The +identity-first `mesh.ConnectAsync(...)` facade remains planned work; this guide +will collapse to that form when it lands. + +Next: [publish one Eve surface to multiple runtimes](03-publish-an-eve-surface.md). + diff --git a/src/GameCult.Mesh/docs/getting-started/03-publish-an-eve-surface.md b/src/GameCult.Mesh/docs/getting-started/03-publish-an-eve-surface.md new file mode 100644 index 00000000..666acf1d --- /dev/null +++ b/src/GameCult.Mesh/docs/getting-started/03-publish-an-eve-surface.md @@ -0,0 +1,49 @@ +# 3. Publish One Eve Surface To Multiple Runtimes + +An Eve application publishes one provider advertisement and one or more typed +surface documents through CultMesh. Browser, Unity, Electron, Flutter, and +other clients discover the same advertisement and lower only the capabilities +they support. + +The authority split is fixed: + +- provider daemon: live application state, command handling, receipts, assets; +- Eve: surface, command, binding, embedding, and plugin contracts; +- CultMesh: discovery, sessions, document delivery, and asset transfer; +- runtime: native rendering, input sampling, and platform lifecycle. + +A runtime configuration contains identity and selection constraints, not a +copy of provider behavior: + +```text +rendezvous: odin +provider: aetheria.daemon +surface kind: interactive-world +runtime capabilities: unity-scene + eve-fields +``` + +EveUnity currently expresses this through +`EveUnityCultMeshPlayableWorldProvider.Configure(...)`. Its provider discovery, +advertisement snapshot, live snapshots, and subscriptions share one managed +CultMesh document session. Other runtime lowerers must preserve the same +boundary: they may reject or report unsupported capabilities, but they may not +import provider internals. + +## Multi-Runtime Checkpoint + +Run the same provider and connect at least two lowerers. Both must report the +same provider id, surface id, surface version, and command receipt ids. Native +pixels may differ; provider truth may not. + +Current verification for the Unity consumer: + +```powershell +cd E:\Projects\EveUnity +powershell -ExecutionPolicy Bypass -File .\scripts\run-release-consumer-tests.ps1 +``` + +The browser/Electron counterpart and a single command-driven two-runtime sample +remain required before this chapter can be considered complete. Their absence +is tracked as developer-experience debt rather than papered over with bespoke +setup instructions. + diff --git a/src/GameCult.Mesh/docs/getting-started/README.md b/src/GameCult.Mesh/docs/getting-started/README.md new file mode 100644 index 00000000..ffb1094c --- /dev/null +++ b/src/GameCult.Mesh/docs/getting-started/README.md @@ -0,0 +1,36 @@ +# CultMesh And Eve Getting Started + +This series builds one typed application state and presents it through multiple +Eve runtimes. It is maintained as an API acceptance test: examples use public +APIs, name the owner of each decision, and include a verification checkpoint. + +Follow the chapters in order: + +1. [Persist typed application state](01-persist-typed-state.md) +2. [Connect a client by stable identity](02-connect-by-identity.md) +3. [Publish one Eve surface to multiple runtimes](03-publish-an-eve-surface.md) + +The intended application shape is small: + +```text +provider daemon -> typed CultCache documents -> CultMesh advertisement + | + +------------------------+--------------------+ + | | | + Eve browser EveUnity another lowerer +``` + +The provider owns live truth. Eve owns the surface contract. Each runtime owns +native projection. CultMesh owns discovery and connection continuity. + +## Maintenance Contract + +- A chapter must not tell an application to choose physical endpoints, build a + reconnect loop, or duplicate provider state. +- Code must compile against the package version named by the release that + publishes it. +- Every release changing a demonstrated API must update this series in the same + pull request. +- A setup step that depends on repository internals is an API defect, not + acceptable tutorial folklore. +