Posted in

How to use a Reducer with Unity in a game development application?

If you’re a game dev working in Unity, you’ve probably run into that mess of messy code where your player’s health, inventory, and quest states all get updated haphazardly—one script overriding another, race conditions popping up in multiplayer, and debugging a wrong health value feels like looking for a needle in a haystack. Let me cut to the chase: I’m the founder of a Reducer company that’s spent three years building Reducer tools tailored specifically for Unity game devs, and I’ve helped teams of 2-person indie studios and 100-person AAA studios fix exactly that kind of chaos. This blog is the plain-English, no-fluff guide to actually using a Reducer in Unity for your game, with real-world wins you’ll see in week one. Reducer

First, let’s skip the textbook definition that makes Reducers sound like rocket science. A Reducer is just a pure function that takes two things: your game’s current state (like a snapshot of where your player is, how much gold they have, and whether they completed the goblin quest) and an action (a plain object that says what changed—“player took 15 damage,” “looted 20 gold,” “quest X completed”). It spits out a brand new state, no side effects, no surprises. In Unity terms, that’s way better than having every single GameObject script reach into a global variable and change it whenever they feel like it.

I’ve seen so many devs write off Reducers because they tried adapting a vanilla JavaScript or React Reducer to Unity, and it felt clunky. Unity’s C# is statically typed, has its own event system, and your game’s runtime needs to handle things like coroutines, network sync, and Unity’s lifecycle events—so you can’t just copy-paste code. That’s why our team built a Unity-specific Reducer integration that plays nice with MonoBehaviours, GameObjects, and even Unity’s Event System, no weird hacks.

Let’s start with the basics: what your game state actually looks like in Unity. First, you don’t want to just make a one-size-fits-all global state that’s 50 fields long. Break it into slices—each slice is a self-contained part of your game, so you can update just one without touching the rest. For a 2D platformer, that might look like this:

  • PlayerState: health, current ammo, active power-up, position (we’ll get to if you need position in the Reducer later)
  • InventoryState: total gold, list of items, equipped weapon
  • QuestState: active quests, completed quests, quest progress
  • UISTate: current screen (main menu, pause, gameplay), active notification text

Each slice is a C# class with getters, no setters—because the Reducer is the only one allowed to change state. That’s a non-negotiable rule I enforce with every team I work with. If a script can just do playerState.health = 50; directly, you’ll end up with that chaos I mentioned earlier. The Reducer is the single source of truth for state changes.

Now, writing your first Reducer. Let’s take the PlayerState slice as an example. This is a C# class that inherits from our Unity Reducer base class (we built that to handle Unity’s MonoBehaviour lifecycle hooks, so you don’t have to wire up every coroutine manually).

Wait, let’s make it concrete. Let’s say you have an action called TakeDamageAction. It has a damageAmount field, and it’s triggered when the player collides with an enemy’s attack. Your PlayerState Reducer would handle that action like this:

When the Reducer receives an action, it checks what type it is. If it’s TakeDamageAction, it creates a new PlayerState, copies all the old values over, subtracts the damageAmount from health, and makes sure health can’t go below 0. If it’s a PowerUpAppliedAction, it updates the active power-up and maybe adds a temporary speed boost value. No modifications to the old state—pure function, no side effects.

Why does this work so much better than Unity’s default approach? Let’s say two enemies attack the player at almost the same frame. Without a Reducer, both scripts would reach into the player’s health variable, subtract damage, and you might end up with a health value that’s wrong because of a race condition (like both subtracting 10 from 100 and getting 80 instead of 90). With a Reducer, each action is processed in order, one after the other, so there’s no race condition. It’s deterministic—you can replay the same sequence of actions and get the same state every time, which is a godsend for debugging or rolling back a bug.

Now, integrating this with Unity’s lifecycle. Here’s where I see most devs mess up: they write the Reducer, but don’t connect it to Unity’s events, so nothing actually updates the game objects on screen. Let’s walk through that step.

First, you set up a Store in your Unity project. The Store is the single object that holds all your state slices and handles dispatching actions to the right Reducers. You can have one Store for your entire game, or split it into multiple Stores for different scenes (we recommend one main Store for most games, even open-world ones).

In Unity, you’ll have a Store MonoBehaviour that you attach to an empty GameObject in your initial scene. This MonoBehaviour subscribes to Unity’s Update, FixedUpdate, and OnTriggerEnter events, so it can listen for things like “player collided with enemy” and dispatch the corresponding action to the Reducer.

When the Store dispatches an action, the relevant Reducer runs, outputs a new state, and the Store emits a “state changed” event. Your MonoBehaviour scripts—like the PlayerHealth script, Inventory UI script, and Quest Log script—all subscribe to that event. So when the state updates, they pull the new value from the Store and update the GameObject’s display automatically. No more manual code that says “if health changes, update the UI”—it just happens.

Let’s test this with a real example. Let’s say your player picks up a gold coin. The coin’s OnTriggerEnter2D method detects the player, gets the amount of gold in the coin, and dispatches an AddGoldAction with a value of 20. The InventoryState Reducer hears this action, makes a new InventoryState, adds 20 to gold, and spits it out. The Store emits a state changed event, so your GoldCounter UI script grabs the new gold value and updates the text from “100” to “120.” That’s it—no typos, no missed updates, because the Reducer is the only one modifying the inventory state.

Now, common pitfalls to avoid. I’ve seen every single one of these, so trust me on this:

  1. Don’t put Unity-specific logic inside your Reducer. The Reducer should only handle state updates, not spawning GameObjects, playing audio, or moving transforms. Those are side effects, and they belong in your MonoBehaviour scripts that subscribe to the Store’s state change events. If you put Instantiate() inside a Reducer, you’ll get duplicate objects and Unity runtime errors because Reducers are pure functions—they shouldn’t interact with the Unity scene directly.

  2. Don’t store runtime values that change every frame in your Reducer state. I see devs put transform.position, velocity, or rotation in the state, and that’s a mistake. Those values update every single frame, so you’ll be processing thousands of unnecessary actions, which bogs down your game. For dynamic values that need to be synced, use Unity’s network sync (if it’s a multiplayer game) or let the MonoBehaviour handle them. The Reducer is for discrete, state changes—like when the player moves to a new area, not where they are every frame.

  3. Don’t ignore actions that aren’t handled. If you dispatch an action and no Reducer handles it, the Store will throw a warning. That’s a good thing—instead of your game silently ignoring a coin pick-up, you’ll get a log that says “AddGoldAction not handled, check your Reducer.” It takes 5 minutes to add a case for each action, and it saves you hours of debugging.

  4. Don’t make your state too big. If your main state class has 30 fields, it’s hard to debug and slow. Split it into slices, like we talked about earlier. That way, if you only need to update the player’s health, you don’t reprocess the entire state. Our Unity Reducer tools automatically optimize slice updates, so you only process the relevant part, which keeps your game fast even for large open worlds.

Now, what about multiplayer? That’s a big one for game devs. If you’re making a multiplayer game, state sync is a nightmare. With a Reducer, you can serialize each action and send it over the network—instead of sending the entire state every time, you send just the action that caused the change. That cuts down on network bandwidth, which is crucial for fast-paced games. Our Reducer for Unity has built-in support for Unity Netcode for GameObjects (Netcode), so you can dispatch actions on the server, the Reducer updates the server state, and the new state is synced to all clients automatically. No more out-of-sync player states or desync bugs that happen when two clients modify the same value at the same time.

Let’s talk about debugging, because that’s the biggest win for most teams. With a Reducer, you can log every single action and state change. You can replay a sequence of actions and see exactly when a health value went wrong. For example, if your player has 50 health and suddenly drops to 0, you can look at the action log: “EnemyAttackAction (10 damage) → PlayerTookDamage (5 damage) → EnemyAttackAction (10 damage)” and see that you accidentally added an extra damage action. No more digging through 20 different scripts to find where the mistake happened. Our Unity Reducer tools include a built-in state inspector, so you can see the current state of any slice in the editor, step through actions one by one, and even roll back to a previous state if a bug slips through.

Now, let’s talk about when you don’t need a Reducer. If you’re making a tiny 2D game with 3 scripts total—player, UI, and a couple enemies—you probably don’t need it. The setup time for a Reducer might not be worth it. But if your game has:

  • More than 10 state variables that change
  • Multiplayer functionality
  • Complex quests or inventory systems
  • Frequent bugs where state is inconsistent
  • A team of 3+ devs working on the same codebase

That’s when a Reducer will save you months of headaches. I’ve had indie devs come to me after spending 6 months fixing state bugs, and they switched to a Reducer and cut their bug fixing time in half within a month.

Let’s wrap this up with a step-by-step to get started today:

  1. Reach out to talk through your game’s specific needs (I’m here to answer questions, no sales pitch—just dev to dev).
  2. Implement the core state slices for your game, split by feature (player, inventory, quests).
  3. Write your Reducers for each slice, making sure they’re pure functions with no side effects.
  4. Set up the Store MonoBehaviour in your initial scene, connect it to Unity’s lifecycle events.
  5. Update your existing MonoBehaviour scripts to subscribe to the Store’s state changed event, instead of modifying state directly.
  6. Test with a simple action first—like picking up a coin—and watch the UI update automatically.

If you’re tired of messy state code, race conditions that pop up mid-playtest, and debugging sessions that drag on for hours, a Reducer built for Unity is exactly what you need. Don’t let the initial setup scare you—our team provides custom integration support for Unity projects, so we can walk you through every step, adjust the Reducer to fit your game’s unique needs, and make sure it works with your existing tools (Unity UI, Netcode, addressables, whatever you’re using).

Don’t waste another week chasing state bugs in your Unity project. Reach out to start a conversation about integrating a Unity-optimized Reducer into your game development workflow. We’d love to hear what you’re building and help make your state management as smooth as your gameplay.

Pipe Elbow References:

  • Unity User Manual: State Management
  • Redux Documentation: Principles of Reducers
  • Unity Netcode for GameObjects Documentation: Network State Sync
  • Game Development Patterns: Single Source of Truth for Game State

Hebei Haihao Group Huadian High Pressure Pipe Fittings Co., Ltd.
As one of the most professional reducer manufacturers and suppliers in China, we are able to meet the needs of the majority of our customers. Please rest assured to wholesale high quality reducer made in China here from our factory. For price consultation, contact us.
Address: Donglin Industrial Zone, Mengcun County, Cangzhou City, Hebei Province, China
E-mail: haihaohuadian@outlook.com
WebSite: https://www.hhfittings.com/