CultLib/src/GameCult.Caching.MessagePack.Generator/README.md
Meta Vens 0db1fe5448 Apply Soul fixes to the store composition docs and routing tests
Conditional commit, not plain flush, is what protects against unseen data.
C# batch and conditional commit are specified, not implemented. Home-type
claims use exact equality. TypeScript attach does not read. CultMath has no
encoding. Reflective and generated descriptors differ until Cut 4. Routing
tests now check the inherited Name, the global flag precondition, and that a
refused write publishes no change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 16:13:20 +02:00

2.5 KiB

GameCult.Caching.MessagePack.Generator

A Roslyn incremental source generator that emits CultCache document metadata, and MessagePack payload codecs where it can, for classes marked [CultDocument].

Scope

Infrastructure for the caching stack. Application code does not reference it directly; it arrives through GameCult.Caching.MessagePack.Analyzers. Without it, CultDocumentRegistry builds descriptors by reflection, and the two differ: reflective descriptors include inherited members and order unkeyed members by declaration token; generated descriptors include only declared members and order unkeyed members by name. For derived documents or unkeyed members the two produce different schema ids. This is scheduled to be fixed in Cut 4.

What It Generates

One GeneratedCultDocumentMetadataProvider_<Assembly> per assembly, registered with [assembly: CultGeneratedDocumentMetadataProvider], holding for each [CultDocument] class:

  • schema name, schema version, and whether the type is [CultGlobal]
  • member definitions (name, slot, persisted type name, reference and cardinality, [CultName], [CultIndex])
  • name and index accessors
  • a payload serializer, and a deserializer when the type has a public or internal parameterless constructor

Members are the public, non-static, non-[IgnoreMember] fields and settable properties declared on the class itself; inherited members are not discovered. Members with [Key(n)] take slot n; unkeyed members follow the highest key in ordinal name order. Annotate every persisted member: source order is not a schema.

Payload codecs are emitted only when slots are dense (0..n-1) and the compilation references MessagePack and GameCult.Caching.MessagePack. Otherwise the definition carries no codec and serialization falls back to the reflective path. A generated payload is an array of the members in slot order; the deserializer leaves missing trailing slots at their initializer values and skips unknown extra slots. Generated codecs read CultDocumentMessagePackSerialization.Options at call time.

The generator has no [Union] handling.

When You Need To Think About This Package

  • a document's descriptor or schema id differs between generated and reflective builds
  • a document serializes through the reflective path when you expected a codec
  • you are debugging build-time source generation

Distribution

Packaged for consumers through ../GameCult.Caching.MessagePack.Analyzers/README.md.