Yes. It works very well.
Let’s assume that you are already applying SOLID, TDD, CI, clean architecture, and you create cohesive software at a class and module level.
What do events get you?
They enable you to decouple the interactions between all the different systems in a game engine: sound, animation, character entities, etc.
They also enable you to send future messages. This is tremendously powerful.
Originally, object oriented programming was inspired by biological cells. OO entailed creating objects that sent messages to each other. Events are a loosely coupled way of enabling this. I apply it at the module level between bigger systems, not between everything. So I define clear boundaries, and boundaries are crossed with events. They let you abstract the sender and receiver from the message. So the idea of a future event can be reused across any message between any two objects. AI and players can “use” the system the same way. Display and business logic are completely separated. It’s easy to connect customized events, like a sound on a certain animation.
You will get control flow that is more complex. However, the structure of the tighter coupling required in lieu of events is just as complex. Events enable a simpler structure but make control flow more difficult. However, I ensure that event processing is serialized, predictable, and deterministic. I also ensure that event processing only happens at one point per loop.
It works very well. Happy to answer more specific questions.