contracts

Contracts (Client SPIs)

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.

Category Infra Unity types 4
Unity package
com.crossplay.contracts
Depends on
nothing but the kernel
Shape
client-only · no server half

Unity seams you implement 4

The client half's sockets. Bind your implementation in the client context and Crossplay's client calls it — this is where your models, animators, UI and controls plug in.

IAnimatorParameterMapper unity SPI

SPI the game implements to map Crossplay's universal locomotion state onto its own animator. The base sends a discrete idle/walk/run byte plus velocity/yaw; the game decides which animator parameters that drives (a Speed float, an IsMoving bool, a blend tree, …).

  • void Apply(Animator animator, byte locoState, Vector3 velocity, float yaw)

    Applies locomotion to animator. locoState is the idle/walk/run byte (see Crossplay.Movement.Contracts.Protocol.LocomotionState); velocity and yaw (radians) allow finer blends.

IAssetScope unity SPI

A disposable loading bucket (a zone's content, a screen's content).

  • UniTask<T> LoadAsync<T>(string key)

    Loads through the service and remembers the key for bulk release.

  • UniTask<int> PreloadLabelAsync<T>(string label)

    Preloads a label and remembers it for bulk release.

IAssetService unity SPI

The asset-loading SPI every Crossplay client system loads content through: ref-counted load/release by key, label preloads, tracked instantiation, and CreateScope for lifetime-bound loading. The default provider is the Addressables service in the assets piece, but a game may bind its own implementation (Resources, a bundle loader, …) — so consumers depend on THIS contract, not on any particular loader.

  • UniTask<T> LoadAsync<T>(string key)

    Loads (or shares) the asset at key; increments its ref count.

  • void Release(string key)

    Decrements a key's ref count; the underlying handle is freed at zero.

  • UniTask<GameObject> InstantiateAsync(string key, Transform parent = null)

    Instantiates a prefab by key (tracked; release with ReleaseInstance).

  • void ReleaseInstance(GameObject instance)

    Destroys an instance created by InstantiateAsync and frees its handle.

  • UniTask<int> PreloadLabelAsync<T>(string label)

    Loads EVERY asset under a label (bulk preload; ref-counted as one unit per label).

  • void ReleaseLabel(string label)

    Releases a label preload.

  • IAssetScope CreateScope(string name)

    A lifetime bucket: everything loaded through it releases together on Dispose.

  • IReadOnlyDictionary<string, int> LoadedKeys

    Currently held keys with their ref counts (diagnostics/overlay).

IGameplayInput unity SPI

SPI the game implements to feed movement intent from any input source (new Input System, AI, replay, …). Crossplay samples it once per fixed send tick and forwards it as a MoveInput.

  • MovementIntent Sample()

    Returns the current desired movement for this frame.