Library that tries to provide tools tackling the fundamental problem of the RTS genre:
- How should this unit individually move
Tackling Formation, guide units to formation places, navigation and moving in a formation along the planned path.
- Formation Shape Creation
- Usher
- Flocking
-  Pathfinding
- Distance Grid
- Flow Field
- Grid of Flow Fields
- Line Of Sight
- Continous Crowd
 
In this example a simple Rectangle Formation is created and used for some units. The places are the untransformed location where the units should be.
The Usher generates tickets assigning each unit a location.
In a real scenario the places are transformed after generation to the real location.
    std::string formationDescription = R"""(
      {
        "OwnInterfacePoint"                : 0,  
        "ParentInterfacePoint"             : 0, 
        "OverwriteWidthWithInterfaceWidth" : false, 
        "RotateWithInterface"              : false, 
        "Rotation"                         : 0, 
        "UnitCategory"                     : 0, 
        "UnitDistributionWeight"           : 1,
        "Children"                         : {},
        "Shape" : {
          "Type" : "Rectangle",
          "Size" : [1,1],
          "Scaling" : "Isotropic"
        }
      }
    )""";
    auto formation = RTSPathingLib::Formation();
    formation.fromJson(nlohmann::json::parse(formationDescription));
    std::vector<RTSPathingLib::Body> units;
    units.push_back(RTSPathingLib::Body(glm::dvec2(4, 6), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(-3, 5), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(3, 2), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(5, 3), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(3, 5), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(2, 3), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(0, 1), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(-3, -2), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(-2, 4), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(2, -5), 0, 1));
    units.push_back(RTSPathingLib::Body(glm::dvec2(-3, -5), 0, 1));
    auto places = RTSPathingLib::FormationCalculator(formation, units).calculate();
    std::vector<size_t> tickets = RTSPathingLib::Usher::assignPlaces(units, places);
- Units are Green Dots.
- Places are Gray.
- The Tickets are Yellow.
A Complex Example for a Formation with different Unit Sizes.
Here is an example that may justify this Formation:
- Red Units are in the center to be protected from aggressive Forces. Archers and a few Big Catapults.
- Green Units are the Protectors. Heavy armored Paladins.
- Blue Units are Horsemen / Zerglings. Melee units that are fast. They swarm out protected by the heavy fire of the archers.
See "Formation/PraiseTheSun" Test if you are interested how its done.
- Get more confidence with testing
- Try TDD
- Use SVG for Visual Testing and Documentation
- try out Github CI features
 
- Get more versatile with cmake and vcpkg
- Build Mechanic before Graphic
- Build a giant RTS, in small deliverable pieces
Here some links which maybe helpful to understand the tech behind it:
- Usher
- Pathfinding
- https://www.jdxdev.com/blog/2020/05/03/flowfields/
- https://www.gameaipro.com/GameAIPro/GameAIPro_Chapter23_Crowd_Pathfinding_and_Steering_Using_Flow_Field_Tiles.pdf
- https://www.sanctuaryshatteredsun.com/post/pathfinding-1
- https://github.com/bjkarasek/flowfield-unity
- https://gamedev.stackexchange.com/questions/387/how-does-flow-field-pathfinding-work
 
- Flocking
- Multiple Topics
- Use VCPKG and CMAKE
- Dependencies
- Boost.Geometry
- Boost.Graph
- nlohmann::json
- glm
- catch2