Skip to main content

4 posts tagged with "Best Practices"

Development best practices and tips

View All Tags

Cross-Scene Events: The Persistence Problem Nobody Talks About

TinyGiants
GES Creator & Unity Games & Tools Developer

Your AudioManager plays background music. It subscribes to OnLevelStart to change tracks when the player enters a new area. You put the AudioManager on a DontDestroyOnLoad object so it persists across scene loads. Everything works during development because you're always testing in the same scene.

Then someone loads Level 2 from Level 1 for the first time. The music stops changing. The AudioManager is still alive — DontDestroyOnLoad did its job — but the event subscription didn't survive the transition. Or worse: the OLD subscription is still there, pointing at the destroyed Level 1 version of the event raiser, and the next time something tries to invoke it you get a MissingReferenceException in the middle of gameplay.

This is the persistence problem, and every Unity project with more than one scene hits it eventually.

Event System Pitfalls: Memory Leaks, Data Pollution, and Recursive Traps That Ship in Production

TinyGiants
GES Creator & Unity Games & Tools Developer

You've been testing your game for 5 minutes at a time. It runs great. Then QA files a report: "Memory usage grows steadily over a 30-minute play session. Frame rate degrades from 60 to 40 after loading 6 scenes." You profile it. There are 847 listeners registered to an event that should have 12. Each scene load added new subscriptions but never removed the old ones. The objects were destroyed, but their delegate references live on, pinning dead MonoBehaviours in memory where the garbage collector can't touch them.

Or this one: "Health values are wrong on the second Play Mode session. First run works fine." You hit Play, test combat, stop. Hit Play again. The player starts with 73 HP instead of 100. ScriptableObject state from the last session bled through because nobody reset it.

Or the classic: the game hangs for 3 seconds, then Unity crashes. Event A's listener raised Event B. Event B's listener raised Event A. Stack overflow. Except sometimes it doesn't crash — it just hangs, eating CPU in an infinite loop that produces no visible error.

These aren't hypothetical. These are bugs I've seen ship in production games. And they all have the same root cause: event system patterns that look correct in isolation but fail at scale.

Execution Order Bugs: The Hidden Danger of 'Who Responds First' in Event-Driven Systems

TinyGiants
GES Creator & Unity Games & Tools Developer

The player takes 25 damage. The health system subtracts it from the current HP. The UI updates the health bar. Except the health bar shows 100 instead of 75. You stare at your code for 20 minutes before you realize: the UI listener executed BEFORE the health system listener. The UI read the old HP value, rendered it, and then the health system updated. By the time the data was correct, the frame was already drawn.

You've just discovered execution order bugs, and if you've shipped anything with event-driven architecture, you've probably shipped a few of these without knowing it. They're the kind of bug that works fine in testing because your scripts happened to initialize in the right order, then breaks in production because Unity decided to load things differently.

This isn't a rare edge case. It's a structural flaw in how most event systems work — including Unity's UnityEvent and standard C# event delegates. And once you understand why, you can't unsee it.

200 Events and Counting: Why Event Organization Breaks Down and How to Fix It

TinyGiants
GES Creator & Unity Games & Tools Developer

You start a new Unity project. You create ten events. OnPlayerDeath, OnScoreChanged, OnLevelComplete. You name them sensibly, drop them in a folder, and move on. Life is good. You can hold the entire event structure in your head.

Fast forward six months. You've got 200 events. The Project window is a wall of ScriptableObject files. You need OnPlayerHealthDepleted — or was it OnPlayerHPLow? Or OnPlayerHealthZero? You scroll through the list, squinting at names that all start with OnPlayer. After three minutes you give up and create a new one because you're not even sure if the event you want already exists.

This is where every event-driven Unity project lands eventually. And it's not because the event pattern is wrong — it's because nobody built the tooling for managing events at scale. Unity gives you the Animation window, Shader Graph, Timeline, the Input System debugger. Events get... the Project window.