Table of Contents

Class ContentMaterializer

Namespace
GrindFest.Content
Assembly
GrindFest.dll

Turns a definition's data into a spawned instance. Two layers:

Hydrate(ContentDef, GameObject) — applies the definition's merged values (patches, replaces, added/removed components) onto a freshly instantiated archetype. Untouched definitions are a no-op: their archetype already carries the final values, and prefab identity stays stable because gameplay derives deterministic values from prefab references. Only overridden content pays the ~2–3 ms apply measured by the phase-0 spike (MaterializerSpikeTests). • Materialize(GameObject, ContentDef, out Report)/Apply(GameObject, Dictionary<string, object>) — the spike-compatible raw surface (clone + apply, or apply onto an instance).

Value decoding lives in ContentCodec (plan §4.2, runtime direction). A baked-template cache (plan L4) is deliberately not part of this build: a cached template is an inactive clone, and instantiating from it would defer Awake for spawns whose consumers expect an active prefab — templates return once consumer activation semantics are audited.

public static class ContentMaterializer
Inheritance
object
ContentMaterializer

Methods

Apply(GameObject, Dictionary<string, object>)

Applies encoded component values onto an instance. Matching is by component type name (the mirror's key is the concrete class name, e.g. "WeaponBehaviour"); the first matching behaviour wins.

Hydrate(ContentDef, GameObject)

Applies a definition's merged values onto a just-spawned instance. A no-op for untouched definitions (their archetype already carries the final values, and prefab identity stays stable for the gameplay formulas that hash prefab references); the whole point for patched/overridden ones.

Call right after Instantiate, before the instance starts living. Only overridden content pays the apply cost, and only once per spawn (~2–3 ms measured naive).

Materialize(GameObject, ContentDef, out Report)

Materialises from an already loaded archetype (the caller owns its lifetime/refcount).

MaterializeAsync(ContentDef)

Materialises a definition: loads its archetype, clones it, applies the merged component values.

Async because there is no synchronous load: the archetype is fetched through GetOrLoadAsync<T>(string, AssetTier, CancellationToken) and the report is returned alongside the instance, since an out parameter cannot cross an await.