logo80lv
Articlesclick_arrow
Talentsclick_arrow
Events
Workshops
Aboutclick_arrow
profile_login
Log in
0
Save
Copy Link
Share

Building Scaleable Data-Driven Gameplay Architecture In UE5 Using C++

Chukwuyenum Opone shared how he built a modular platform system for rhythm platformer Meowsic using World Subsystems and Data Assets, replacing actor-heavy Blueprint workflows to improve scalability and speed up development.

Meowsic

Introduction

Have you ever shipped a game jam prototype and realized it doesn't scale? That was us with Meowsic.

During the GMTK Game Jam 2025, we built a rhythm-puzzle game where you play as a cat on a Digital Audio Workstation. This is Meowsic. A genre-bending rhythm platformer where the platforms are your audio loops. Four days, one level, shipped successfully. The community loved it. But then we decided to make it a full commercial game for Steam with 2-5+ levels and dozens of platform variations. That's when our jam-era architecture fell apart.

Our original approach was simple: individual platform actors, manually configured, managed by a central coordinator. For a game jam prototype, it worked perfectly. But when we planned multiple levels with platform variants, iteration became agonizingly slow. Designers couldn't experiment. I spent hours managing consistency instead of building features. Changing one platform property meant updating 40+ actors.

I needed a fundamentally different approach: one that separated data from behavior, let configuration changes ripple instantly across all instances, and reduced production friction instead of amplifying it.

The solution is the Layered Gameplay Systems Model, an architectural pattern that decomposes any gameplay system into five distinct layers, each with a specific responsibility. It's not specific to platforms or Meowsic. Any system with data, rules, and multiple instances can benefit from this approach.

The Problem: Why It Broke Down

The Consistency Problem

Imagine 40 platform actors split across 7 variants. Each has properties for movement behavior, audio, materials, mesh type, and more. You realize the max Z-height is wrong, it's 500 when it should be 800. You update one actor, test it, and it feels good.

But what about the other 6? Did you update them? How do you know they're consistent? In a manual workflow, you don't. You either update every single actor (tedious and error-prone), hope you caught them all (bad idea), or create visual inconsistencies that break player expectations (worse).

The Iteration Problem

Designers wanted to experiment. "What if platforms move higher? What if they change color when stepped on? What if audio plays at different pitches?"

Each experiment meant:

  1. Create a new property in PlatformActor;
  2. Place 7 platform copies in a test level;
  3. Configure each one individually;
  4. Test the behavior;
  5. If it didn't work, delete all 7 and start over.

One iteration cycle took 30+ minutes. Designers stopped experimenting. Iteration velocity collapsed.

The Performance and Duplication Problem

Each platform was a full AActor in memory. For 2-5 levels with 50 platforms per level, that's 100-250+ instances. Each carried identical properties and logic, the same movement speed, audio cues, and rules stored 250 times.

Level load times climbed to 5-10 seconds. And we had massive code duplication with little flexibility. The core problem: Configuration and behavior were tightly coupled. Every change meant changing many places.

The Solution: Separating Data from Behavior

The Core Insight

What if we inverted the architecture?

Instead of:

Actor [Config + Behavior]... × 250

We could have:

DataAsset [Config]
    ↓ references
Actor [Behavior only]... × 250

Now all 250 actors reference the same configuration. Change the data once, and every actor updates instantly. No duplication. No inconsistency. No busywork. 

The Layered Gameplay Systems Model

To implement this cleanly, I developed a pattern: five distinct layers, each with a specific responsibility.

Layer 1: Representation - Where does configuration live?

Answer: UPlatformDataDefinition (a custom DataAsset). Single source of truth, reusable, hotloadable.

Layer 2: Transformation - How do we convert stored data to runtime values?

Answer: PlatformSubsystem reads the DataAsset and calculates runtime-specific values. Clamps ranges, performs calculations, and combines properties.

Layer 3: Validation - What rules do platforms follow?

Answer: Subsystem enforces constraints. Min/max positions, view-based manipulation, and collision checks.

Layer 4: Orchestration - Who manages everything?

Answer: PlatformSubsystem is the single authority. Tracks instances, applies logic, enforces rules, responds to events, and keeps everything synchronized.

Layer 5: Interface - How do designers interact?

Answer: Blueprint Function Library (Platform API). Designers call clean functions without understanding subsystems or validation logic.

Each layer is independent. Change one without breaking others. Information flows upward; orchestration flows downward.

The Implementation

The beauty of this approach is simplicity.

Platform Actor becomes a thin wrapper: That's it. The actor references a DataDefinition, registers with the subsystem, and receives state from it. No properties duplicated across 250 instances. No configuration logic. Just a thin wrapper.

Platform Data Definition defines and manages how data is represented in Data Assets.

PlatformSubsystem becomes the heart:

  • Tracks all platform instances;
  • Calculates Platform state from DataAssets;
  • Validates interactions;
  • Reads the DataAsset and calculates runtime-specific values;
  • Responds to gameplay events;
  • Keeps everything synchronized.

PlatformLibrary exposes the API:

  • "Get all platforms";
  • "Get Moveable platforms";
  • "Set platform data";
  • "Register Platform".

Designers use these functions in Blueprints without touching C++.

The Results

The main platform class was reduced from more than 300 lines to just over 100 lines, representing a 67% decrease in size. Platform-specific logic that was previously duplicated was centralized into a single system.

This shift to a data-driven workflow also had a major impact on production efficiency. Tasks that previously required more than 30 minutes, like updating platform properties across an entire project, can now be completed in just 2-3 minutes. Creating a new platform type, which once took over 20 minutes, now takes only 3-5 minutes. Consistency issues that previously required 1-2 hours of debugging have been eliminated with automation. Also, level load times improved dramatically, dropping from 5-10 seconds to around half a second.

Designer Experience

Before: "What if platforms go higher?" – 45 minutes of setup – "Let's not try it"

After: "What if platforms go higher?" - Create Gameplay Tag, link to Platform Data Struct, configure, test - "Let's try 10 variations and pick the best"

Iteration velocity changed. Creativity increased. That's the real win.

When to Use This Pattern

This pattern works for any gameplay system with:

  • Data (configuration that controls behavior);
  • Rules (validation and constraints);
  • Instances (multiple copies of the same thing).

Examples:

  • Loot drops: Drop rates, rarity, quantities across 1000s of instances;
  • Enemy types: Stats, AI behavior, balance rules across 50+ enemies per level;
  • Dialogue trees: Branching logic across 100s of nodes;
  • Audio systems: Parameters and cues across 1000s of sound sources.

Ask yourself: Do I have 10+ instances sharing a configuration? Is iteration slow? Are consistency bugs common? If yes to 3+, use this pattern.

Final Thoughts

The best architecture isn't the one with the most abstraction. It's the one that removes friction between intent and execution.

When a designer thinks, "I want platforms to move 4 steps higher," and they can execute that in 10 minutes instead of 2 hours, something fundamental has changed. They're no longer constrained by implementation details. They're free to create.

That freedom compounds. Iteration builds on iteration. Experimentation leads to discovery. Discovery leads to unique gameplay that only your team could have built.

For Meowsic, this architecture helped me find the fun in data. And then keep finding it.

Start small with one painful system. Build one subsystem following these five layers. Measure the results. Expand when you see it works. The pattern scales from one system to dozens. The payoff isn't just cleaner code or faster iteration. It's the ability to experiment fearlessly, to keep trying variations until you find something magical. That's worth building for.

Chukwuyenum Opone, Gameplay Programmer

Built for Creators. Read by the Best
Partner with 80 Level

Comments

0

arrow
Type your comment here
Leave Comment
Built for Creators. Read by the Best
Partner with 80 Level

We need your consent

We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more