This is meant to serve as an introduction to developing on the Robocode engine, giving an overview of the code and robot structure and walking through the steps of a battle. Hopefully, this makes it a little easier to start off :)
This guide is written for Robocode 1.7.3.
Code Structure
The Robocode source is broken down in different modules.
robocode.api is the module that is built first and has no dependencies. This is code that is visible to robot authors. It contains all the events a robot receives, all the interfaces a robot can inherit, and so on. It also contains several interfaces that are implemented in other modules.
robocode.core has some lower-level class loading and more interfaces later modules will implement.
robocode.repository is concerned with most of the class loading. This is where all robot binaries are loaded.
robocode.host is the security module of Robocode. It deals with events, robot I/O, some threading, and contains the robot proxies (more on this later).
robocode.battle contains various classes that run the battle. The Battle object runs through the battle loop, interacts with robot peers (more later), updates bullets, tracks scores (as the various Statistics classes), and creates Snapshots. The Snapshots are mainly sent to the Battle GUI so the GUI updates properly.
robocode.samples contains sample robots.
robocode.tests contains unit tests and integration tests.
robocode.ui contains GUI code.
These modules are explained in greater detail at http://zamboch.blogspot.com/2009/06/robocode-modules-as-in-version-17.html. Pretty pictures are included.
Robot Communication Structure
Each robot can access an IRobotPeer object within its source code. Any function called on this IRobotPeer will go through the robot’s proxy in the (robocode.host) module. Any command will be sent from the proxy to the robot peer (in the robocode.battle) module as a message. The proxy also validates the command. The robot peer then interacts with the battle loop and is updated as needed.
The structure is explained in greater detail at http://zamboch.blogspot.com/2008/07/plan-for-robocode-162.html.
Typical Robocode Battle
The main entry point of the application is within the class Robocode within the robocode.api package. This leads into RobocodeMain within robocode.core, where command line arguments translated. Unless an argument of “-nodisplay” is included, the GUI will start up here. Classes are loaded and the robot database is constructed. A new battle is started using the NewBattleDialog or by loading a .battle file. Either one of these will set up a BattleProperties object. Robots are selected within the NewBattleDialog or the .battle file specifies which robots to use.
BattleManager, within robocode.battle, is instantiated and will start a new battle. A Battle object is created and its thread is started.
Battle sets up the battlefield based on the BattleProperties and the robots selected from the robot repository. Battle sets the robot’s initial positions, creates RobotPeers for each of the loaded robots, assigns teams, and sets a ContestantPeer for each robot or for each team. It creates a thread for each robot. The battle begins.
At the start of each turn, RobotPeers translate the commands they received from their respective RobotProxies into ExecCommands. Bullets are updated, following a velocity until they hit something. Robots are updated, interpreting their ExecCommands. After this, dead robots are handled. If the round is over, each ContestantPeer’s ContestantStatistics updates its own score information. Otherwise, the robot threads are notified and each robot runs through its own program.
Each robot goes through its code. Any blocking calls (such as ahead() and execute()) will cause the RobotProxy to send a message to its respective RobotPeer. The robot thread then sleeps.
At the end of a battle, all ContestantPeers total their ContestantStatistics and report the results, which are in turn reported to the GUI or the specified output file.