Skip to content

BredaUniversityGames/reflection-and-serizalization

Repository files navigation

Reflection & Serialization Examples

Educational examples demonstrating C++ reflection and serialization techniques for game engines, based on the "Reflection & Serialization" lecture.

Overview

This project demonstrates various approaches to reflection and serialization in C++ game engines, from basic RTTI to advanced meta-programming systems. Each example is self-contained and progressively builds understanding of how modern game engines achieve data-driven design.

Project Structure

reflection-examples/
├── CMakeLists.txt              # Root build configuration
├── README.md                   # This file
├── common/                     # Shared types and utilities
│   ├── types.hpp              # Vector3, Quaternion, Transform
│   └── json_helpers.hpp       # JSON serialization for common types
└── examples/                   # Individual examples
    ├── 01_basic_rtti/         # C++ built-in RTTI
    ├── 02_visit_struct/       # Macro-based reflection
    ├── 03_entt_meta/          # EnTT meta system
    ├── 04_entt_snapshots/     # ECS serialization
    ├── 05_generic_serialization/  # Engine/game separation ⭐
    ├── 06_cereal_serialization/   # Serialization-only library
    ├── 08_lua_integration/    # Lua scripting integration
    └── 09_wren_integration/   # Wren scripting integration

Building

Prerequisites

  • CMake 3.20 or later
  • C++20 compatible compiler (GCC 10+, Clang 11+, MSVC 2019+)

Build Instructions

# Create build directory
mkdir build && cd build

# Configure
cmake ..

# Build all examples
cmake --build .

# Or build specific example
cmake --build . --target 03_entt_meta

Running Examples

From the build directory:

# Windows
.\examples\01_basic_rtti\01_basic_rtti.exe

# Linux/Mac
./examples/01_basic_rtti/01_basic_rtti

Or use CMake to build and run:

cmake --build . --target 03_entt_meta && ./examples/03_entt_meta/03_entt_meta

Examples Overview

1. Basic RTTI (01_basic_rtti)

What it demonstrates: C++'s built-in Runtime Type Information

  • Using typeid and std::type_info
  • Type comparison and name retrieval
  • Limitations: No member iteration, no introspection
  • Why RTTI is insufficient for game engines

Key takeaway: RTTI provides minimal type info; game engines need full reflection.

2. visit-struct (02_visit_struct)

What it demonstrates: Macro-based reflection system

  • VISITABLE_STRUCT macro for member registration
  • Iterating over struct members with visit_struct::for_each
  • Generic serialization to/from JSON
  • Simple and lightweight approach

Key takeaway: Macros enable reflection, but require listing members twice.

3. EnTT Meta (03_entt_meta)

What it demonstrates: EnTT's powerful meta reflection system

  • Runtime type registration with entt::meta<T>()
  • Dynamic member access without compile-time type knowledge
  • Iterating all registered types and their members
  • Foundation for generic engine code

Key takeaway: Meta systems enable runtime introspection and manipulation.

4. EnTT Snapshots (04_entt_snapshots)

What it demonstrates: Proper ECS serialization

  • entt::snapshot for saving registry state
  • entt::continuous_loader for restoring state
  • Binary archive adapters
  • Preserving entity IDs and component data

Key takeaway: EnTT provides dedicated serialization, but must specify component types.

5. Generic Serialization ⭐ (05_generic_serialization)

What it demonstrates: Engine/game separation pattern (MOST IMPORTANT!)

  • engine.hpp: Generic code that serializes ANY registered component type
  • game_components.hpp: Game-specific components (PlayerController, EnemyAI, etc.)
  • main.cpp: Demonstrates complete separation and includes console property inspector
  • Engine serializes components it doesn't know about at compile time!

Key takeaway: This is how real game engines work! Add new components without recompiling the engine.

Special feature: Interactive console-based property inspector demonstrating editor functionality.

6. Cereal (06_cereal_serialization)

What it demonstrates: Serialization WITHOUT reflection

  • JSON and binary serialization with Cereal library
  • Clear demonstration that Cereal is NOT reflection
  • Comparison: what Cereal can and cannot do
  • Why game engines need true reflection systems

Key takeaway: Cereal is great for simple save/load, but can't build editor UI or expose to scripting.

8. Lua Integration (08_lua_integration)

What it demonstrates: Scripting language integration via reflection

  • Binding C++ types to Lua using Sol3
  • Creating and modifying C++ objects from Lua scripts
  • Calling C++ methods from Lua
  • Reading Lua-modified data back in C++
  • Implementing game logic in Lua

Key takeaway: Reflection enables exposing C++ to scripting languages for runtime-modifiable game logic.

9. Wren Integration (09_wren_integration)

What it demonstrates: Lightweight scripting alternative

  • Binding C++ types to Wren using foreign class API
  • Similar integration pattern to Lua
  • Comparing Wren vs Lua for game scripting
  • Multiple scripting language support

Key takeaway: Same reflection system can power different scripting languages - choice depends on project needs.

Dependencies

All dependencies are automatically downloaded via CMake FetchContent:

  • EnTT (v3.12.2) - Entity Component System with meta reflection
  • nlohmann/json (v3.11.3) - JSON serialization
  • visit-struct (v1.1.0) - Macro-based struct reflection
  • cereal (v1.3.2) - Serialization library
  • Sol3 (v3.3.0) - Modern C++ Lua binding library
  • Lua (5.4.6) - Scripting language
  • Wren (latest) - Lightweight scripting language

Key Concepts

Reflection vs Serialization

Reflection: Runtime introspection and manipulation of types

  • List member names and types
  • Get/set member values dynamically
  • Iterate all registered types
  • Build editor UI, scripting integration

Serialization: Converting objects to/from storable format

  • Save to file (JSON, binary, XML)
  • Load from file
  • Network transmission

Key insight: Serialization is a subset of reflection! Full reflection enables serialization PLUS much more.

Engine/Game Separation

Modern game engines achieve data-driven design through reflection:

  1. Game registers types at startup with meta system
  2. Engine works generically without knowing types at compile time
  3. Add new components without recompiling engine
  4. Same system powers:
    • Serialization (save/load) - Examples 5, 6
    • Editor UI (property inspectors) - Example 5
    • Scripting (expose C++ to Lua/Wren) - Examples 8, 9
    • Networking (component replication)

See Example 5 for engine/game separation and Examples 8-9 for scripting integration!

Real-World Applications

These techniques are used in:

  • Unity: C# reflection (built-in)
  • Unreal Engine: UHT (Unreal Header Tool) code generation
  • Godot: GDScript property system
  • Custom Engines: EnTT meta, rttr, Ponder

Learning Path

Recommended order:

  1. Start with Example 1 - Understand RTTI limitations
  2. Example 2 - See how macros enable reflection
  3. Example 3 - Learn EnTT meta basics
  4. Example 4 - Understand ECS serialization
  5. Example 5 ⭐ - Master engine/game separation (THE MOST IMPORTANT!)
  6. Example 6 - Understand serialization vs reflection
  7. Example 8 - See reflection enable Lua scripting integration
  8. Example 9 - Compare with Wren for scripting alternatives

Note: Example 7 (RTTR) was skipped as it requires complex setup. Examples 8-9 demonstrate the same core concepts using EnTT meta.

Common Issues

Build Errors

If you encounter build errors:

  1. Ensure C++20 is supported by your compiler
  2. Update CMake to 3.20 or later
  3. Check that FetchContent can access GitHub (firewall/proxy issues)

Missing Dependencies

All dependencies are downloaded automatically. If FetchContent fails:

# Clean build directory and retry
rm -rf build
mkdir build && cd build
cmake ..

Further Reading

License

This educational project is provided as-is for learning purposes.

Contributing

This is an educational project. Feel free to use and modify for learning!


Happy Learning! 🎮

Master these patterns and you'll understand how modern game engines achieve data-driven design!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors