AI scripts receive data from the engine about the current simulation state, once per simulation turn. This is a fairly low-level mechanism - it is expected that AI scripts will use a wrapper to provide more convenient access to the data. Currently this wrapper is implemented in `common-ai/base.js`. The AI's `HandleMessage` method is called with one argument: {{{ state = { entities: ..., events: ..., players: [...], timeElapsed: ..., // seconds since the start of the match map: ..., passabilityClasses: ... }; }}} == `entities` == TODO == `events` == TODO == `map` and `passabilityClasses` == {{{ state.map = { width: 256, height: 256, data: [ ... ] // Uint16Array with width*height entries }; }}} {{{ state.passabilityClasses = { "pathfinderObstruction": 1, "foundationObstruction": 2, "building-land": ..., // these are all the PassabilityClasses defined in simulation/data/pathfinder.xml ... }; }}} `state.map.data` encodes all the passability data of each terrain tile. `state.passabilityClasses` gives bitmasks that define how to interpret `state.map.data`. For example: {{{ // Get the bitmask for tiles that will obstruct foundations (i.e. you can't place any buildings there) var obstructionMask = gameState.getPassabilityClassMask("foundationObstruction"); for (var i = 0; i < map.data.length; ++i) if (map.data[i] & obstructionMask) ; // tile i is an unbuildable location }}} Since these are bitmasks, you can 'or' them together: {{{ var obstructionMask = gameState.getPassabilityClassMask("foundationObstruction"); // Add in the bitmask for tiles that are obstructed for the "building-land" passability class // (i.e. tiles that are underwater or too steep, based on the definition in pathfinder.xml) obstructionMask |= gameState.getPassabilityClassMask("building-land"); for (var i = 0; i < map.data.length; ++i) if (map.data[i] & obstructionMask) ; // tile i is an unbuildable location for land-based buildings }}}