Events and delegates look clean in C#. That does not mean they are cheap. If you register listeners carelessly, or rebuild gameplay data every update, you are quietly feeding the GC and buying hitch risk you do not need.
This module gives you three practical fixes. First, cache your actions instead of asking C# to build delegates over and over. In the lesson, that simple change drops the sample from roughly 432 bytes of allocs to about 176 bytes. That is not theory. It is the first quick win.

Second, if your event flow is still too loose, stop improvising and move to a custom event manager with reusable event objects. That gives you the ergonomic part of events without paying the usual per-event garbage bill every time you fire gameplay data through the system.
Third, stop deserializing like you own infinite frame time. If you already have the object in memory, do not rebuild it from scratch just because new JSON arrived. The lesson shows why FromJsonOverwrite is a useful first move, and why manual field-level parsing can take recurring allocs all the way down to zero when you only care about a few values.

Start here: profile your event registration path and your deserialization path separately. If you see delegate combine/remove work, cache the action in Awake. If you see JSON turning into fresh objects every time, test FromJsonOverwrite before you reach for something more elaborate.
Brutal reality check: clean architecture can still be a hidden GC machine. Nice code that allocates in the wrong place is still bad code.
CEO/Producer translation: this is how you remove tiny scripting leaks before they pile up into frame-pacing noise, QA churn, and late optimization work.
The members-only module is the full step-by-step playbook: cached delegates, the custom event manager implementation, the JSON overwrite workflow, the lower-level manual parsing route, and the tradeoffs that tell you which fix is worth it in your project.
In this module:
Join to unlock the full module, audio, and resources.