Skip to content

Switched list iteration flow for GameObject rendering and updates#277

Open
huggyex64 wants to merge 2 commits into
ProwlEngine:New-Editor-UIfrom
huggyex64:Event-Manager
Open

Switched list iteration flow for GameObject rendering and updates#277
huggyex64 wants to merge 2 commits into
ProwlEngine:New-Editor-UIfrom
huggyex64:Event-Manager

Conversation

@huggyex64

@huggyex64 huggyex64 commented Jun 13, 2026

Copy link
Copy Markdown

Instead of iterating over all the active objects to gather the renderables, call updates, call fixedupdates, etc..., this implementation has the objects subscribed to an event manager that reduces the call overhead by a lot.
Among other notable improvements, there are:

  • guaranteed execution order
  • smaller memory footprint
  • overall performance benefits

Following are two small benchmarks ran with ~1800 gameobjects with 7 monobehaviour each, for a total of ~12600 monobehaviours. each with an Update that rotates the transform.
before:
Screenshot 2026-06-12 152111
after:
Screenshot 2026-06-12 150314

Introduce a full event subsystem (Prowl.Runtime.Events) with EventManager, Event<T>, delegate containers, diagnostics, attributes, and helpers; add an EventDomain source generator (Prowl.Runtime.Generators) and EquatableArray. Update core types to use scene event flow: SceneEvents, WindowEvents, GameEvents and generated accessors; change OnRenderCollect signatures to use SceneEvents.OnRenderCollectArgs and propagate renderable/light lists. Wire Game/Window/Scene/GameObject/MonoBehaviour to subscribe and dispatch events, execution order calculation, batching, and subscription management. Update project/solution files to include the generator project.
Replace DEBUG-guarded event diagnostics with EVENT_DEBUG to allow selective compilation of event diagnostics. Add allowMultiple parameter to EventAccessor.Subscribe overloads and propagate it through EventManager so multiple identical subscriptions can be allowed. Introduce Scene.MarkExecutionOrdersDirty and defer recalculation of execution/priorities to once-per-frame (SubscribeObjectsToEvents/RecalculateExecutionOrders) with batching around recalculation. Adjust GameObject/MonoBehaviour to mark scenes dirty when hierarchy/component changes and subscribe scene-level handlers with allowMultiple where needed. Misc: minor reorders to ensure consistent update/subscribe behavior.
@huggyex64 huggyex64 changed the title Nintendo Switched Switched Jun 13, 2026
@huggyex64 huggyex64 changed the title Switched Switched list iteration flow for GameObject rendering and updates Jun 13, 2026
@michaelsakharov

michaelsakharov commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

First off, thanks for taking the time to put this together

Ive gone through the PR, and I think the performance improvements are significant
The core idea of moving away from iterating over every GameObject each frame is absolutely in the direction I want the engine to go

That said, Im not convinced we need the full event framework to achieve it

If the main issue were trying to solve is avoiding full GameObject traversal every frame, I think the solution may be able to stay much simpler

For example, we could potentially maintain static collections of active components that participate in Update, FixedUpdate, rendering, etc, with components registering and unregistering themselves as they become active or inactive, based on whether those virtual methods have been overridden which could be cached per type

That would give us many of the same benefits:

  1. No full hierarchy scan each frame
  2. Only iterate components that actually participate (though less precise using a single collection, if needed we could do one collection per method)
  3. Minimal memory overhead
  4. Very little code (if the static lists go on MonoBehaviour or somewhere else we can avoid an additional supporting class)
  5. Easy to reason about and debug

The event system certainly works (in fact I think its quite clever could be a nice standalone Prowl library) but I also feel it pushes Prowl away from the KISS philosophy the project is built around
It introduces significantly more infrastructure than I think the engine needs for this particular problem

Would you be interested in exploring a simpler implementation focused specifically on update/render registration?
I'd love to hear your thoughts on that as well as any other paths/solutions you might have

Either way, I really appreciate the work that went into this PR
It helps validate that moving away from GameObject iteration is the right direction, and the performance gains here are valuable data for whatever final implementation we land on

@PaperPrototype

Copy link
Copy Markdown
Contributor

My suggestion for this PR is: make it do the LEAST amount possible needed for GameObject components to subscribe to events, and thats it. This PR looks like an entire Event system package. As an example of what Wulferis means by "KISS" (Keep it simple stupid) the EditorAssetDatabase is at most 5 scripts in total.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants