For games driven by events. How to create an appropriate system to generate/process events? Normally, I will create an EventSystem to provide interfaces for registering listeners and firing events. When an event is fired, callbacks listening to the event will be called immediately.
It’s fine in OO, but it might not good in ECS because invoking a callback when an event happens means that memory from anywhere could be loaded and cause cache misses.
Are there some good approaches to implement an event system? Thanks in advance.
In rough implementation. When event must fired, attach component data with event args to entity, then system will be inject this entity, and in system update loop do stuff and remove component data from entity after all.
Or instead of attaching to existing entity create a new empty entity with event component data (no data inside, or maybe some event arguments inside). The system looking for it will run and only once if you properly destroying that entity after all is done. The advantage is you can do this easily from inside the job via EntityCommandBuffer. (It might be difficult to reference existing entities from inside the job)
It’s two different event types, I think. If you need send some event with some abstract data, epidemy in city for example, is a good way, but many times you need to now who send event, or on who fired event in this case existing entities more usable, because you use them for transfer event data IMO. Anyway booth examples can be useful.
That reminds me of a built in attribute [RequireComponentTag] for IJobProcessComponentData that Unity officially define the term “component tag”. So yet another way maybe try to use tags for events but you cannot remove a tag inside the job as it does not give you an entity, so maybe create an another system that run at the end of frame to clean up all events if you only want it run once. (You do not get to access the data in those tags but you can specify more than generic parameter limit)
The Reactive Systems that are coming should be helpful with this. They will allow systems to process “events” when components are added, removed and filter to only process changed components.
That way you should be able to add an event component with data and have a system handle it right then and remove it again. Alternatively just have a component for the event permanently on the Entity and just add event data to it and process it when it changes.
They are also working on array support for IComponentData so you can have multiple events per component.
adding and removing component data a lot will be a hit in performance. I am pulling this out of my ass a little bit though.
My reasoning is that if you want to keep memory tightly packed, then adding removing a little means that you are shifting a lot of stuff around.
if your component data had an enabled disabled state as well. so when the system that run it can check for it, you would reduce allocation/deallocation and still have good control over it.
I am absolutely not sure about anything i just said but i will probably go and test this out in the near future as it is interesting to me as well. Obviously though i am trying to approach theoretically what happens when events scale up
EDIT: i just saw the berlin talk from joachim and reactive systems seem to be exactly what is being discussed. its very event oriented in philosophy
I’m afraid that won’t be sufficient. If an event callback triggers other events and you want the entire even chain happen in one frame, you would want to run the same system multiple times in the same frame until all EventData is consumed.