Thanks for replying, and I still have a few more questions. You mentioned that I would be able to encapsulate environment specific behaviour in the event system. That assumes that I would define and register the events outside of the entity classes right? I'm not too sure if I want to move entity-related behaviour outside of the entity, thus I think the inheritance model above may work better.
What is 'inside' and 'outside'? Whether you use inheritance, composition, or some other association, you still have 2 classes.
Assuming I do use the observer pattern, would it make sense to use a "global" event handler or a single event (with listeners) per entity?In my experience you can go a long way just by assigning callbacks to the object. The abstract Entity could have an onShot member which it calls when it gets shot. All you need to do is assign the ClientEntity.onShot function to it.
The Observer pattern is a good alternative in languages like C++ or Java where assigning arbitrary callables to another object is awkward, but in the likes of Python or C# it can be more trouble than it's worth.
Could you offer any advice as to when a queue is really needed?I like to use queues because it means I can totally separate the input from the logic. But they're not strictly necessary.
I have also decided that I would like to work with a component system. I think that I feel somewhat drawn to having intelligent components rather than the dumb entity system approach which utilises systems. Are there any issues with this?My opinion on entity-based components, whatever variation you prefer, is that they usually cause more trouble than they are worth unless you are at the level where you don't need to ask how best to use them. They're a bit of a tar-pit for people who are eager to do things the most flexible way from day one. But each method is functionally equivalent to all the others, and all the non-component methods as well. People have written whole games in languages that don't even have structures, never mind classes, so everything is possible - it just changes how you do it.