A pure .NET BWEM 1.4 implementation. It's ported from the BWEM library.
Brood War Easy Map for .NET library that analyses Brood War's maps and provides relevant information such as areas, choke points and base locations.
It is built on top of the BWAPI.NET library.
It first aims at simplifying the development of bots for Brood War, but can be used for any task requiring high level map information. It can be used as a replacement for the BWTA2 add-on, as it performs faster and shows better robustness while providing similar information.
- To access general information on the Map.
- To access the Tiles (32x32) and the MiniTiles (8x8) information.
- To access the Areas information.
- To access the Starting Locations information.
- To access the Minerals, the Geysers and the Static Buildings information.
- To parametrize the analysis process.
- Provides some useful tools such as Paths between Choke Points and generic algorithms like Breadth First Search.
- Installation
- Create a bot project
- Run
dotnet new console -o MyBot
- Run
cd MyBot
to change directy intoMyBot
folder - Run
dotnet add MyBot.csproj package BWAPI.NET
to add the reference to the BWAPI.NET nuget package - Run
dotnet add MyBot.csproj package BWEM.NET
to add the reference to the BWEM.NET nuget package - Copy and paste example bot below into
Program.cs
or develop your own bot - Run
dotnet run
(At this point you should see "Game table mapping not found." printed each second)
- Run
- Run StarCraft through Chaoslauncher
- Run Chaoslauncher.exe as administrator
- Chaoslauncher is found in Chaoslauncher directory of BWAPI install directory
- Check the BWAPI Injector x.x.x [RELEASE]
- Click Start
- Make sure the version is set to Starcraft 1.16.1, not ICCup 1.16.1
- Run Chaoslauncher.exe as administrator
- Run a game against Blizzard's AI
- Go to Single Player -> Expansion
- Select any user and click OK
- Click Play Custom, select a map, and start a game
- Run a game against yourself
- Run Chaoslauncher - MultiInstance.exe as administrator
- Start
- Go to Multiplayer -> Expansion -> Local PC
- Select any user and click OK
- Click Create Game, select a map, and click OK
- Start – Uncheck BWAPI Injector x.x.x [RELEASE] to let a human play, leave alone to make AI play itself
- Go to Multiplayer -> Expansion -> Local PC
- Select any user and click OK
- Join the existing game created by the other client
using BWAPI.NET;
using BWEM.NET;
namespace ExampleBot
{
public class ExampleBot : DefaultBWListener
{
private BWClient _bwClient;
private Game _game;
private Map _map;
private Player _self;
public void Run()
{
_bwClient = new BWClient(this);
_bwClient.StartGame();
}
public override void OnStart()
{
_game = _bwClient.Game;
_self = _game.Self();
_map = new Map(_game);
_map.Initialize();
}
public override void OnFrame()
{
var workers = new List<Unit>();
var marines = new List<Unit>();
Unit barrack = null;
Unit commandCenter = null;
var buildingSupply = false;
// iterate through my units and collect relevant information
foreach (var myUnit in _self.GetUnits())
{
var unitType = myUnit.GetUnitType();
if (unitType == UnitType.Terran_SCV)
{
workers.Add(myUnit);
}
else if (unitType == UnitType.Terran_Command_Center)
{
commandCenter = myUnit;
}
else if (unitType == UnitType.Terran_Barracks)
{
if (!myUnit.IsBeingConstructed())
{
barrack = myUnit;
}
}
else if (unitType == UnitType.Terran_Marine)
{
marines.Add(myUnit);
}
else if (unitType == UnitType.Terran_Supply_Depot)
{
if (myUnit.IsBeingConstructed())
{
buildingSupply = true;
}
}
}
// if it's a worker and it's idle, send it to the closest mineral patch
foreach (var myUnit in workers)
{
if (myUnit.GetUnitType().IsWorker() && myUnit.IsIdle())
{
Unit closestMineral = null;
// find the closest mineral
foreach (var neutralUnit in _game.Neutral().GetUnits())
{
if (neutralUnit.GetUnitType().IsMineralField())
{
if (closestMineral == null || myUnit.GetDistance(neutralUnit) < myUnit.GetDistance(closestMineral))
{
closestMineral = neutralUnit;
}
}
}
// if a mineral patch was found, send the worker to gather it
if (closestMineral != null)
{
myUnit.Gather(closestMineral, false);
}
}
}
// build SCV if we can
if (commandCenter != null && commandCenter.GetTrainingQueue().Count == 0 && workers.Count < 12 && _self.Minerals() >= 50)
{
commandCenter.Build(UnitType.Terran_SCV);
}
var i = 1;
foreach (var worker in workers)
{
if (worker.IsGatheringMinerals())
{
// check if we can build a barrack and build it
if (_self.Minerals() >= 150 * i && barrack == null)
{
var buildTile = BuildingPlacer.GetBuildLocation(UnitType.Terran_Barracks, _self.GetStartLocation(), 40, false, _game);
if (buildTile != TilePosition.Invalid)
{
worker.Build(UnitType.Terran_Barracks, buildTile);
}
}
// check if we can and need to build a supply depot and build it
if (_self.Minerals() >= i * 100 && _self.SupplyUsed() + (_self.SupplyUsed() / 3) >= _self.SupplyTotal() && _self.SupplyTotal() < 400 && !buildingSupply)
{
var buildTile = BuildingPlacer.GetBuildLocation(UnitType.Terran_Supply_Depot, _self.GetStartLocation(), 40, false, _game);
if (buildTile != TilePosition.Invalid)
{
worker.Build(UnitType.Terran_Supply_Depot, buildTile);
buildingSupply = true;
}
}
}
i++;
}
// build a marine if we can
if (barrack != null && !barrack.IsBeingConstructed() && barrack.GetTrainingQueue().Count == 0)
{
barrack.Build(UnitType.Terran_Marine);
}
// move the marines to the nearest chokepoint in the map
foreach (var marine in marines)
{
if (!marine.IsMoving())
{
var marinePosition = marine.GetPosition();
var nearestChokePoint = _map.ChokePoints.MinBy(x => x.Center.ToPosition().GetDistance(marinePosition));
var nearestChokePointPosition = nearestChokePoint.Center.ToPosition();
marine.Move(nearestChokePointPosition, false);
}
}
}
}
}
BWEM doesn't provide any geometric description (polygon) of the computed areas.
Starcraft and Starcraft: Broodwar are trademarks of Blizzard Entertainment. BWAPI.NET through BWAPI is a third party "hack" that violates the End User License Agreement (EULA). It is strongly recommended to purchase a legitimate copy of Starcraft: Broodwar from Blizzard Entertainment before using BWAPI.NET and/or BWAPI.