Sunday, June 27, 2010

Client-Server Optimization

I've decided to take a break from the testing framework to work on the client server architecture.

The client-server architecture is a new alternative way of making AIs with BWAPI. Traditionally, people would write their AI in a DLL which would get loaded by BWAPI at the start of a match. In contrast, the client-server architecture lets users write their AI as a separate executable program which connects to their local BWAPI server (loaded in Broodwar memory), and communicates with it via shared memory.

This new architecture is almost fully functional, however up to this point it has been extremely slow due to the method that BWAPI uses to get information from Broodwar into the shared memory bank. The inefficient/simplistic implementation currently just calls relevant BWAPI::Unit member functions, and copies the results into shared memory. Since each unit's state is comprised of about 100 different pieces of information, this results in about 100 BWAPI function calls per unit. And each of these functions call other functions in order to generate the appropriate error codes when needed and determine if the user/AI is allowed to access the given unit (hidden units are not accessible unless Flag::CompleteMapInformation is enabled).

To optimize the process of getting information into shared memory, BWAPI will compute the UnitData struct directly from Broodwar memory, bypassing the BWAPI function calls. Thus the last few days I've been moving implementation details of each individual Unit member function to a single function, called Unit::update(), so that it computes the entire UnitData struct directly from Broodwar memory without using any unnecessary or redundant function calls. In addition, to prevent duplicate code I've been simplifying the Unit member functions so they just compute their answers from the UnitData struct, just like the client-side implementation of the Unit object does. This should also go a long way to ensuring that BWAPI behaves consistently whether you're writing you AI as a DLL or as a separate client process.

In short, I'm making a rather large internal change to how the BWAPI::Unit class works in order to optimize the client-server architecture, however the end-user functionality should go unchanged. Also, the test framework module is a DLL, so it can be run both as a DLL in Starcraft memory the traditional way or be loaded into a separate program such as BWAPI's AIModuleLoader and run in a separate client process, so the test framework will be able to test both implementations to make sure they behave correctly and indistinguishably once everything is complete.

No comments:

Post a Comment