3 min read
When “Just Data” Quietly Turns Into Code

Modern games and apps love being data-driven. Items live in JSON. Enemies come from spreadsheets. Dialog is authored in YAML. At first, this feels safe: data isn’t code, right?

But here’s the uncomfortable truth:

The moment data starts deciding what happens, it’s behaving like code.

And that shift often happens without anyone explicitly choosing it!


The slippery slope

Most projects move along this path:

  1. Static data
player:
    hp: 100
    speed: 3.5
  1. Parameterized behavior Code defines logic, data tweaks the numbers.
  2. Rule-driven behavior Data starts choosing which logic runs and when.

That third step is where things get interesting — and risky!


A tiny example: data that behaves like logic

This looks harmless:

effects:
  - type: "heal"
    amount: 25

But once you add conditions…

effects:
  - type: "if"
    cond:
      let:
        - "player.hp"
        - 30
      then:
        - type: "heal"
          amount: 40
      else:
        - type: "heal"
          amount: 10

…you’ve crossed a line.

This asset now contains:

  • branching
  • state inspection
  • ordered execution

That’s not just data anymore. That’s a mini behavior script!


Why teams do this anyway

Because it’s powerful.

  • Designers can iterate without engineers
  • Balance changes don’t require code builds
  • Live updates and hotfixes get easier
  • Modding becomes possible

These are real wins. The problem isn’t doing it — it’s doing it by accident!


The hidden cost of “data as code”

Once assets control behavior, you inherit all the problems of code:

  • Debugging: “Why did this trigger?”
  • Validation: malformed data can crash logic
  • Versioning: old assets break new runtimes
  • Tooling: editors, schemas, tests become mandatory

If you don’t plan for this, complexity sneaks up fast!


A simple rule of thumb

If your data can:

  • branch (if / else)
  • reference runtime state
  • apply ordered effects
  • choose behaviors

Treat it like code!

That means:

  • strict schemas
  • clear error messages
  • versioned formats
  • limited, well-defined “instructions”

The takeaway

“Data-driven” doesn’t mean “safe by default.”

The moment your assets decide what happens next, you’re no longer just shipping data — you’re shipping behavior. And behavior deserves the same care, tooling, and respect as code.

If you design for that upfront, data-driven systems become a superpower instead of a slow-burn bug factory.