A hard problem for BW bots is the decision on when to attack and what to attack. Part of the problem is the question "who will win?"
ASS tries to answer that question by allowing a simulation of possible outcome.
Additionally, various utilities for path-finding or fast location queries are also available.
- Fco. Javier Sacido for his JFAP port
- Hannes Bredberg for the original FAP
While the simulator is API independent, JBWAPI and BWAPI4J work out of the box. BWMirror should also work but is not thoroughly tested.
Add the maven repo:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
And the dependency:
dependencies {
implementation 'com.github.Bytekeeper:ass:1.1'
}
Add the maven repo:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
And the dependency:
<dependency>
<groupId>com.github.Bytekeeper</groupId>
<artifactId>ass</artifactId>
<version>1.1</version>
</dependency>
To get it, either download and build it yourself or grab the Appveyor Build.
Agent is the Unit abstraction being used. It can be either created directly, or
the BWAPI4JAgentFactory (resp. BWMirrorAgentFactory) can be used to create an Agent for an existing Unit.
Creating Agents by using just a UnitType is also possible.
The main class is Simulator. You can add Agents for player A or player B here.
After doing that, you can simulate a number of frames (default: 96). Next, you
retrieve the result and check if it's to your liking (some of your units survived?).
BWMirrorAgentFactory factory = new BWMirrorAgentFactory(game);
Simulator simulator = new Builder().build(); // You can also customize the simulator
simulator.addAgentA(factory.of(someOfMyUnit));
simulator.addAgentB(factory.of(someEnemy));
simulator.simulate(240); // Simulate 24 seconds
if (simulatior.getAgentsA().isEmpty()) {
// Uh oh
} else {
// Hurray
}Simulates:
- Medics
- SCV repair
- Suiciding units (scourge, scarabs, ...)
- Ground attackers
- Air attackers
- Basic movement
- Kiting
- Elevation affecting damage
- Cloaked units
- Splash (Radial, Line and "Bounce" aka Tanks, Lurkers and Mutas)
- Stim, Armor, Weapon, Range and Speed upgrades
- Effects like plague, lockdown, stasis, dark swarm
- Frame skipping to improve simulation performance at cost of precision
- Elevation is deemed "constant" within the simulation
- Visibility is ignored (visibility is "constant" within the simulation)
- Spellcasters are doing nothing
- Distance mechanism does not match BW's "boxed" distances
- Instant acceleration
Default behaviors:
Medics:
- Find any unit that can be healed this frame (in range and damaged)
- Otherwise find unit in range and in need of healing and move toward it
Suiciders:
- Find any unit that can be attacked this frame and dive in
- Otherwise find targetable unit and close in
Repairers (SCVs):
- Find any unit that can be repaired this frame and repair it
- Find closest unit that can be repaired and move toward it
- If no unit can be repaired, attack
Attackers:
- Find any unit that can be attacked this frame and attack
- Otherwise find viable target unit and close in
- Otherwise flee from any unit that could attack us
You can also use the RetreatBehavior to make some or all units run away instead of attacking.
Another way to estimate outcome of a battle is to use the Evaluator. It does not simulate
agents as the Simulator does. Instead it uses some heuristics to determine a
"how well is player A going to be vs B" ranging from [0-1].
The basic idea is:
- Let all agents of A shoot at B and all agents of B shoot at A
- Divide through the combined health to determine how many agents would have died in that round
- Medic heal, health and shield regen are also factored in
A DBScan based clustering algorithm.
- Stable clustering: Unless a cluster is split up, units will end up in the same cluster as in previous runs
- Iterative: Instead of assigning all units to clusters at once, do it iteratively. Once done, the clustering restarts and the previous result can be accessed.
A utility class to make 2D-position based queries:
- radius queries
- area queries
- nearest queries
An implementation of the algorithm described here: https://zerowidth.com/2013/05/05/jump-point-search-explained.html
Generally much faster that a normal A* while still being optimal.
- GMS class to manage gas, minerals and supply in one value type.
- Can be used to manage existing resources vs cost of units, tech or upgrades