Runtime Reflection

Runtime Reflection enables the engine to inspect and modify type information at runtime, powering editor tools, serialization, and data-driven systems without compile-time coupling.

Overview

This page breaks down the design and implementation of a custom runtime reflection system in C++.

The system allows engine and gameplay types to be inspected and modified at runtime, enabling generic tooling without explicit per-type integration.

Core Idea

The goal is to expose component and engine data to tools such as the editor without requiring compile-time knowledge of their structure.

Design Goals

  • Remove compile-time coupling between engine and tools
  • Enable automatic inspection of all reflected types
  • Support serialization and editor integration

Concept

Each type registers metadata describing its fields, including name, type, and memory offset. This metadata is stored in a central registry and used by engine systems at runtime.

Design

The reflection system is built around a global type registry that stores metadata for all registered types. Each type defines its fields during a registration step executed at startup.

Type Metadata

  • Type name
  • Field definitions
  • Memory offsets
  • Type size information

Registry System

The registry acts as a lookup database that allows tools and runtime systems to query and interact with types generically.

Evolution of the System

The initial implementation used templated field wrappers to preserve compile-time type safety. While this worked for early prototypes, it quickly became restrictive for tooling and serialization.

The system was later redesigned to use a metadata-driven approach based on memory offsets, allowing fully generic runtime access without compile-time dependencies.

Initial Approach (Templates)

  • Compile-time typed field wrappers
  • Strong coupling to C++ types
  • Poor serialization flexibility

Final Approach (Offsets)

  • Runtime metadata representation
  • Field access via memory offsets
  • Fully decoupled tooling system

Use Cases

Editor Integration

Automatically generates inspectors for any reflected type, enabling real-time editing of components without custom UI code.

Serialization

Enables generic save/load systems by iterating over metadata instead of hardcoded fields.