DigitalExtinction / Game

A 3D RTS game implemented in Rust.
https://de-game.org
GNU Affero General Public License v3.0
315 stars 25 forks source link

Energy Distribution Grid: Graph Representation #472

Open Indy2222 opened 1 year ago

Indy2222 commented 1 year ago

As a first step, lets make this extremely simple:

Indy2222 commented 1 year ago

In the future we might use whatever comes out of https://github.com/bevyengine/bevy/issues/3742. However, let's not get this blocked -> we might need custom implementation in the meantime.

JackCrumpLeys commented 1 year ago

I aim to cover my progress, thoughts and discussion I have had privately with @Indy2222 around this system in this comment to allow open discussion of this very essential system. Most of the code I have at this stage is here: https://github.com/JackCrumpLeys/DE/tree/feat/energy/graph. These are not final decisions but rather prototype code.

Data

Graph

The graph contains every every unit as its nodes and edges between nearby units.

/// The energy producer component is used to mark an entity as an energy producer.

[derive(Component, Debug, Clone, Copy)]

pub struct EnergyProducer;


# systems to design
## nearby units component
Units all have a nearby component (maybe a smallvec with some enum like transmitters, receivers or enemy units),
- Either e.g NearbyReceiver(Entity) or NearbyReceivers(SmallVec<Entity>)
- This component allows the graph to be assembled with more ease.
- A system that updates this component based on unit movements (Built with parallelism). One thing I noticed during testing is that the rotation that they like to do (pathfinding?) updates the graph way to much so we should check for real movement before processing.
  - We could solve the update issue by only Triggering an update if both a) Bevy change detection on Transform was triggered, b) the position was updated by at least x (so small changes & rotational changes do not lead to unnecessary re-computation)
- We should keep all nearby entities (not just the transmitters) in the component. That would enable reciprocal updates (i.e. you only update (de)spawned or moved entities and their reciprocals). Also, we could use such a data structure in movement (like hybrid reciprocal obstacle avoidance). 
- Uses either KdTree or AABB to find nearby entities depending on profiling.
## Graph updates
a system that builds/updates the graph for new entities and updated entities (`Added<NearbyUnits>` and `Changed<NearbyUnits>`). This system should be able to run very fast as all it does is add edges where there should be and remove edges were no connection exists. (What do we do with edge weight here?) 
- The graph should be updated regularly but does not need to update at the speed of the frame rate (possibly 10 updates per second). 
## Energy processor
A system that uses the graph to transfer energy. This system is solely responsible for using and interpreting the graph. This system ultimately decides where energy is needed and tries to get it there. (probably the most performance heavy system)
- Maximum flow algorithm.
- Assign priory for where to put energy.
- This system still needs a lot of design and should mostly be covered by #475 
# [Video demo showing a visualization on my prototype branch](https://cdn.discordapp.com/attachments/1123028085923643502/1123516676646899803/out.mp4)