The entity system i use/create has some non quite default modifications, that make sense IN MY CASE (carfeull here for what you want to do), keep this in mind as this is special for mine and not necessarly following the clean concept of an es.
Basically my systems (whatever they are) are threads, that have a central CyclicBarrier. In the cycilcbariers runnable all changes are synchronized with the live data (I only use immutable objects, to easy multithreading, and allow delayed concurrent processing for special systems.
Basically assume a queue that collects changes in the current itteration and before the next they will be applied.
-> Other implications I have, only one system is allowed to write at a specific component, but multiple may read at any time.
-> Only one write per component is valid per iteration! (This hugly changes on how stuff can be approached, but makes the synching between ticks nearly free.
-> No matter when I read I get a consistent state, eg i will never get a half updated entity.
-> There is absolutly no gurantee on the order in wich systems will process Entities, and wich Thread will actually do the work, but it is guranteed that any system intrested will process each intresting entity once a tick.
-> Adding removing entities happens between ticks.
One downside is that I have a higher performance base hit per iteration, however since everything is truly concurrent, it scales nearly with factor 1 per cpu core.
Other stuff:
-> JME on the client is only a system, the es is independet, i could just disable that system and it would still run.
-> Networking is independet, on the server and the client is a system that manages everything else depending on annotations present
-> I do no runtime detection of those, I wrote a small precompiler that does all registering of entities systems (network message types ect) by writing a simple java class out of it. (while a bit strange, this greatly reduces problems with forgot to register)
[An average networked component that can be persistent in my system has to be registerd with up to 5 systems currently (Database so tables are generated and ESQLCriterions (yes i made a own Criterion based language for ES), Network to prepare caches, and custom serializers, universe so the component gets an id based on type ect.]
Now after that basics to your question (on how i would handle this, note that pspeed is probably way more using a clean es than i)
-> I would have a PhysicSystem, DamageApplierSystem, HealthComponent,ResitanceComponent.
-> PhysicSystem will provide all collision data, and (for example via userdata the id of the entitys affected) in my case not via a component but directly
-> DamageApplier will read all entities with collision, filter for entites with health
-> At this point I then would be able to calcualte the new health and set it, since I have all data potentiall affecting health available (remember limitation of my Es to only set once per tick)
One recommendation:
Download Artemis (another Es not reall being a clean one) and their example verticalshooter
Now after you understood that eample, modify the game such that
- The enemys get a random velocity at spawn and move into the direction
- The enemys can shoot back (cooldown and maybee based on size of them?)
- You can get damage, and have a small shield that can take 1 hit /10 seconds
- Make larger enemys fire different bullets that do more damage, see how the shield reacts to this without changing any code.(Report this back as I wonder how you will do this step and I can imagine different implementation based outcomes)
After this think about all connections between components and systems and if they are the minimal ones necessary.
Also throw out all normal design patters you know when thinking about an ES, while without a problem possible to make a system for example like a state machine, try to not think into , as it will always have a limiting context, ES is like OO a own paradigmen that my seem similar in many points but is not.
Also there are almost no real clean ES out there, mine has that thread implications, pspeeds cannot handle multiple entity generating servers (as i understood form an earlier discussion about what to use as an id, simply because it is not required) ,artemis has a limited idea of systems, ect. each is modified a bit for it’s use case and personal likings as well as some crude performance based choices.
Well yes, thats quite longer than i expected to write, I hope it helps you, especially the part about doing a bit of work with artemis might be the most important, as that was when it suddenly made a loud click in my head.