# Pyrite64 Prefab System: Object Instantiation and UUID Management Explained

> Discover Pyrite64's prefab system. Learn how stable 64-bit UUIDs for templates and ephemeral 32-bit UUIDs for instances manage object instantiation and data reuse effectively.

- Repository: [Max Bebök/pyrite64](https://github.com/hailtododongo/pyrite64)
- Tags: deep-dive
- Published: 2026-02-19

---

**Pyrite64's prefab system uses stable 64-bit UUIDs for template definitions and ephemeral 32-bit UUIDs for instantiated objects, linked via a `uuidPrefab` property that enables per-instance overrides while maintaining data reuse.**

The Pyrite64 prefab system, implemented in the `HailToDodongo/pyrite64` repository, provides a robust mechanism for creating reusable object templates in Nintendo 64 development. By separating the persistent prefab definition from runtime instances through a dual-UUID architecture, the system enables efficient asset management while allowing per-instance customization through property overrides.

## Core Architecture of the Pyrite64 Prefab System

### Prefab Definition and Global UUIDs

At the heart of the system lies the `Prefab` class defined in [`src/project/scene/prefab.h`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/scene/prefab.h). Each prefab maintains a **global 64-bit UUID** stored via `PROP_U32(uuid)` alongside an `Object` instance that serves as the template data. This template contains the default transform (position, rotation, scale), component configurations, and other properties that define the prefab's behavior.

The UUID generation relies on `Utils::Hash::randomU64()`, ensuring that each prefab receives a unique, stable identifier that persists across project saves and loads. As noted in the source comments, changing these ID mappings would break existing saved scenes and prefabs, emphasizing the critical role of UUID stability in the asset pipeline.

### Serialization and Asset Storage

The `Prefab` class implements `serialize()` and `deserialize()` methods in [`src/project/scene/prefab.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/scene/prefab.cpp) to handle persistence. During serialization, the method writes both the prefab's UUID and the serialized `Object` data into JSON format. The `save()` method then writes this JSON to disk at `assets/<name>.prefab`, establishing the asset file format that the engine uses to reload prefab definitions.

## Object Instantiation and UUID Generation

### Creating Prefabs from Existing Objects

The `Scene` class in [`src/project/scene/scene.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/scene/scene.cpp) provides `createPrefabFromObject()` to convert existing scene objects into reusable prefabs. When invoked, this method generates a new random 64-bit UUID using `Utils::Hash::randomU64()` and creates a new `Prefab` instance containing the object's current state. This establishes the template that future instances will reference.

### Instantiating Prefabs in Scenes

Runtime instantiation occurs through `Scene::addPrefabInstance()`, also located in [`src/project/scene/scene.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/scene/scene.cpp). This method performs several critical operations:

1. **Retrieves the prefab** using `AssetManager::getPrefabByUUID()` from [`src/project/assetManager.h`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/assetManager.h)
2. **Generates a fresh 32-bit UUID** for the new instance via `Utils::Hash::randomU32()`
3. **Copies transform data** from the prefab's template object
4. **Establishes the prefab link** by setting `obj->uuidPrefab.value = prefab->uuid.value`

This dual-UUID approach—64-bit for the prefab definition, 32-bit for the instance—enables the `AssetManager` to maintain a global lookup table while allowing the `Scene` to track individual object instances efficiently.

## Property Overrides and Instance Customization

Once instantiated, objects can override prefab properties without affecting the template. The `Object` class stores a property override map (`<property-id → GenericValue>`) that shadows the prefab's default values. When `addPrefabInstance()` creates a new instance, it automatically adds override entries for transform properties (`pos`, `rot`, `scale`), enabling immediate per-instance editing.

The property system, defined in [`src/utils/prop.h`](https://github.com/HailToDodongo/pyrite64/blob/main/src/utils/prop.h), uses macros like `PROP_U32` to create properties with deterministic hash-based IDs generated via `Utils::Hash::crc64(name)`. This ensures that property identifiers remain consistent across compilation units, enabling reliable serialization and override resolution.

## Build Pipeline Integration

During the build process, [`src/build/prefabBuilder.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/build/prefabBuilder.cpp) processes prefab instances for the Nintendo 64 target. The builder checks `obj->uuidPrefab` to identify prefab-linked objects and retrieves the corresponding template data from `prefab->obj`. This integration ensures that prefab definitions are properly resolved and baked into the final ROM, maintaining the relationship between instances and their templates while optimizing for the target hardware.

## Summary

- **Pyrite64's prefab system** uses a dual-UUID architecture with stable 64-bit identifiers for prefab templates and ephemeral 32-bit UUIDs for runtime instances.
- **Prefab definitions** are stored in `assets/<name>.prefab` files via JSON serialization, with UUIDs generated using `Utils::Hash::randomU64()` in [`src/project/scene/scene.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/scene/scene.cpp).
- **Instantiation** occurs through `Scene::addPrefabInstance()`, which creates new objects with unique 32-bit UUIDs and establishes prefab links via the `uuidPrefab` property.
- **Property overrides** allow instances to customize transform data and components without affecting the template, utilizing the generic property system defined in [`src/utils/prop.h`](https://github.com/HailToDodongo/pyrite64/blob/main/src/utils/prop.h).
- **Build integration** in [`src/build/prefabBuilder.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/build/prefabBuilder.cpp) resolves prefab links during compilation for Nintendo 64 targets.

## Frequently Asked Questions

### How does Pyrite64 generate UUIDs for prefabs versus object instances?

Pyrite64 uses `Utils::Hash::randomU64()` to generate 64-bit UUIDs for prefab definitions when calling `Scene::createPrefabFromObject()`, ensuring stable, globally unique identifiers for templates. For individual object instances created via `Scene::addPrefabInstance()`, the system generates 32-bit UUIDs using `Utils::Hash::randomU32()`, allowing efficient scene-level tracking while maintaining the link to the parent prefab through the `uuidPrefab` property.

### What is the relationship between a prefab and its instances in Pyrite64?

Each prefab instance maintains a reference to its template through the `uuidPrefab` property, which stores the 64-bit UUID of the source prefab. When instantiated via `Scene::addPrefabInstance()`, the new object copies the transform data from the prefab's template object but receives its own unique 32-bit UUID for scene management. This architecture allows instances to override specific properties without modifying the shared prefab template, enabling both data reuse and per-instance customization.

### How does property overriding work in the Pyrite64 prefab system?

Property overriding utilizes the generic property system defined in [`src/utils/prop.h`](https://github.com/HailToDodongo/pyrite64/blob/main/src/utils/prop.h). When an instance overrides a property, it adds an entry to its internal override map (`<property-id → GenericValue>`), which shadows the prefab's default value during serialization and runtime. The `PROP_…` macros generate deterministic property IDs using `Utils::Hash::crc64(name)`, ensuring consistent identification across the engine. When `Scene::addPrefabInstance()` creates a new instance, it automatically establishes override entries for transform properties, allowing immediate editing of position, rotation, and scale.

### Where are prefab files stored and how are they loaded in Pyrite64?

Prefab definitions are serialized to JSON and saved to disk at `assets/<name>.prefab` via the `Prefab::save()` method in [`src/project/scene/prefab.cpp`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/scene/prefab.cpp). The `Prefab::serialize()` method writes the prefab's 64-bit UUID and the serialized template object data to JSON, while `deserialize()` restores these fields when loading. At runtime, `AssetManager::getPrefabByUUID()` in [`src/project/assetManager.h`](https://github.com/HailToDodongo/pyrite64/blob/main/src/project/assetManager.h) retrieves prefab instances from the asset table using their stable 64-bit UUIDs, enabling the scene to instantiate objects while maintaining the link to the original template.