Every seam, by category
Crossplay runs the universal machinery and calls out to your game wherever a decision is genuinely yours. These are every one of those call-outs, across all 106 pieces.
You implement it and it changes a game rule. Crossplay ships an inert or permissive default, so register yours before the piece's AddCrossplay* call and it wins.
You swap it and it changes infrastructure, never a rule — where data lives, what time it is, how bytes move. Crossplay ships a working implementation of each.
The client-side sockets. Bind your implementation in the client context: models, animators, UI and controls are always 100% your game's.
Core
The always-on kernel.
The always-on kernel: connect, login, sessions, rooms/groups, and the messaging SDK.
-
IAccountCharacterSourcegame SPIWhere an account's character ids come from.
-
IAccountDataParticipantgame SPIGDPR seam: one participant per data domain.
-
IAccountDirectoryproviderResolves online players by ACCOUNT id — the account-keyed sibling of IOnlineDirectory (which resolves by display name).
-
IAccountDisplayNamesgame SPIA display name for an account, online or not - a name the player CHOSE, separate from the login username.
-
IAccountPresenceListenergame SPIAccount-level presence hooks: told when an account SIGNS IN (its first live session on this node is logged in or resumed - after the login/resume reply went out, so anything you…
-
IAccountStoreproviderAccount persistence.
-
IActingEntityResolvergame SPIAnswers "which entity is this session acting AS" — the one question every piece that resolves an actor has to ask, at the one layer every piece is allowed to ask it.
-
IAnomalySinkgame SPIWhere anomaly flags go.
-
IAuditSinkproviderA durable destination for audit entries (so the trail survives a restart).
-
IBanStoreproviderPersists account bans.
-
IClusterBusproviderCross-node message bus — publish/subscribe of opaque bytes on named channels.
-
IClusterInboxproviderA hand-off queue from background bus threads to the server poll thread.
-
IClusterSessionControlproviderCross-node SESSION CONTROL — the act-on sibling of the account directory's remote proxies.
-
IConnectionproviderA single transport-level connection (one peer).
-
IDistributedLockproviderCross-node mutual exclusion for the rare operations that must not run twice concurrently anywhere in the cluster (cross-node matchmaking sweeps, market settlement, scheduled jobs).
-
IEmailSenderproviderOutbound email delivery — the game/ops plug in SMTP/SES/SendGrid; the framework never speaks a mail protocol itself.
-
IExternalIdentityValidatorproviderPlatform ticket validation — the game plugs Steam/Google/Apple (usually an HTTPS call to the platform; it runs on the auth work queue, never the poll thread).
-
IFleetLifecyclegame SPIThe provider-neutral lifecycle contract between this node and the fleet orchestrator that HOSTS it (PlayFab Multiplayer Servers, Amazon GameLift Servers, an Agones sidecar).
-
IFrameCipherproviderAuthenticated encryption for ONE framed message, independent of which transport carries it.
-
IHealthCheckgame SPIA readiness check for one subsystem (e.g. the persistence backend or the transport).
-
IIdentityLinkStoreproviderThe external-identity ↔ account link table: a proven platform identity (provider + externalId) maps to the account it was attached to.
-
IMessageHandlerRegistrargame SPIImplemented by any package/piece that contributes message handlers.
-
IMessageTrafficStatsproviderPer-message-id byte and frame accounting: the breakdown behind the aggregate BytesReceived, so a bandwidth claim can name the id it changed.
-
IMetricsTextSourcegame SPIA pluggable extra section for the /metrics endpoint.
-
IOutboundShaperproviderDecides whether an outbound frame to a connection may go out under that connection's bandwidth budget.
-
IPasswordHasherproviderHashes and verifies passwords using a salted, slow KDF.
-
IReplyFlagsgame SPI"Something new for you" bits piggybacked on the next reply a session gets - new mail, a new battle report, a cache to flush - so a game never needs a separate poll for them.
-
IRequestGategame SPIDecides, before its handler runs, whether a typed request (one registered with RegisterRequest``2) may proceed.
-
IRequiredVersionProvidergame SPISupplies the client version the server requires RIGHT NOW, read once per login/register attempt — so the gate can be moved without redeploying a node, and so a rejected client c…
-
IRestResourcegame SPIOne read-only JSON resource on the companion-app gateway: GET /api/{name}?args → Get.
-
IResumeTokenStoreproviderTracks issued reconnect tokens so a later ResumeSession can be validated.
-
IServerActivationgame SPIWhether this process is doing the job it was started for yet, or merely STANDING BY waiting to be given one.
-
IServerClockproviderA monotonic millisecond clock.
-
IServerInfoProvidergame SPIBuilds the ServerInfo advertised to clients on connect.
-
IServerMetricsproviderA pluggable telemetry sink.
-
IServerPollablegame SPIIncremental per-poll work hook: Poll calls Pump every cycle — a high-frequency, event-driven cadence (typically thousands of times per second under load, and at least the host's…
-
IServerTickablegame SPIImplemented by pieces that need periodic server work decoupled from the inbound-message poll — e.g. the Movement piece batches its observer broadcast into a fixed-rate tick (ser…
-
IServerTransportproviderA server transport.
-
ISessionLifecycleListenergame SPIImplemented by pieces that need per-connection lifecycle hooks — e.g.
-
ISessionTokenFactoryproviderCreates opaque, unguessable session tokens used for reconnect.
-
IStandbyTickablegame SPIAn IServerTickable that must keep ticking while the process is in fleet STANDBY — i.e. work that is about staying alive rather than about running a game.
-
ITickRateExpectationgame SPIDeclared by a piece that simulates on a fixed step and therefore has a tick rate it was tuned for — e.g.
-
ITransportSignalproviderOptional low-latency extension of IServerTransport.
-
IAuthProviderunity SPISPI: a source of platform login tickets.
-
IClientMessageTrafficunity SPIPer-message-id wire counters for the client connection — the breakdown behind IConnectionStats, so "which message is the bandwidth" has an answer on this tier too.
-
IClientTransportunity SPIThe client's wire seam — the mirror of the server's IServerTransport.
-
IClientTransportOverrideunity SPILets a piece decide, for the NEXT dial, how the connection reaches the server — instead of the wire selected by Transport.
-
IConnectionStatsunity SPICumulative wire counters for the client connection — the raw feed for diagnostics overlays (rates are computed by the consumer over its own window).
-
IRawMessageDispatcherunity SPIAn OPTIONAL extra on a dispatcher: deliver a message's raw payload — the frame's bytes after the id header — instead of a decoded instance.
-
IServerClockDiagnosticsunity SPIRead-only visibility into how the clock estimate is moving (GAP-16).
-
IServerClockSamplerunity SPIWrite side of the clock — the heartbeat feeds one sample per pong.
-
IServerConnectionunity SPIClient half of the transport: a single UDP link to the Crossplay server.
Genre-agnostic authored-content store: define content types + records (entities, items, levels, classes, quests, anything) over a metaschema — every domain type is DATA, not code. Saved in the DB, served to clients on demand (manifest -> lazy fetch -> live push), asset-load-path binding. A must for Core — auto-installed, cannot be unselected.
-
IContentAssetStoreproviderPersistence seam for authored content ASSETS — keyed + versioned binary blobs (images/icons/audio).
-
IContentStoreproviderPersistence seam for authored content.
-
IContentAssetBinderunity SPIThe game-implemented seam that turns a content record's opaque asset-path field into a real Unity asset.
Spatial
Worlds, entities & movement.
Create / select / roster of characters with an opaque appearance blob (ICharacterFactory SPI).
-
ICharacterNamePolicyproviderThe game's name rule beyond the universal length gate (donor-gap E3): reserved names, charsets, profanity filters, impersonation guards — all the game's vocabulary.
-
ICharacterPolicygame SPI5.3: the game's precondition gate on character CREATE and SELECT — beyond the built-in checks (length, name policy, roster limit, name uniqueness, ownership).
-
ICharacterStoreproviderCharacter persistence SPI — the seam a game implements to store its roster durably.
-
ICharacterAppearanceClientunity SPIReplaces an owned character's opaque appearance blob after creation — a garage repaint, a wardrobe change, a pick-your-look screen.
-
ICharacterFactoryunity SPISPI the game implements to turn an opaque appearance blob into a visible avatar.
Enter-world, spawn/despawn, spatial interest, zones/instancing, server entities, bounds, pathfinding (A*), and spatial enter/exit/dwell trigger volumes.
-
IBoundsAreagame SPIA playable area on the XZ plane — the abstract "shape of the map" both tiers evaluate with the SAME code (this assembly ships to the server and, as the embedded contracts DLL, t…
-
IBoundsVolumegame SPIA 3D playable/collision volume — the volumetric sibling of the 2D IBoundsArea, evaluated with the SAME code on both tiers (this assembly ships to the server and, as the embedded…
-
IBroadcastCullingPolicygame SPINetwork-LOD seam: decides, per subject→observer pair, how often that observer receives the subject's EntityMove.
-
IEntityBoundsgame SPIOptional SPI: a PER-ENTITY playable area, tighter than the zone's.
-
IEntityObstaclesgame SPIOptional SPI: the OTHER entities a mover may not step into — a parked cart, a crate, a beast standing still — as an IBoundsArea resolved on the mover's swept step, after the zon…
-
IEntityRegionAnchorgame SPIOptional companion to IEntityBounds: where INSIDE its own region an entity belongs.
-
IEntityTerritorygame SPIOptional companion to IEntityBounds: what an entity DEFENDS, as opposed to where it may move.
-
IInstanceSpawnPolicygame SPIOptional per-arrival spawn placement into an instanced zone — the seam the composition-layer Zone instance realizer consults so a SPATIAL game gets scatter (or any per-player la…
-
IInterestVisibilityPolicygame SPIThe game's "may this observer KNOW this subject exists" rule — fog of war, spotting systems, bush/stealth mechanics, GM invisibility.
-
IPositionStoreproviderPersists a character's last zone + world position, so a player resumes where they logged out (see RestoreSavedPosition).
-
ISightBoundsgame SPISPI for things that block SIGHT but are not in the static bake: a shut door, a dropped barricade, a destructible wall, a smoke cloud.
-
ISpatialIndexprovider2D spatial index over the XZ plane for interest queries — the swappable strategy behind the interest system (one index per zone).
-
ISpatialIndexFactoryproviderCreates one spatial index per zone/instance (each zone is its own interest space).
-
ITriggerListenergame SPISPI the game implements to give volumes meaning — the plug-in point of this piece.
-
IWorldBoundsgame SPISPI the game implements to give zones a playable-area shape ("drop a map, it has bounds"): return an IBoundsArea (box, circle, grid mask, or the game's own shape) per zone, or n…
-
IWorldGeometrygame SPISPI the game implements to give a zone its 3D collision volumes — the volumetric sibling of IWorldBounds ("drop a map, it has walls, floors and kill zones").
-
IWorldGeometryProviderproviderThe swappable back-end that actually answers 3D geometry queries for a zone — the seam (RULE 13) that lets the fidelity scale without changing callers.
-
IWorldSurfaceMapgame SPISPI the game implements (or the baked default answers) to give zones a per-cell SURFACE plane — the bounds grid-mask's opaque sibling.
-
IZoneAdmissionPolicygame SPIThe game's "may THIS session enter THAT zone" rule — per-party instances, personal housing, solo trials, who may spectate which match.
-
IZoneDirectoryproviderWho owns which zone — the seam that turns zone-per-node scale-out from static config into a live cluster directory.
-
IZoneSpawnSlotsgame SPIThe claim book over ZoneSpawnSlots: hands each entrant its OWN authored placement out of a zone's ordered slot list, and takes it back when that entrant leaves.
-
IClientEntityBoundsunity SPISPI the game implements to give the CLIENT the same PER-ENTITY areas it registered on the server (IEntityBounds) — the client mirror of IClientWorldBounds, which mirrors the zon…
-
IClientWorldBoundsunity SPISPI the game implements to give the CLIENT the same per-zone playable areas it registered on the server (IWorldBounds) — the shared BoundsResolver then makes local prediction sl…
-
IClientWorldGeometryunity SPISPI the game implements to give the CLIENT the same 3D collision volumes it registered on the server (IWorldGeometry) — the volumetric sibling of IClientWorldBounds.
-
ITerrainHeightProviderunity SPISPI the game implements to ground remote replicas: the server is authoritative over X/Z but does not simulate Y, so the client samples the terrain height for spawns and moving e…
-
IWorldEntitiesunity SPIRead model over the entities the client currently knows about (self + observed remotes).
-
IZoneMoveNoticesunity SPIThe server's advance notice of a zone move it is about to make (opt-in server side: Crossplay:World:AnnounceZoneMoves).
Server-authoritative movement: input, 20Hz broadcast, prediction/reconciliation, interpolation.
-
IControlResolvergame SPIPossession seam: decides which entity a session's movement input drives.
-
ILocomotionResolvergame SPILocomotion seam: which state id is THIS entity in right now?
-
IMovementGategame SPIMobility seam: may this entity move right now?
-
IMovementSpeedProvidergame SPIPer-entity move-speed seam: how fast may THIS entity move right now?
-
IMovementDiagnosticsunity SPILive movement-quality numbers for diagnostics overlays — how far behind the render timeline sits, and how wrong the last prediction was.
Client-side distance tiers over entity views: full detail near, animator pose-write culling in the mid ring, deactivation beyond. Whatever the game spawns gets culled and the layer never knows what the objects are. No server half and no wire — usable on its own, including by a client that only moves a camera.
-
ICullingClientunity SPIThe client culling layer: assigns every world entity view a distance tier from the local player and (by default) applies the built-in actions — full detail near, animator pose-w…
-
ICullingOriginunity SPIOPTIONAL seam: where the culling layer measures distance FROM.
Relays opaque game-encoded audio frames by voice channel, or by proximity when World is installed; the framework never decodes — codec + playback are the game's.
-
IVoiceChannelPolicygame SPIDecides whether a session may JOIN a voice channel, and whether it may SPEAK on one.
-
IVoiceFrameObservergame SPIWatches the audio frames the server accepts, without changing where they go.
-
IVoiceProximityAudiencegame SPIResolves WHO hears a proximity (Channel 0) voice frame — the listeners "near" the speaker.
-
IVoiceChannelAssignmentsunity SPIChannels the SERVER assigns (a lobby room, a team): which one you are on and who speaks on it.
"Player used entity X": a validated verb pipeline; the game's policy SPI decides meaning.
-
IInteractionPolicygame SPIThe game's interaction rules — THE plug-in point of this piece.
One entity rides another: a rider's pose is derived from its carrier at a fixed offset in the carrier's own frame. Passengers in a vehicle, a patient on a stretcher, cargo in a hold, a player on a moving platform, a turret on a tank — the framework never knows which. The wire carries ONE reliable message per ride (replayed on interest reveal), not a pose per tick: a rider costs nothing while it rides and cannot drift against the thing carrying it. Server-decided and therefore unforgeable — there is no client verb.
-
IAttachmentsClientunity SPIThe Attachments piece, client side: an entity told to ride another has its view driven from the carrier's, every frame, at the offset the server sent.
Optimized networked transform sync for non-player physics bodies (crates/vehicles/debris/doors): quantized position + smallest-three quaternion + velocity, sleep-gated, interest-culled, batched. The game runs its own physics; this only syncs the result.
-
IPhysicsBackendproviderOPTIONAL engine seam: a server-authoritative physics engine that RigidBodies drives.
-
IPhysicsBodyFactorygame SPIOPTIONAL creation sibling of IPhysicsBackend: an engine that can build a body from an engine-neutral PhysicsShape.
-
IPhysicsBodyPlacementgame SPIOPTIONAL placement sibling of IPhysicsBodyFactory: putting an EXISTING body back somewhere, stopped.
-
IPhysicsBodyProfilesgame SPIDecides WHICH physical profile a given entity is — the game's answer to "what kind of thing is this".
-
IPhysicsBodySleepgame SPIPHYS-28 — putting a settled body's constraint island to sleep, and asking whether it already is.
-
IPhysicsForcesgame SPIOPTIONAL force sibling of IPhysicsBodyFactory: an engine that can be told to PUSH something.
-
IPhysicsImpactSinkgame SPIWhere collisions go — the PUSH counterpart to IPhysicsBackend's pull surface, and the difference between physics that is scenery and physics that is gameplay.
-
IPhysicsJointBreakSinkgame SPIWhere breaks go.
-
IPhysicsJointReleasegame SPIOPTIONAL release sibling of IPhysicsJoints: let go of everything holding ONE body.
-
IPhysicsJointStrengthgame SPIOPTIONAL strength sibling of IPhysicsJoints: changing what an EXISTING joint can carry.
-
IPhysicsJointsgame SPIOPTIONAL joint sibling of IPhysicsBodyFactory: an engine that can hold two bodies together, and let go when pulled hard enough.
-
IPhysicsLevelGeometrygame SPIGives a physics backend the LEVEL — the static collision a zone is actually made of.
-
IPhysicsQueryBackendgame SPIOPTIONAL query sibling of IPhysicsBackend: a physics engine that can also answer spatial queries (raycast / swept sphere) against its world.
-
IPhysicsShapeLibrarygame SPIWhere a server gets the shapes a game authored — the last link in "a model in Unity becomes a collision volume on the server".
-
IRigidBodyInputSinkgame SPIWhere a validated input frame goes — the game's half of client-predicted rigid bodies.
-
IStructureCataloggame SPIPHYS-21 — the live connection graph of a built structure, and what it implies.
-
IStructureDetachgame SPIPHYS-29 — taking a piece OFF a kinematically-held structure: the donor engine's FracturedChunk.DetachFromObject().
-
IStructureGraphgame SPIPHYS-29 — walking and CUTTING the structure graph, for the kinematically-held mode.
-
IStructureIntegritygame SPI -
IStructureLibrarygame SPIWhere a server gets the STRUCTURES a game authored — the last link in "an artist's wall becomes a building the server holds up and can knock down".
-
IStructuresgame SPIPHYS-20 — every structure currently standing, and what is left of each.
-
INeighbourAwareRigidBodyIntegratorunity SPIAn integrator that can also see the bodies near the one it is stepping (GAP-28) — so a predicted body stops being alone in the universe.
-
IRigidBodyBatchViewunity SPILB-GAP-16 — the presentation seam for MANY rigid bodies at once: every tracked body's render pose, handed over in one call per frame instead of one call per body.
-
IRigidBodyCollisionShapesunity SPIWhat a networked body is SHAPED like, for the client's own collision — PHYS-14's one game-facing seam.
-
IRigidBodyIntegratorunity SPIThe game's local-physics seam for bodies THIS client owns and predicts (Pattern B, PhysicsNetMode.ClientPredicted).
-
IRigidBodyViewunity SPIThe presentation seam for ONE rigid body — the game binds an entity id to its own Rigidbody/Transform (or a 2D body, or a text row: the piece cannot tell).
-
IRigidBodyViewFactoryunity SPIThe game's factory that resolves an entity id to its IRigidBodyView — the rigid-body analogue of ICharacterFactory.
Generic client-authoritative avatar relay (Route B): the owning client simulates its avatar with its OWN controller and reports a full-3D pose (Vec3 + smallest-three quaternion + quantized velocity) plus an opaque game-state blob; the server validates (rate + gross-delta + optional IAvatarMoveValidator) and relays to observers with interpolation. Any bespoke-controller game (platformer/racer/ragdoll) gets multiplayer with near-zero netcode — it implements only IAvatarStateSource + IAvatarStateApplier and never defines a message or an id.
-
IAvatarMoveValidatorgame SPIOptional game seam for DEEP validation of a client-authoritative avatar report.
-
IMotorRelayAuthoritygame SPIOptional game seam that decides which client may drive which server-spawned entity.
-
IMotorSimulationgame SPIThe ENTIRE per-game surface for server-authoritative motion: a pure, deterministic step the framework runs on BOTH tiers (server = authority, client = prediction).
-
IAvatarStateApplierunity SPIOBSERVER-side game seam — the entire per-game surface for rendering a remote avatar.
-
IAvatarStateSourceunity SPIOWNER-side game seam — the entire per-game surface for reporting the local avatar.
-
IMotorClientunity SPIPublic facade / diagnostics seam for the Motor client loop.
-
IMotorDiagnosticsunity SPIWhat the Motor client can tell you about remote playback quality, so "is the jitter fixed?" is a number rather than an impression.
-
IMotorInputSourceunity SPIOWNER-side game seam for ServerAuth mode — the game's INPUT (not a pose).
-
IMotorPlacementHandlerunity SPIThe game's hook for "you are now here" — PHYS-10's client half.
-
IRelayedAvatarStateSourceunity SPIHOST-side game seam — report poses for entities this client does not own.
Authored static level objects with server-authoritative state — pickups, crates, chests, levers, doors, checkpoints, moving platforms, goals. A designer places them as CONTENT (the piece defines its own content types, so the editors show a ready-made form) and the piece owns spawning, stable ids, the 3D reach test, the state blob and its replay on interest reveal. Five built-in rules cover the recurring shapes — claim-once, durability, counter, flag, clock-epoch — with an ILevelObjectRule SPI for anything novel; which verb acts on which kind is authored, not coded. Zero new wire: spawns ride World, state rides EntityState, verbs ride Interactions.
-
ILevelObjectChannelsproviderWhether a named channel is ON in a zone — the question a kind's RequiresChannel asks before a player may use it (a lock that needs power, a TV that needs the mains, a tap that n…
-
ILevelObjectHarmPolicyproviderOptional gate + feedback for the one archetype that is genuinely COMBAT: Durability.
-
ILevelObjectResetPolicygame SPIWHO may reset a zone's authored objects over the wire (GAP-35's LevelObjectResetRequest) — the game's rule, because the framework cannot know what a "run", a "match" or a "lobby…
-
ILevelObjectRulegame SPISPI for an object rule the five built-in archetypes cannot express — the escape hatch, not the normal path.
-
ILevelObjectTableproviderWhere the authored level-object table comes from.
-
ILevelObjectBinderunity SPIThe game seam for authored level objects — where presentation begins and this piece ends.
3D collision/query fidelity: baked triangle-mesh geometry (slopes/loops/ledges) answering raycast / sphere+capsule sweep / ground-probe via World's IWorldQueries3D, alongside the analytic volumes. Ships as content (.mesh3d, CBK envelope) — zero wire. The client package carries the mesh->.mesh3d editor BAKER, the shared collision math, and a RUNTIME mirror (IClientMeshGeometry) that preloads the same bakes by Addressables label so prediction asks the identical triangles authority does — which is what lets a client predict a vehicle's height and slope per frame instead of receiving them at the ack rate.
-
IWorldMeshGeometrygame SPISPI the game (or the file loader) implements to give a zone its baked collision TriangleMesh — the mesh analogue of IWorldGeometry/IWorldBounds.
Deterministic segment bodies: a body travels in straight legs and deflects off game-supplied surfaces by a configured rule set (hit-offset steer, capped surface-motion transfer, speed gain with a floor and a ceiling). The wire carries one leg per CONTACT, not a pose per tick, and both tiers evaluate the same line against the shared clock — so there is no interpolation delay and nothing to smooth at a bounce. For pong and its family, air hockey, breakout, arcade football.
-
IKinematicSurfacesgame SPIThe game's answer to "what can this body bounce off right now?" — the piece's one required SPI.
Shared spatial cell grid: per-zone chunked opaque cells (terrain edits, tiles, build pieces), streamed to each player's chunk window and delta-batched on change. Seed + persistence SPIs; server-set only.
-
IWorldGridSeedgame SPIThe procedural-generation seam: fills a chunk's cells the FIRST time it is touched (no stored copy existed).
-
IWorldGridStoreproviderPersistence seam for chunk payloads — one record per (zone, chunkX, chunkZ).
Population spawners over server entities: keep N alive in an area, respawn on removal. Server-only.
-
ISpawnPlacementPolicygame SPIThe GAME's say over WHERE a spawn lands: the spawner offers each candidate point before it spawns anything, and the policy accepts it as-is, moves it (write the new coordinates…
Dropped-item entities: opaque payload, atomic first-claim, timed expiry. Server-only.
-
ILootClaimPolicygame SPISPI the game implements to gate claims — consulted BEFORE the atomic take in both the manual claimer-aware TryClaim path and the AutoClaimRadius auto-claim pass.
NPC behavior drivers: wander/patrol/chase built-ins + an IAgentBehavior game SPI. Server-only.
-
IAgentAttackHandlergame SPIThe attack seam this piece OWNS: a behavior decides WHEN to attack (range, cooldown); this seam decides WHAT an attack does — spawn a projectile, apply a stat change, start a di…
-
IAgentBehaviorgame SPIOne NPC brain — the SPI to implement for custom AI.
-
IAgentFixedKindAttackFactorygame SPIThe narrower sibling of IAgentAttackHandler: what a brain template that PINS one attack kind (AttackProjectileKind) attacks WITH.
Instanced-zone lifecycle: create/seed via IDungeonContent, complete/reset, abandon sweep. Server-only.
-
IDungeonContentgame SPIThe game's dungeon content — THE SPI to implement for the Dungeons piece.
A rideable STATE on an entity: mount id + opaque look blob + speed multiplier (applied through Movement's speed seam via a Hosting bridge). Horses, hoverboards, sprint stances, transformation forms — same state machine, the game's render. Ownership/eligibility = IMountPolicy; broadcast on change + replayed on interest reveal; empty catalog = inert.
-
IMountPolicyproviderThe game's mount rule: may THIS player ride THIS mount now?
Bind/recall points, a warp destination table, and death→respawn location resolution through an ORDERED strategy chain (bind → nearest zone point → your own IRespawnStrategy). WHEN travel is allowed is the game's policy SPIs (the default DENIES client respawns until one is composed — the Stats-depletion bridge supplies the classic 'dead may go home'); moves ride the ITravelMover seam (Movement's prediction-aware Teleport when composed).
-
IBindPointStoreproviderStorage seam for per-player bind points.
-
IBindPolicyproviderThe game's bind rule: may THIS player bind HERE, now?
-
IRespawnPolicyproviderThe game's respawn gate: WHEN may this player respawn?
-
IRespawnStrategygame SPIOne link of the respawn WHERE chain.
-
ITravelMoverproviderHOW an entity actually moves — the seam that keeps Travel off the Movement piece (a sibling, never a reference).
-
IWarpPolicyproviderThe game's warp rule: may THIS player take THIS destination now?
Generic entity-vs-entity contact: circle / yaw-oriented-box footprints, layer bits + mask, weight-split push-out. Hard corrections ride the swept movement pipeline (never through walls); predicted avatars push via the ISoftContactResolver seam. Zero wire — positions ride the existing movement broadcast. Server-only.
-
IContactDisplacementResolvergame SPIWhere a swept REWIND goes — the seam GAP-19 needs for an entity whose position is owned by a simulation rather than by the world.
-
IContactImpulseResolvergame SPIWhere an IMPULSE goes — the seam for Impulse, and the counterpart to ISoftContactResolver's positional push.
-
IContactPairFiltergame SPIOptional seam: a veto on which entity PAIRS the piece checks at all — asked once per candidate pair per tick, after the layer/mask filter and before any geometry.
-
ISoftContactResolvergame SPIThe Soft-correction seam this piece OWNS: how a contact push reaches an entity the server must NOT silently reposition — an input-driven predicted avatar, where a server-side po…
Server-authoritative heading+speed vehicle motion (cars/karts/boats/hover/tanks): sampled steer/drive/drift axes in through one validated path (wire AND AI), substepped shared-integrator sim over baked per-class LUT tables, swept through the world bounds every substep (no wall tunneling), full-state owner ack for client prediction. Wall + vehicle-vs-vehicle contact events (car-vs-car via the config-gated Contact bridge); per-entity multiplier SPI (nitro / upgrades). Drivable from CONFIG ALONE: AutoRegister says which entities entering which zone become vehicles of which class, and SurfaceHandling maps the world's baked per-cell surface ids to handling multipliers (surface 0 and unmapped ids stay neutral) — no server code required for either. Motion rides the Movement broadcast; requires the Movement piece composed. The client package predicts the local vehicle through the same shared integrator and reconciles on the owner ack.
-
IVehicleDrivergame SPIServer-side DRIVER seam — the other half of SetInput, which until now had exactly one caller (the client wire handler).
-
IVehicleParamsProvidergame SPIPer-entity handling overlay seam — the vehicle twin of Movement's IMovementSpeedProvider: each substep the integrator asks it for THIS vehicle's multiplier set (VehicleParams: m…
-
IVehicleClassTableProviderunity SPISPI the game implements to give the CLIENT the same per-class integrator tuning the server's Crossplay:Vehicles:Classes:{id} config carries — the vehicles twin of IClientWorldBo…
-
IVehicleClientParamsProviderunity SPISPI the game implements to mirror the server's per-entity IVehicleParamsProvider overlay (surface grip, nitro, upgrade tiers) for the LOCAL vehicle, so prediction applies the sa…
-
IVehicleGameplayInputunity SPISPI the game implements to feed vehicle intent from any input source (new Input System, AI, replay, a rhythm chart, …) — the vehicle twin of the movement piece's IGameplayInput.
-
IVehiclesClientunity SPIThe vehicles piece's client surface: the game tells it when the local player starts/stops driving (the server registered its entity as a vehicle through the game's own flow — an…
Combat
Stats, abilities & effects.
Opaque verbs with server-tracked cooldowns and an IAbilityRules SPI.
-
IAbilityBookPolicyproviderThe game's learning rule (donor-gap E4): may THIS player learn (or rank up) THIS ability now, and at what cost?
-
IAbilityBookStoreproviderStorage seam for the per-player book.
-
IAbilityGategame SPIActor seam: may this entity use abilities right now?
-
IAbilityRulesgame SPISPI the game implements to give abilities their meaning — hit detection, damage, combos, ammo.
Kinematic projectile entities with deterministic client rendering + click-frame prediction: one launch event per volley, no interpolation buffer.
-
IProjectileBlockersgame SPIThings that stop a round but are not in any bake: closed doors, shields, destructible cover — whatever a game opens, closes, raises or breaks at runtime.
-
IProjectileRulesgame SPISPI the game implements to give projectiles their meaning.
-
IProjectileTargetResolvergame SPIAcquisition seam for seeking kinds (Homing): which entity should this projectile steer toward, and is the one it already holds still worth steering toward?
-
IProjectileAvatarLifecycleunity SPIOptional SPI: told why a predicted ghost's avatar goes, immediately BEFORE the projectile client hands it to ICharacterFactory.DestroyAvatar.
-
IProjectilesClientunity SPIThe projectile client: renders deterministic catalog kinds from the shared trajectory evaluator at server-now (no interpolation buffer — their entities stop streaming movement)…
Timed opaque markers (buffs/debuffs) applied to entities.
-
IStatusEffectRulesgame SPISPI the game implements to give effects their meaning — a burning DoT modifies a stat on tick, a stun gates ability rules, a shield changes damage math.
WHO MAY HARM WHOM, answered in one place: consent stances (opt-in verb), combat flags on aggression, escalation tiers on innocent kills, safe zones — one IHarmResolver seam every combat consumer asks (Crossplay:Hostility:DriveTargeting bridges Targeting). PvE pairs pass through untouched; defaults = the classic no-PvP baseline.
-
IHarmResolverproviderTHE seam combat consumers ask: may attacker A harm target B right now?
Two halves of "what am I aiming at". (1) Auto-attack driver: enrolled attackers acquire a target (ITargetSelector) and attack on a cadence (IAttackAction) over World — survivors/auto-shooter auto-fire, turrets, sentries, pet auto-attack. (2) The SELECTED target (TargetSelection:Enabled): SetTargetRequest in, TargetChanged out, validated against the actor's interest set + an ITargetPolicy SPI, readable server-side through ITargetService — tab-target MMOs, RTS selection, a sports pass target, a card game's targeting step. DriveAutoAttack makes your swings land on what you clicked; RevealTargets drives target-of-target frames (off by default — who you selected is information).
-
IAttackActiongame SPIEffect seam: what does an attack DO?
-
IAttackCadenceProvidergame SPIPer-attacker fire-cadence seam: how many seconds between THIS attacker's shots right now?
-
ITargetHostilitygame SPIFaction seam: is a candidate a valid target for an attacker?
-
ITargetPolicygame SPISelection seam: may this actor SELECT this candidate?
-
ITargetSelectorgame SPIAcquisition seam: which entity (if any) should this attacker attack right now?
Consensual 1v1: challenge -> accept -> fight -> the winner is decided by a SERVER-reported defeat, a forfeit, or the time limit. There was no challenge/accept flow anywhere (matches is match containers, tournaments is brackets, and hostility models consent as a standing STANCE rather than "this person, now, then we stop"). The piece is CORE-ONLY: mutual harm, ending a duel just before the loser would die, and restoring the health they spent are the composition's job (Crossplay:DuelCombat over Hostility + Stats), so it also composes into a game with neither. IDuelPolicy = eligibility + stakes.
-
IDuelPolicygame SPIWhether a duel may happen — the game's eligibility and stakes (GAP-14).
Pooled nameplates + eased HP bars + effect chips + cooldown pips over the combat clients. Client-only UI.
-
ICombatHudNameSourceunity SPIThe game's display-name vocabulary: Crossplay has no client-side name registry (names are game data — often encoded in the opaque appearance blob), so plates ask the game.
-
ICombatHudStyleSourceunity SPIThe game's effect presentation vocabulary: an effect id means nothing to the framework, so the default chip is a deterministic id-derived color + the numeric id.
-
ICombatLogClientunity SPIRead access to the live combat log, for games that render their own feed instead of (or beside) the built-in view.
-
ICombatLogVocabularyunity SPIThe game's combat-log wording.
-
IHudCameraProviderunity SPIThe camera plates project through.
Economy
Items, currency & trade.
The generic opaque-item-container engine every item piece sits on: containerId-keyed slots/stacks, policy SPI, persistence, and atomic cross-container moves. Server-only; inventory/bank/vault/equipment are thin roles over it.
-
IContainerConfigProviderproviderOptional seam: supplies the ContainerConfig to create a container with the FIRST time the engine loads it, when no explicit config was passed to EnsureContainer.
-
IContainerPolicygame SPISPI the game implements to give containers their item rules — the framework only moves opaque bytes.
-
IContainerStoreproviderPersistence seam for containers, keyed by ContainerId.
The character's bag — a container role over the Container engine (opaque item blobs, policy SPI, persistence).
-
IInventoryPolicygame SPISPI the game implements to give items its rules — the framework only moves opaque bytes.
-
IInventoryStoreproviderPersistence seam for inventories, keyed by character id.
A personal item-storage container — a role over the Container engine (opaque item blobs; atomic bag<->bank deposit/withdraw via TryExchange; policy SPI; persistence). Depends on Container, not Inventory.
-
IBankPolicygame SPISPI the game implements to give the bank its item rules — the framework only moves opaque bytes.
Worn/active gear in typed slots — a container role over the Container engine (opaque items + opaque slot ids, IEquipmentPolicy SPI). World-optional visible loadout broadcast; item effects via Equipped/Unequipped events (never references Stats).
-
IEquipmentPolicygame SPISPI the game implements to give equip slots their TYPED rules — the framework only moves opaque bytes into slots.
-
IEquipmentSpatialAudiencegame SPIThe spatial audience of a wearer's VISIBLE loadout: who can see the wearer, and when a newcomer starts to.
-
IEquipmentClientunity SPIThe Equipment piece, client side.
-
IEquipmentViewunity SPIThe presentation seam for ONE wearer's VISIBLE loadout — the game binds an entity id + its equipped slots to its own models / attachment points (or a text row, or a 2D paper-dol…
-
IEquipmentViewFactoryunity SPIThe game's factory that resolves a wearer's entity id to its IEquipmentView — the equipment analogue of IRigidBodyViewFactory / ICharacterFactory.
A player's OWN shop, standing where they left it: open a stall that escrows stock out of your bag, and anyone the game's IStallPolicy says can reach it browses and buys — the seller does nothing, and may be afk or offline. Nothing else covered it (shop is system-owned, market is asynchronous listings, trade needs both parties present and consenting). Presentation-agnostic: a market stall, a vending machine you place, a shop sign over an avatar, or a text for-sale list are the same data. Currency = IStallWallet, proximity/zone rules = IStallPolicy, so it names nothing spatial and no Economy type.
-
IStallPolicygame SPIWHERE a stall may open, and who may see one — the game's rules (GAP-13).
-
IStallWalletproviderCurrency seam.
Validated recipe execution (opaque in/out, all-or-nothing) over Inventory; catalog is a game SPI.
-
ICraftingCataloggame SPISPI the game implements to supply its recipe book — the piece is inert (every craft returns UnknownRecipe) until a non-default catalog is registered.
-
ICraftingRulesgame SPIOptional SPI the game implements to gate crafts beyond "holds the ingredients" — skill/level checks, a required crafting station in range, per-recipe cooldowns, quest prerequisi…
Atomic, policy-gated, ledgered currencies; read-only on the wire.
-
IEconomyLedgerproviderSPI recording every committed mutation — the audit trail for the whole economy.
-
IEconomyPolicygame SPISPI the GAME implements to gate every currency mutation — where taxes, caps, level requirements, and region rules live.
-
IEconomyStoreproviderPersistence seam for balances.
Escrowed listings + lock-guarded buyout over Inventory + Economy, with durable Scheduler expiry.
-
IMarketExpiryScheduleproviderThe durable-expiry seam a Market needs: schedule (and re-schedule) a listing's auto-return to the seller — without the piece compiling against the concrete Scheduler.
-
IMarketStoreproviderListing persistence SPI (in-memory default; document-backed across restarts/nodes).
-
IMarketWalletproviderThe currency seam a Market needs: debit the buyer, credit the seller.
System-owned stores selling/buying OPAQUE items for game currencies: catalog stock, per-buyer daily caps, finite stock, buyback ring. Currency/access/appraisal/pricing are seams (Economy bridges the wallet); WHAT a shop is — NPC, vending machine, terminal — is the game's. Server-only wire verbs; empty catalog = inert.
-
IShopAccessproviderThe game's access rule: may THIS player use THIS shop right now?
-
IShopAppraiserproviderThe game's sell-side rule: what does THIS shop pay for THIS item?
-
IShopCounterStoreproviderStorage seam for per-buyer daily purchase counters.
-
IShopFulfilmentproviderHow a paid purchase reaches the buyer — called AFTER the debit.
-
IShopHoldingsproviderHow many units of a line the buyer holds, for MaxHeld.
-
IShopPricingproviderThe game's buy-side price rule — personalizes an entry's unit price per buyer (reputation discounts, dynamic economies, sales).
-
IShopWalletproviderThe currency seam Shop spends and pays through — the piece references NO concrete currency system.
-
IShopEntryExtrasClientunity SPIPer-entry extras a shop sends beside its contents (opt-in server side: an entry's MaxHeld, UnitsPerPurchase or Data): how many more units the buyer may hold, the bundle size, an…
Offline delivery with escrowed item attachments.
-
IMailAttachmentStoregame SPIThe item store Mail's attachments move through: escrowed OUT of the sender's bag on send, materialized into the recipient's bag on claim.
-
IMailPolicygame SPISPI the GAME implements to gate every player-to-player send — where block lists, cross-faction rules, and postage costs (via Economy) live.
-
IMailRecipientResolverproviderThe identity seam Mail resolves recipients through, so the piece never hard-references the Crossplay.Characters spatial piece (it only needs a name↔id directory, not character d…
-
IMailStoreproviderMail persistence SPI (in-memory default; document-backed override across restarts).
Shared guild inventory of opaque item blobs with per-rank deposit/withdraw/view permissions and an audit trail.
-
IGuildVaultItemSourceproviderWhere a WIRE deposit's items come from — the seam that makes the SERVER, not the client, decide what is being deposited.
-
IGuildVaultPolicygame SPISPI the game implements to give the vault its item rules — the framework only moves opaque bytes.
-
IGuildVaultStoreproviderPersistence seam for guild vaults, keyed by guild id.
Containers owned by a group rather than a character — a crew kit, a party stash, a team's shared crate — over the Container engine: the contents are pushed to every session the game's audience seam admits, and only those sessions may read or rearrange them. Items enter and leave through server-side game verbs (atomic exchanges with a member's bag); the wire carries request and move only, so a client is never trusted to say what it takes. Inert until an audience is composed.
-
ISharedContainerAudiencegame SPIThe game's answer to "who sees this container?" — the one decision that makes a container SHARED.
-
ISharedContainerGrantPolicyproviderWhether a session may KEEP using a container the server opened for it — asked on every use (request, move, transfer) and before every pushed change, so a player who walked out o…
-
ISharedContainerWindowsunity SPIOpen containers ("press F on the fridge"): which containers the server has open for this client, closing one, and moving items between your bag and an open container.
Data-driven purchase catalog: wallet stat, per-buyer live price (stored as a stat, so it replicates) with growth, and capped stat effects. Server-only wire verb; empty catalog = inert.
-
IPurchasePolicygame SPIWhether a purchase may happen RIGHT NOW — the SPI that keeps commerce timing the game's.
Coin-priced, persistent, server-authoritative meta-upgrades: price from the buyer's stored tier (ceil(InitialPrice*Growth^tier)), atomic currency debit, tier persisted per-character. Currency + persistence via seams bridged to Economy + PlayerData.
-
IUpgradeTierStoregame SPIThe persistence seam: read / write an owner's upgrade TIER by key.
-
IUpgradeWalletgame SPIThe currency seam: debit amount of currency for an upgrade purchase, atomically.
Social
Chat, guilds & matchmaking.
Alliances of groups - guilds when Guild is installed, otherwise single players: a group founds one, the leader invites, a group applies and the member groups vote it in (a configurable share), groups leave, the leader removes, hands over or disbands. Relationship markers between alliances, between groups and between accounts carry the game's own values (ally, enemy, neutral, whatever it defines). Durable across restarts. Elections, chat and seasonal scores stay with the game or other pieces: an election result calls SetLeader.
-
IAllianceClockproviderThe clock alliances stamp founding times with (a seam so tests and replays control time).
-
IAllianceMembersgame SPIWhat an alliance is made of: the GROUP an account acts for (a guild, a clan, a house) and whether it may act for it.
-
IAlliancePolicygame SPIThe game's say over alliances: who may found one, which group may apply where, which may walk straight in (e.g.
-
IAllianceStoreproviderWhere alliances and relationship markers are kept.
Boards of threads of posts: a parish board, a guild board, a general board - board keys are the game's. Threads list pinned first, then by latest activity, a page at a time; posts page oldest first from a cursor. Authors edit within a window and delete their own; moderators pin, lock and delete. Who may read, post and moderate each board is the game's IForumAccess. Bounded (boards, threads per board, posts per thread, text length, a posting cooldown) and durable across restarts. Nothing is pushed; Posted lets the game tell players.
-
IForumAccessgame SPIWho may read, post on and moderate a board - the game's rules (a parish board for its villagers, a house board for its members, a staff-only board).
-
IForumClockproviderThe clock posts are stamped with (a seam so tests control time).
-
IForumStoreproviderWhere threads and posts are kept.
Server-generated reports delivered to accounts - a battle report, a scouting report, a trade receipt, a match summary. The game calls Create with recipients, a type and category key, title values, related ids and an opaque payload; each recipient gets their own copy. Players list them newest first (by folder, category, unread), open one (which fires Opened), mark read or unread, file them in the game's folders, keep them from expiring, delete (to a deleted folder, then for good) and forward a copy that names the forwarder - who may be forwarded to is the game's IDispatchPolicy. Unread counts per category; online recipients get a push and an optional reply flag. Bounded per account, expired by age, durable across restarts.
-
IDispatchClockproviderThe clock dispatches are stamped and expired by (a seam so tests control time).
-
IDispatchPolicygame SPIWhat a player may do with dispatches beyond their own inbox.
-
IDispatchStoreproviderWhere dispatches are kept.
A conversation-style player mailbox. Threads have a subject and several participants, each with their own copy and read state: start one by player names (unknown names are reported back), reply, forward a thread to new recipients, list newest activity first with paging, open with only-newer-posts refresh, mark posts or whole threads read or unread. Players create, rename and delete their own folders (the inbox is built in), move and delete threads in batches, keep favourites (recent recipients are kept for them), block players (optionally hiding threads with any or all participants blocked) and search names by prefix. Game code posts system threads to any set of accounts under a sender label; posts can be reported for moderators. Push on arrival, unread counts per folder, every limit an option, durable across restarts. Names are the IConversationDirectory seam.
-
IConversationClockproviderThe clock posts are stamped by (a seam so tests control time).
-
IConversationDirectoryproviderPlayer names to account ids and back - how recipients typed by name are found and how senders are named.
-
IConversationStoreproviderWhere conversations are kept.
Standing, weighted elections for offices - one per scope (an area, a region, a server). Voters accrue vote points every period up to a cap and spend any number on any eligible candidates; every tally decays each period, so support has to be kept up. The leader is the top candidate over a minimum (a different bar for the sitting leader is allowed; ties keep the incumbent), recomputed each period, with a LeaderChanged event. Who may vote and stand, allowances, caps and minimums are the game's IElectionPolicy, per account and scope. Works by account id with nobody online; standings, my points and casting over the wire; durable.
-
IElectionClockproviderThe clock periods are counted by (a seam so tests control time).
-
IElectionPolicygame SPIWho may vote and stand in a scope, and the numbers of an election - per account and per scope, so a game can give a noble more vote points than a peasant or ask a higher bar of…
-
IElectionStoreproviderWhere elections are kept.
A recent-activity wall per scope (an area, a group, a server): game code appends typed entries - a kind, the actor, a few numbers and a small opaque payload - and players read them newest first, a page at a time, with actor names and a total, or poll cheaply with a since-cursor. Each scope keeps a capped number of entries, oldest first out (an option, or the game's IActivityPolicy per scope), and who may read a scope is the same policy. Nothing is pushed; durable across restarts.
-
IActivityClockproviderThe clock entries are stamped by (a seam so tests control time).
-
IActivityPolicygame SPIWho may read a scope's wall, and how long it is - the game's rules (a region's members, a guild's members).
-
IActivityStoreproviderWhere walls are kept.
Operator-posted timed notices every player sees - "Maintenance at 18:00" for the next 30 minutes. An operator posts one from the admin API (announce / announce-clear / announcements) with its text and an end time; everyone signed in gets it pushed, every player who signs in before it ends gets it at sign-in, and clearing it takes it down everywhere. The client hides each notice on time by itself; the popup is the game's. No player verb exists, so a notice cannot be forged. Held in memory on each node: a restart drops them.
-
IAnnouncementClockproviderThe clock notices end by (a seam so tests control time).
A display name per account, separate from the login name: the player sets it, game code may set it too, and anyone signed in reads the names of a batch of accounts in one request - offline players included, which is what a friends list, a ranking or a member roster needs. Names are trimmed, length-limited, refused with control or invisible characters, unique by default across case and look-alike forms, and anything further (a word filter, reserved names) is the game's IProfileNamePolicy. Optionally shown as the account's online name when it signs in. Durable across restarts.
-
IProfileNamePolicygame SPIWhat a display name may be, beyond length and characters - a word filter, reserved names, a paid rename.
-
IProfileStoreproviderWhere names live.
Channels and whispers over Core, with profanity masking and rate caps.
-
IChatAudienceResolvergame SPIResolves WHO hears a channel whose audience is not a subscriber list (GAP-15).
-
IChatChannelDirectorygame SPIThe game's list of room channels a player may see: area channels from the game's rules, a help channel, a global one.
-
IChatChannelPolicygame SPIThe game's say over room channels (Party, Guild, Custom): who may join a Custom channel, who may send to a room, who may read and delete its history.
-
IChatClockproviderWall-clock seam (unix UTC ms) so mute-expiry math is testable — implement it to feed a fake clock in tests.
-
IChatHistoryStoreproviderWhere chat history and read markers are kept.
-
IChatMuteStoreproviderMute-persistence SPI — the seam that decides where mutes are stored.
Persistent guilds: officer ranks, MOTD, invites/kicks, leader handoff.
-
IGuildPolicygame SPIThe game's say over guild membership: who may found a guild, invite, apply and join.
-
IGuildStoreproviderGuild persistence SPI — the seam that owns where and how guild data lives.
Ephemeral parties: leader, ready checks, kicks.
-
IPartyMemberLocatorgame SPIThe member-location seam the Party piece OWNS — how the roster's Zone/Endpoint fields fill without Party (a Core-only feature piece) ever referencing the World piece.
-
IPartyReadySinkgame SPIThe post-ready-check seam the Party piece OWNS — the analog of Matchmaking's IMatchFormedSink and Lobbies' ILobbyStartSink: fired once when a party's ready check completes with…
-
IPartyStatePolicygame SPIWho may write the party's shared opaque state blob (PartySetStateRequest).
-
IPartyStoreproviderPersistence SPI for live parties and pending invites.
Server-authoritative in-match sides per game-defined scope: opaque team ids, members, a rankable score + opaque blob, team-scoped broadcast, optional policy-gated self-service joins.
-
ITeamPolicygame SPIGame-implemented join rules for self-service (TeamJoinRequest) joins — balance caps, faction locks, "no switching after the round starts".
Friend lists, requests, and online presence.
-
IFriendStoreproviderFriendship persistence SPI.
Queue-based matchmaking with team/role quotas and MMR.
-
IMatchFormedSinkgame SPIThe post-formation seam this piece OWNS (the IMatchResultSink idiom): called after a match forms, BEFORE any MatchFound is sent, with every member — cross-node aware.
-
IMatchmakerPolicygame SPISPI the game implements to gate match QUALITY: given a full set of candidates, is this a good enough match to form now?
-
IRatingModelgame SPISPI the game implements to rate players — the MMR the matchmaker balances by.
Create/join/list lobbies with slots and metadata.
-
ILobbyStartPolicygame SPIWhether the host may start the lobby RIGHT NOW — the SPI that keeps "when is a lobby ready to play" the game's.
-
ILobbyStartSinkgame SPIThe start seam this piece OWNS (the IMatchFormedSink idiom): called inside TryStartMatch after the lobby's state flips to InProgress, BEFORE the MatchStarting broadcast, with th…
-
ILobbyJoinCodeClientunity SPIJoin codes (opt-in server side: Lobbies:JoinCodes:Enabled): the code of the lobby you entered, and joining by one.
-
ILobbyQuickJoinClientunity SPIQuick join (opt-in server side: a Lobbies:QuickJoin row per mode): the Play button — an open room of the mode, or a new one.
Allocate game instances (zone/room/lockstep) on match/lobby formation across nodes, hand each player a single-use join token, run the lifecycle, and return them to the hub.
-
IExternalAllocatorgame SPIThe game/infra adapter to an EXTERNAL fleet manager (Agones, a Kubernetes operator, a studio's own allocator API).
-
IInstanceKeepAlivegame SPIOpt-in keep-alive for the abandoned sweep (TTG-12): lets the game say "this instance is empty, but its players are coming back" — e.g. a roster sent away into ANOTHER instance (…
-
IInstanceRealizergame SPIThe kind bridge: how an InstanceKind becomes a real container on THIS node.
-
IInstanceStoreproviderInstance-record store.
-
IJoinTokenStoreproviderSingle-use join-token store.
-
IPlacementStrategyproviderPlacement SPI.
-
ITransferAuthenticatorunity SPINarrow re-authentication seam the transfer flow rides after each dial: "restore my session on the server I'm now connected to — did it work?".
Progression
XP, quests & rewards.
Persistent ranked boards: keep-best, around-me, rolling seasons.
-
ILeaderboardClockproviderSPI supplying "now" (unix UTC ms) to the rolling-season math — implement it to control where season boundaries fall (and to make season rollover deterministic in tests).
-
ILeaderboardEntryDatagame SPIThe game's per-row bytes on a page (Data): a group id, a badge, anything the board screen shows beside a name.
-
ILeaderboardStoreproviderPersistence-swappable storage for leaderboard entries: an upsertable set of ScoreRecord per (board, season).
-
ILeaderboardSubmitPolicygame SPIWire-submit gate (game SPI): decides whether a SESSION may submit a score to a (board, season) over the wire (LeaderboardSubmitRequest).
Interval claims with grace-window streaks; reward is an IDailyRewardGrantor game SPI.
-
IDailyClockproviderWall-clock seam (unix-epoch UTC milliseconds) so the interval/streak math is testable and restart-safe.
-
IDailyRewardGrantorgame SPITHE game hook: what a daily reward IS.
-
IDailyRewardStoreproviderClaim-state persistence SPI, keyed by the owner (character) id.
Server-reported counters against game-defined thresholds; catalog/reward are game SPIs.
-
IAchievementCataloggame SPISPI the GAME implements to declare its achievements — the source of every id, counter key, and threshold.
-
IAchievementRewardGrantorgame SPIOptional SPI the GAME implements to decide what an unlock GRANTS.
-
IAchievementStoreproviderPersistence seam for achievement state.
Multi-track server-granted xp/levels; curve is config exponential or an IProgressionCurve SPI.
-
IProgressionCurvegame SPISPI the GAME implements to define the shape of the leveling curve — how much xp completes each level on a track.
-
IProgressionRewardGrantorgame SPIOptional SPI the GAME implements to decide what a level-up GRANTS.
-
IProgressionStoreproviderPersistence seam for progression state.
Accept/track/turn-in over game-defined objectives; catalog/policy/reward are game SPIs.
-
IQuestCataloggame SPISPI the GAME implements to define its quests — the source of every quest id, its repeatable flag, and its objectives.
-
IQuestPolicygame SPISPI the GAME implements to gate quest ACCEPTANCE — prerequisites, level gates, faction checks, "one per chain" rules.
-
IQuestRewardGrantorgame SPIOptional SPI the GAME implements to decide what a turn-in GRANTS.
-
IQuestStoreproviderPersistence seam for quest state.
Server-resolved conversation graphs: opaque node/choice payloads, per-choice conditions evaluated SERVER-side and stripped from the wire, choice actions via game SPIs. NPC talk, visual novels, tutorials, quest givers — one engine; Core-only, stateless, empty graph table = inert.
-
IDialogActiongame SPIThe game's action vocabulary: what picking a choice DOES — accept a quest, open a shop, grant an item, set a flag.
-
IDialogConditiongame SPIThe game's condition vocabulary: "is condition C true for THIS player right now?" — quest state, stats, items, reputation, anything.
-
IDialogPolicyproviderThe game's open rule: may THIS player open THIS graph now?
-
IDialogSourceproviderWhere graphs come from.
Meta
Data, matches & tournaments.
Timed movements between named nodes that survive restarts: an army marching on a village, a caravan carrying goods, a scout, a monk, a delivery drone. Start one with an opaque private payload and public data, recall it (it returns taking as long as it had travelled), redirect it, cancel it; the game's ITransitArrival resolves what arriving means (a siege, a trade, a drop), and may start the trip home. Owner and target see every change (ITransitAudience adds watchers), a since-id cursor lists what is in flight, and nothing streams while it travels - a client draws the journey from its two timestamps. Nodes are game-defined strings: a village on a 2D map, a city on a globe, a stop on a route.
-
ITransitArrivalgame SPIThe game's answer to "what happens when it gets there?" - one registration per kind it cares about (or kind 0 for every kind).
-
ITransitAudiencegame SPIWho sees a transit: the accounts it is pushed to on every change, and whether one viewer may list it.
-
ITransitClockproviderWall clock seam (unix ms UTC) so journeys are testable.
-
ITransitRecallPolicygame SPIWho may recall a transit from the client.
-
ITransitStoreproviderWhere transits live between restarts.
Interest without an avatar: a client watches the regions of a map it is looking at - a parish, a tile block, a whole-world ownership layer - and gets each one as a snapshot, then versioned deltas on that region's own flush cadence (busy parishes fast, the world map slow). Rejoining with the version it held gets only what changed. Entries are game ids with opaque values the game keeps current (IRegionService.Set); who may watch what is the game's IRegionAccess. For strategy maps, city builders, board and grand-strategy games - anything whose players look at places rather than walk through them.
-
IRegionAccessgame SPIWho may watch a region.
Server-originated one-shot opaque events to a session, a room, or a zone — a bell everyone hears, a scripted cue, "somewhere a door opened". An EVENT, never state: never stored, never replayed, so a reconnecting player is told nothing about what they missed (which is what separates it from ZoneState/EntityState). No client verb exists, so a signal is unforgeable by construction. Spatial-optional: the zone route needs World, the rest does not.
-
ISignalZoneAudiencegame SPIResolves WHO is in a zone, for ToZone.
Per-player key/value store of opaque blobs.
-
IPlayerDataPolicygame SPISPI the game implements to gate CLIENT-initiated writes (the wire PlayerDataSet).
-
IPlayerDataStoreproviderPersistence seam for player data, keyed by the owner (character) id.
Match lifecycle (countdown/duration/return-zone) with results bridged to Leaderboards.
-
IMatchResultSinkgame SPIWhere final results go besides the participants — the composition layer bridges this to Leaderboards when both pieces are present (Matches itself never references another piece).
-
IMatchRulesgame SPISPI the game implements to give matches their meaning — scoring, win conditions, teams — the plug-in point of this piece.
Server-authoritative phase/round state machine per game-defined scope: opaque phase ids, per-phase deadlines, IRoundFlow SPI transitions, and an authoritative elimination set. No client verbs (unforgeable).
-
IRoundFlowgame SPITHE plug-in point of the Rounds piece: the game's phase graph.
Server-opened proposals over opaque choice ids: one ballot per eligible voter, live anonymous tallies, deadline/everyone-voted close, outcome decided by an IVoteRules SPI (plurality default). The game acts on Closed; the piece never executes outcomes.
-
IVoteRulesgame SPIThe game's tally rules: called once when a vote closes (deadline, everyone voted, or an explicit close) with the full context — all ballots, choices, and eligible voters — and a…
Server-assigned opaque role ids with per-viewer visibility filtering (a hidden assignment never touches the wire), per-holder private payloads, role-scoped sends, and an end-of-game reveal. IRoleVisibilityPolicy SPI; no client verbs (unforgeable).
-
IRoleVisibilityPolicygame SPIThe game's "who may know whose role" rule — the non-spatial visibility axis this piece exists for.
Live tuning values pushed to clients.
-
IRemoteConfigStoreproviderPersistence seam for the config set.
Persistent fire-at-time callbacks that survive restarts. Server-only.
-
IScheduleHandlergame SPIThe SPI a game implements per KIND: when an entry of your kind comes due, you get its opaque payload.
-
IScheduleStoreproviderPersistence seam: pending entries must survive restarts.
-
IWallClockproviderWall-clock seam (restart-safe time, unlike the uptime-based server clock).
Genre-agnostic gameplay-event pipeline: server-authoritative Track + a rate-capped client wire, batched off-thread to the game's IAnalyticsSink SPI (Segment/Amplitude/BigQuery/…). Ships inert (null sink counts + drops).
-
IAnalyticsSinkgame SPITHE routing SPI (server-side): the game implements this to ship batched events to ITS warehouse — Segment, Amplitude, BigQuery, Kafka, a JSONL file, anything.
Report-a-player: rate-capped, recorded, surfaced via an admin decorator.
-
IReportClockproviderWall-clock seam (unix UTC ms) so rate-cap math is testable.
-
IReportStoreproviderPersistence seam for filed reports.
Server = input authority (order/relay/ack/checksum); client RollbackEngine + IDeterministicSim SPI.
-
IBufferedDeterministicSimgame SPIThe allocation-free flavour of IDeterministicSim.
-
IDeterministicSimgame SPIThe SPI a game implements to run under rollback netcode — the same three-callback shape GGPO pioneered.
Single-elimination brackets: winners reported by server code (never client-trusted); join policy + champion reward are game SPIs.
-
ITournamentEventFormatgame SPISPI: the EVENT-based side of the format family — scheduling rules for tournaments whose unit of play is an N-entrant scored EVENT (a race, a heat, a battle-royale round) rather…
-
ITournamentFormatgame SPISPI: the tournament's SCHEDULING RULES — what a valid field size is, how the field is paired into matches, and how a recorded result advances the schedule until a champion is de…
-
ITournamentPolicygame SPISPI the GAME implements to gate who may register in a bracket — rating floors, entry fees, faction or level checks, ban lists: all game logic.
-
ITournamentRewardGrantorgame SPISPI the GAME implements to decide what a champion receives — the returned byte[] is an OPAQUE, game-defined reward blob that rides the TournamentChampion push to participants; t…
-
ITournamentScoringgame SPISPI the GAME implements to decide what a finishing position in an N-entrant EVENT is worth — the scoring half of the event-based format family (ITournamentEventFormat): standing…
-
ITournamentStoreproviderPersistence seam for tournament state.
Resolves keys (notification codes etc.) to localized, interpolated strings with locale fallback; strings are game data via ILocalizationCatalog. Client-only, Core-only.
-
ILocalizationCatalogunity SPIThe game's locale tables.
Record broadcasts server-side (archive) + play a .cdrp recording back through the live client dispatch with play/pause/speed/seek.
-
IReplayArchiveproviderDurable storage for recordings: upload a blob under a game key, list what exists, fetch it back, delete it.
-
IReplaySpectatorHostgame SPIWhere a ReplayRecorder spectates from: it seats the recorder as an invisible, receive-only session in a zone, so the recorder is handed exactly the frames a watching client woul…
-
IReplayPlayerunity SPIReplay playback control: load a .cdrp recording and play it back through the live client dispatch.
Infra
Client-side toolkits.
Generic rent/return instance pooling on the client. Client-only.
-
IObjectPool<T>unity SPIA generic rent/return pool for plain C# objects.
-
IPoolableunity SPIOptional lifecycle hook for components on pooled GameObjects.
Peer-to-peer rooms with no dedicated server: a player hosts a Crossplay server inside the game (the same kernel and pieces), friends join by room code over WebRTC through the rendezvous relay Crossplay runs for every project, and the host plays in-process. Rooms service (host / join / browse / leave), Unity-side WebRTC server transport, optional uGUI panel; the game adds its pieces via IInAppServerComposition. Turn P2P on for the project in the Hub to get its relay credentials. Requires com.unity.webrtc. Client-only.
-
IP2pRoomsunity SPIPeer-to-peer rooms for a project that turned P2P on in the Hub: no dedicated server anywhere.
Net/sim overlay: RTT, rates, interp delay, prediction error, cull tiers. Client-only.
-
IDebugGizmoSourceunity SPIGame seam for the debug gizmos (C16): supply extra shapes to draw in the Scene view.
The always-present shared client SPIs a game binds to, independent of any feature piece: IGameplayInput + MovementIntent (feed input intent), IAnimatorParameterMapper (map locomotion onto your animator), and IAssetService + IAssetScope (load assets by key). Feature pieces (movement, input, assets, audio) implement or consume these contracts, so a game can bind any SPI without installing the feature that used to define it. A must for Core — auto-installed, cannot be unselected. Client-only, no wire.
-
IAnimatorParameterMapperunity SPISPI the game implements to map Crossplay's universal locomotion state onto its own animator.
-
IAssetScopeunity SPIA disposable loading bucket for keys and labels (a zone's content, a screen's content).
-
IAssetServiceunity SPIThe asset-loading SPI every Crossplay client system loads content through: ref-counted load/release by key, label preloads, tracked instantiation, and CreateScope for lifetime-b…
-
IGameplayInputunity SPISPI the game implements to feed movement intent from any input source (new Input System, AI, replay, …).
FPS/MMO/click-to-move/ARPG/drag-axis/cards control schemes over the intent SPI. Client-only.
-
IInputAxisProviderunity SPIWhich WORLD direction a rightward drag moves the pawn along — the one thing a drag scheme cannot know for itself.
-
IInputCameraProviderunity SPIThe camera used to turn pointer positions into world rays.
-
IInputPawnLocatorunity SPIWhere the local player's pawn IS — needed by point-targeted schemes (click-to-move, ARPG) to steer toward a world point.
-
IMovementKeysunity SPIWhether a movement control is held - the seam a game binds to offer key REBINDING for walking and running.
Shared infrastructure
Seams that belong to the platform, not to one piece.
Every piece that persists anything rides these. Implement one and every piece's storage follows.
-
IBatchDocumentStoreproviderOptional capability: apply several writes as ONE atomic unit — all land or none do.
-
IDocumentStoreproviderA generic, provider-agnostic document store — the whole persistence infra.
-
IDocumentStoreExportproviderThe backup capability: enumerate EVERYTHING a store holds (documents + indexes + sequences) and set sequence positions on restore.
-
ISteamSocketsproviderThe seam between SteamServerTransport and Steam itself.
-
IRendezvousClientproviderHow this server is introduced to peers that have no address to dial.