cultmath-unity [Unreleased] and cultlib [Unreleased] carry the Breaking entries; no version bump, no tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
108 lines
5.2 KiB
Markdown
108 lines
5.2 KiB
Markdown
# GameCult.Caching.MessagePack
|
|
|
|
`GameCult.Caching.MessagePack` provides the canonical CultCache persistence
|
|
format for the attribute-first `GameCult.Caching` stack.
|
|
|
|
## Included Types
|
|
|
|
- `SingleFileMessagePackBackingStore`
|
|
- `CultDocumentMessagePackSerialization`
|
|
- `CultDocumentResolver`
|
|
- `CultRecordRefFormatter<T>`
|
|
- `CultMathResolver`: the canonical component-array encoding of every public CultMath value type, part of the default resolver chain
|
|
- `CultMathExprResolver`: the canonical encoding of `CultMath.Expr.ExprGraph`, decoded through its validator, part of the default resolver chain
|
|
|
|
Cult document payloads serialize through `MessagePackSerializer` with the
|
|
options of the document's assembly (`CultDocumentMessagePackSerialization.OptionsFor`),
|
|
after the reflective `CultDocumentRegistry` has accepted the document shape. The
|
|
store snapshot format is written by hand against
|
|
`MessagePackWriter`/`MessagePackReader`.
|
|
|
|
## What It Does
|
|
|
|
- stores whole CultCache snapshots in MessagePack
|
|
- serializes attributed document payloads as MessagePack `[Key(n)]` arrays
|
|
- keeps explicit `CultRecordRef<T>` values compact on disk/wire
|
|
- preserves the cache/store split where metadata lives outside the domain model
|
|
|
|
## Example Model
|
|
|
|
```csharp
|
|
using GameCult.Caching;
|
|
using MessagePack;
|
|
|
|
[CultDocument("gamecult.item_data", "gamecult.item_data.v1")]
|
|
public sealed class ItemData
|
|
{
|
|
[Key(0)] [CultName] public string Name = string.Empty;
|
|
[Key(1)] public int Value;
|
|
}
|
|
```
|
|
|
|
## Typical Usage
|
|
|
|
```csharp
|
|
using GameCult.Caching;
|
|
using GameCult.Caching.MessagePack;
|
|
|
|
var cache = new CultCache();
|
|
var store = new SingleFileMessagePackBackingStore("Data.msgpack");
|
|
|
|
cache.AddBackingStore(store);
|
|
await cache.PullAllBackingStoresAsync();
|
|
```
|
|
|
|
## Notes
|
|
|
|
- Payload bytes are MessagePack. Store metadata and schema catalogs are also
|
|
persisted through hand-written MessagePack array layouts in this package.
|
|
- The raw CultNet document lane should treat these payload bytes as already
|
|
blessed, not decode and re-encode them for sport.
|
|
|
|
## CultMath Value Shapes
|
|
|
|
Every public CultMath value type has one MessagePack shape (`CultMathResolver`,
|
|
in the default chain) and one JSON shape (`CultMathJson`, added to a consumer's
|
|
options with `new JsonSerializerOptions().AddCultMathConverters()`; CultLib owns
|
|
no JSON options of its own). MessagePack decoding skips extra elements, leaves
|
|
missing ones at zero (`Color32` alpha at 255) and refuses nil. JSON reading
|
|
skips unknown properties (`UnmappedMemberHandling.Disallow` refuses them), leaves
|
|
missing ones at zero, honours `PropertyNameCaseInsensitive`, lets a repeated
|
|
property replace the whole earlier value (refused when `AllowDuplicateProperties`
|
|
is false), and throws `JsonException` for a wrong token or an out-of-range number.
|
|
Numbers follow `JsonSerializerOptions.NumberHandling` as System.Text.Json's own
|
|
float does: `"NaN"`, `"Infinity"` and `"-Infinity"` are written under
|
|
`AllowNamedFloatingPointLiterals` or `WriteAsString` and read under
|
|
`AllowNamedFloatingPointLiterals` or `AllowReadingFromString`; quoted numbers read
|
|
under `AllowReadingFromString` with no surrounding whitespace.
|
|
Every type is also a dictionary key: its flattened components joined by commas,
|
|
invariant culture (`"1,2"`, `"true,false"`, matrices row by row, `rect` as
|
|
`"minX,minY,maxX,maxY"`), and only that exact spelling reads back. Two intended
|
|
divergences from System.Text.Json: a bare number beyond a component's range
|
|
(`1e40` as a float) is refused where System.Text.Json reads infinity, and a
|
|
refusal on write is a `JsonException` where System.Text.Json throws
|
|
`ArgumentException`. A consumer resolver or converter
|
|
registered ahead of these wins.
|
|
|
|
`CultMath.Expr.ExprGraph` is a class, not a value type, and has its own shape
|
|
(`CultMathExprResolver`, in the default chain): `[version, inputs, params, outputs, nodes]`,
|
|
with a param `[name, default float bits]`, an output `[name, node]` and a node
|
|
`[op name, operands, payload]`. Decoding runs the graph's one validator and refuses a
|
|
broken graph whole (an `ExprGraphException` naming the rule), so a consumer
|
|
`[CultDocument]` record with an `ExprGraph` field needs no registration. A nil graph is nil, as in every reference slot; decoding refuses any encoding but the canonical one.
|
|
|
|
| Type | MessagePack | JSON |
|
|
| --- | --- | --- |
|
|
| `float2`, `double2`, `int2`, `bool2` | `[x, y]` | `{"x":..,"y":..}` |
|
|
| `float3`, `double3`, `int3`, `bool3` | `[x, y, z]` | `{"x":..,"y":..,"z":..}` |
|
|
| `float4`, `int4`, `bool4`, `quaternion` | `[x, y, z, w]` | `{"x":..,"y":..,"z":..,"w":..}` |
|
|
| `Color32` | `[r, g, b, a]` as uint8 | `{"r":..,"g":..,"b":..,"a":..}` |
|
|
| `Random` | `[state]` | `{"state":..}` |
|
|
| `float2x2`, `float3x3` | array of row vectors (row-major) | array of row objects |
|
|
| `rect` | `[min, max]` of `float2` | `{"min":{..},"max":{..}}` |
|
|
| `CultCellular` | `[nearest, edge, id]` | `{"nearest":{..},"edge":{..},"id":..}` |
|
|
| `CultPhasor` | `[cosine, sine]` of `float4` | `{"cosine":{..},"sine":{..}}` (reads legacy `cos`/`sin`) |
|
|
| `CultSiteCells` | `[nearest, second, nearestSite, secondSite]` | `{"nearest":{..},"second":{..},"nearestSite":..,"secondSite":..}` |
|
|
|
|
Floats are MessagePack float32 (`0xCA`), doubles float64 (`0xCB`), integers the
|
|
shortest MessagePack integer.
|