6.370 Home: Specifications

Table of Contents

Introduction

As in last year's contest, your task will be to develop Java programs that will play a realtime strategy game using virtual droids. Each droid's hardware will be modelled as a set of abilities which your software will control through a fixed interface. Software will run in timesliced Java virtual machines written in Java, what we will call Droid Virtual Machines (DVMs). Using these abilities, droid software will be able to explore the closed universe and interact with other objects and droids.

This contest is based on realtime (RTS) strategy games. If you are unfamiliar with RTS terminology, please consult our primer. There are some differences to note from traditional RTS:

  • Resources are not gathered and expended from a single, omnipresent "account" for each player. A droid may only gather and spend resources for itself.
  • There is not a single omniscient player controlling the army. Each droid has a limited sensor and radio range and must communicate with other friendly droids to accomplish goals. As such, there is a very foggy fog-of-war in effect.
  • There are no buildings per se. One type of droid is stationary, guards territory, and serves some other functions traditionally associated with buildings. However, they can also run code like other droids.
  • There is no human intervention in the action of your droid army. Once a game begins, your software controls the droids until the game ends or is aborted.

Contest Format

There are two submission deadlines, and two official tournament maps on which your entry must compete. The goal of the maps is to build a hemlock as close as possible to a given destination point. The goal is described in more detail in the Tournaments & Maps section. For the logistics see the section on submitting your solution.

The first deadline is for your preliminary submission, which will compete in a single-elimination seeding tournament (the winner's bracket from our double-elimination final bracket). Consult the Calendar for a detailed timetable of events.

Teams will be ranked for the final tournament bracket based on matches won; ties will be broken by distance of the closest mature hemlock to the destination point. You may then improve your solution until the the second deadline, when you must submit the version which will compete in the final tournament.

What We Provide

We will provide you with a JAR file that contains the following:

  • Specifications (this document)
  • The colony.common package which defines the interface and constants you must use in developing a solution.
  • The java.lang, java.util, and java.io packages implemented for the DVM.
  • Javadoc HTML documentation for the above packages.
  • Software to test your solution.
  • Sample maps and example source code (but not the exact tournament maps or source code of the reference player).
  • The compiled bytecode of the reference player (in package team00) which you must beat in the preliminary tournament to qualify for the finals and to receive credit for 6.370.

How It Works

In this contest, you will write the software that controls a droid hardware in the closed universe; see Writing Your Solution for more details about writing this software. All the Java classes that you write will collectively be called droid software; specific classes which implement the main static method will be called players. In particular, the class called Player in your team package will be loaded by every droid when it first boots up; this class is known as the primordial player.

Droid hardware is a collection of abilities, which are constraints on its interactions with the closed universe, and properties, which are substates of the droid.

Your code is compiled into Java bytecode and runs on a Java virtual machine written in Java, called a Droid Virtual Machine, or DVM. There is a separate DVM for every droid hardware in the engine, each with its own stack, program counter, static variables, garbage collection, and heap limit. There are a few exceptions:

  • if you are replicating a new droid, it will not have an associated DVM to run code until it finishes assembling.
  • If your droid software throws an uncaught exception or error, the game engine will remove the DVM from its collection and the associated droid hardware will be unpowered.

Each droid hardware exports a DroidHandle to its controlling DVM; this handle has methods for using abilities, gaining information about properties, and gaining information about the closed universe. This handle is the only way your software can interact with other objects, droids, and the closed universe.

 
 
 

The game engine is what manages all the DVMs, droid hardwares, the map, the clock, and their interactions. In one cycle, the engine takes the following actions in order:

  1. Each DVM in the game engine receives an allotted number of bytecode instructions per cycle, called its timeslice. Each DVM currently gets 1000 instructions per cycle; the game engine runs these timeslices in sequences for every DVM in its collection. Some abilities are active, meaning they change game state and end the calling DVM's timeslice; use of active abilities queues up actions.
  2. After all DVMs have received their timeslice, the engine processes all queued actions in order to prevent inconsistencies in game state. Repair actions are always queued before other actions. See Droid Abilities for details.
  3. Next, the action queue is cleared, and the engine calls a clocktick method for every clocked object in its collection. All droid hardwares are clocked objects, because certain properties are updated by the cycle (assembly status, map position, etc.). In addition, maps can be clocked (to end the game after a certain number of cycles for example) as well as artifacts (to take some special action at a specific time).
  4. Finally, the engine increments its time (in cycles), and begins the loop again.

Game Physics

As mentioned above, time is measured in cycles, which is the longest continuous sequence of instructions executed by any one DVM.

Distance is measured in spans, which are continuous. Speed is measured in spans per cycle.

There is one resources in this game, metal ore out of which all droids are constructed. Ore is measured in a unit called stone and is available in fixed quantities at certain locations on a map.

A droid's stored ore decreases when it replicates and increases when it gathers ore. Ore coalsces; that is, if a droid is already carrying ore, any additional ore it stores will "transfer" hit points over to the carried ore, rather than being stored itself.

All objects, physical and nonphysical, are identified by monikers, which are permanently attached to this object upon its creation. All droids have unique monikers, but entities like abilities and terrains share a generic moniker. A moniker is analogous to a name or hash key.

Physical objects, such as a droid or a piece of ore, have a position on a map and hit points measured in stone. However, physical entities do not have a size; as such, they can occupy the same location or even pass through each other. Physical entities whose hit points reach zero are remove from the map and game engine. Abilities and terrains are examples of nonphysical entities.

Unlike other physical objects, droids have abilities (including the ability to store other objects, travel around the map, and replicate) and are controlled by a DVM which can run bytecode. Replicants, or droids that have not fully self-assembled, are still physical objects but are uncontrolled and unpowered until they mature and their DVM boots up their army's primordial player.

Droid Types

You will control four types of droids in the competition, which have all the same abilities and properties, but with different parameters (e.g. different ranges, different hit points).

Scion
Land reconaissance and exploration.
Hemlock
Communications relay and perimeter guard.
Sea Dragon
Naval senty unit.
Beetle
Aerial transport and scout.

Droid Abilities

All droids have the same basic abilities, which are described below.

Active abilities cause a change in the game state and cost 1 cycle of time per use (that is, they are instantaneous and also end your DVM's timeslice). They cause actions to be queued up while DVMs are running, to be processed after all DVMs have run. Repair actions are queued up first; all other actions are queued up in the order they were created.

Passive abilities do not change game state, and may be called multiple times in one cycle; however, they are idempotent in that calling them more than once per cycle gives you no new information.

All uses of abilities are atomic function calls in the DVMs, meaning that they will always return execution to the DVM before its timeslice ends. Some abilities manage state for a droid or have ranges/parameters which are the described in the property table.

The specific syntax for these abilities is discussed in the PlayerConstants javadoc. All the abilities below are linked directly to their corresponding moniker constant in this javadoc; moniker constants are passed into the DroidHandle.useAbility method which is described in the Writing Your Solution section.

Most of these abilities operate on monikers, which you must first retrieve using the Sensor ability. Using these abilities when their conditions are not met will have no effect on the game state.

Passive Abilities
  • GetHitPoints
    A droid can retrieve the hit points of any object within sensor range, including its own.
  • GetAssembly
    A droid can retrieve the assembly status of any object within sensor range, including its own. However, a droid that can run code to retrieve assembly will already be 100% assembled.
  • GetPosition
    A droid can retrieve the position of any object within sensor range, including its own, as a MapPoint.
  • GetVelocity
    A droid can retrieve the velocity of any object within sensor range, including its own, as a Double.
  • GetTerrain
    A droid can retrieve the terrain moniker of any position within its sensor range.
  • GetOreAmount
    A droid can retrieve the amount of ore carried by any droid within its sensor range, including itself.
  • GetStorage
    A droid can retrieve the items stored by any object within sensor range, including its own stored items, as an array of Monikers.
  • GetOwner
    A droid can retrieve the moniker of its owner if it is being carried.
  • GetStorageAvailable
    A droid can retrieve the amount of storage available in any droid within sensor range, including itself, as an Integer. This amount of available storage is in stone and uses the hit points of all physical objects, and in the case of droids, all their stored items resolved recursively.
  • GetGoalStatus
    A droid can retrieve the number of artifacts left unclaimed on the map as an array of one Integer.
  • RadioReceive
    Droids can receive messages sent using the Radio Transmit ability. Droids have a maximum buffer size of messages which are stored in a FIFO queue; when the maximum size has been reached, the oldest message is deleted and the newest one added. When this ability is used, all buffered messages are returned the buffer is cleared.
  • Sensor
    Droids can retrieve the monikers of other free (unstored) physical objects that are nearby (within the range of the sensor). The droid itself does not show up in its sensor readings, nor do its stored items, nor do any objects carried by other droids. To get stored items within range, use the GetStorage ability on the owners.
Active Abilities
  • RadioTransmit
    Droids can send messages to each other in the form of a single Byte, Short, Integer, Long, Float, Double, Boolean, String, Moniker, or MapPoint. You may not send arrays of these objects or any other types, as was erroenously stated in previous revisions. The sender does not receive its own message back. All droids within the range of the transmitter receive the message; that is, the single transmitted object is queued in each droid's receive buffer, waiting to be retrieved with the Radio Receive ability.
  • Reboot
    A droid can reboot itself to load a new class in the team package.
  • Store
    • Droids have the ability to carry other physical objects and have a maximum capacity measured in stone; the storing weight of all physical objects is their current hit points. The one exception is that mature hemlocks cannot be carried.
    • Droids must approach within a certain distance to store an object (specified in colony.common.PlayerConstants.STORE_DISTANCE. Currently this is 1.0 spans. A droid that stores an object is known as that object's owner.
    • A stored droid cannot itself pick up new items or travel independently; its position is the same as its carrier. Droids cannot store themselves.
    • Storage capacity is measured cumulatively; a droid must have enough storage capacity for any droids it wishes to carry as well as those droids' storage items.
    • Ore that is stored will automatically coalesce with any ore that is already present; a droid will almost never need to retrieve ore monikers once the ore has been stored, but rather, it can use the GetOreAmount ability. If a droid only has room for part of a piece of ore, as much stone as will fit will coalesce into the droid's possession, and the remaining stone will be left on the map.
    • If two droids simultaneously (in the same cycle) try to store an object, it will go to the oldest droid (the one who was created first).
  • Discard
    A droid has the ability to discard objects that it is carrying. The discarded objects will be located at the droid's position at the time of discarding.
  • Attack
    A droid can inflict damage on another droid within a certain range. There is no splash damage; only the droid which is targeted by an attack ability receives damage. Each droid type can only attack other droids on certain terrains; these are listed in Droid Properties. Stored droids can be attacked as a unit on their carrier's terrain, but can only attack on their original allowed terrains. Replicants can be attacked whether they are carried or not, but obviously cannot attack back. If a replicant receives damage faster than it can assemble, it can be destroyed. When a droid is destroyed, anything it carries will be discarded into its owner if any; otherwise stored items will be discarded onto the map at the location of the droid when it was destroyed.
  • Repair
    A droid can use any stored ore to repair damage to itself up to its maximum hit points. This repair uses an amount of ore equal to the minimum of the damage amount and available ore amount; repairs occur in 1 cycle.
  • Replicate
    A droid can replicate another droid of the same type if it is carrying enough ore. Replicants will appear on the map 1 span distant from the parent's location at the time of replication. They are initially unpowered and have 0 hit points; they require a certain assembly time before they gain a DVM and can run code. During assembly, their hit points increase linearly to their maximum value; a replicant can be attacked at any time while it is assembling and can be destroyed before it finishes assembling.
  • Travel
    A droid can set its destination at a certain MapPoint and proceed their in a straight line at maximum velocity. However, certain droid types can only travel at certain speeds on certain terrains; see Droid Properties for details. Once a a destination is set, the droid can perform other actions while moving, including attacking, storing, discarding, repairing, and replicating. A droid can change destinations at any time, even whilst moving.
  • Yield
    Ends a DVM's timeslice.

Droid Properties

Note that there is no property of energy and no special abilities (talents).

Type Hit Points
(stone)
Storage
(stone)
Assembly Time
(cycles)
Maximum Velocity
(spans/cycle)
Radio Range
(spans)
Radio Buffer Size
(messages)
Scion 35 50 100 0.3 land 10 10
Hemlock 100 200 500 0.0 land 50 50
Sea Dragon 65 65 250 0.5 water, 0.1 land 15 10
Beetle 40 40 200 1.0 land, water, mountain 25 10
Type Sensor Range
(spans)
Attack Range
(spans)
Attack Damage
(stone/attack)
Can travel on Can attack units on
Scion 10 5 5 Land Land, Air
Hemlock 50 10 15 cannot travel Land, Air, Water
Sea Dragon 15 3 12 Water, Land Water, Land
Beetle 20 5 7 Air Air, Land
  • Droids can exist on any terrain; terrain only affects a droid's ability to travel and to be attacked.
  • Hit points are measured in stone and equal the amount of ore necessary to initially replicate the droid and also how much damage the droid can sustain before being destroyed.
  • Storage is the amount that a droid can carry in stone, whether its cargo is ore or another droid.
  • Assembly time is the number of cycles between the time a droid is first replicated to the time it is active and can run code.
  • Maximum velocity is the maximum rate of change in the position of a droid, measured in spans per cycle.

Tournaments & Maps

Note that this section now describes this year's maps and goals.

Maps are two-dimensional arrays of grid points that are either land, water, or mountain. Mountains are impassable to both land and water units. Flying units are in the air terrain, which encompasses all three of these floor terrains. There will be two tournament maps, one for the preliminary tournament and one for the final tournament. The parameters that will remain fixed across each tournament (but may differ between the preliminaries and the finals) are:

  • Map size (a rectangle anywhere from 200x200 to 500x500 spans in size, not necessarily be a square)
  • Map terrains and layout (land, water, and mountain)
  • Number and type of starting droids (always 4, one of each type)
  • Amount and distribution of ore (500-1,000 stone total in 10-50 quantities)
  • Goal (building a mature hemlock closest to the destination point)
  • Time limit (5,000 cycles)

Parameters which will vary randomly from match to match within the same tournament are:

  • Starting location (randomly chosen from several tactically equal positions), always near water, with all four initial droids within sensor range of each other (within a radius of 10 spans, the smallest sensor range (scion)).
  • The destination point will be equidistant from each team's starting hemlock, between 400 and 500 spans away.

Ore will be distributed in small quantities (no mines) around the map; it may be located anywhere on the map on any terrain. Ore is indestructible.

Maps have a goal which is installed into every droid's handle. This year, the goal is to build a hemlock as close to the destination point as possible; the map will end whenever a Hemlock has been built within PlayerConstants.STORE_DISTANCE of the destination point (1.0 spans) or whenever the time (5000 cycles) runs out, whichever occurs first. The destination point is stored as a parameter in the goal and can be retrieved with the method Goal.getParameter(). Note that one team will have a slight advantage of having a starting hemlock closer to the destination point due to the floating-point precision of map coordinates; this advantage will be no more than 1.0 spans. The winner of a match will be the team that has a mature hemlock closest to the destination point at the end of the match. Note that we make no guarantees about the terrain of the destination point, nor the configuration of mountains, water, and land around the destination point.

In both the preliminary and final tournaments, teams will be ranked by the following ordering:

  • Number of matches won (having the closest hemlock)
  • Distance of closest hemlock to destination point

The preliminary tournament results will rank teams for the final tournament, but otherwise you start the final tournament with a clean slate.

A map has a certain number of positions called sides which can be filled by opposing teams. In all of our tournament matches, there will be two sides who will compete to proceed to the next match. Other than the information given in these specs, you will not be given any other information about the tournament maps, and you are strongly discouraged from optimising your solutions for any particular map.

Writing Your Solution

All your source files must use the same root package name. Specifically, all your source files must begin with the line:

package team<xx>;

where <xx> is the two-digit team ID number you received upon registration and which is available on the teams list page. You may use additional subpackages of your root team package if you wish.

One of your source files must be named Player.java and define the public class Player. This class, and any other player class into which you would like to reboot, must have a method with the following signature:

public static void main(DroidHandle handle)

This is the entry point into your code; you should not let execution return from this method.

Define any other modules or subpackages that you need. Make sure your code complies with the following requirements:

  1. Your team submission should use the root package teamxx.
  2. The team package should include a class named Player. This class, and any other player class into which you would like to reboot, must have the following method signature: public static void main(DroidHandle handle).
  3. The team-written source code should not make use of the Thread class, the Runnable interface, or in any way spawn more threads of execution.
  4. The team-written source code should only make use of the java.lang, java.util, and java.io implementations that we document in the contest Javadocs.
  5. The team-written source code should not interface with non-Java source code, compiled native libraries, compiled Java bytecode, or any Java source code not written by the team explicitly for this particular contest. Specifically, use of Java's Reflection classes, class loading, file system operations, and network operations is not allowed.

Example Code

For your edification, example code is dissected online.

Testing Your Solution

Note that when you test your solution with our software, you are helping us test the final game engine as well. Please report any bugs or send feedback to 6.370-devs@mit.edu.

First download and extract the jar file 6370.jar.

It will produce the following directory structure

  • 6.370/
    • classes/ - compiled bytecode of the contest software.
    • docs/ - Javadoc HTML documentation for the common classes.
    • conf/ - configuration files for the game engine
    • images/ - icons and sprites used in contest software
    • maps/ - map images
    • logs/ - server and engine log files
    • sources/ - example code
    • specs.shtml - this document

Then you can compile your solution using the provided colony.common package by including the classes subdirectory in your classpath.

In order to test your solution, you will need to configure and start the simulator by editing the plaintext file conf/sim.conf. It contains one team per line, with seven to nine comma-delimited tokens, depending on whether a team has one, two, or three members. Note that the line below has been broken to fit on the page, but in the conf file it is one line. For the engine to locate your class, be sure to include the appropriate package name for one of the teams. Currently the built-in simulator map handles exactly two teams; you must enter at least two lines in the following format (they may be the same).

<team_id>,<team_name>,<package_name>,<division>,<major_colour>,<minor_colour>,
<first_member_login>,<second_member_login>,<third_member_login>

To run the simulator, add the Sun 1.3.0 JDK by typing:

add -f java

Then go to the 6.370 root directory and type:

java -classpath .:classes:<path_to_your_classes> colony.simulator.SimClient

If you are using Windows, substitute ';' for ':' above. If you are using Cygwin, enclosing the entire classpath argument in double quotes. Note that if you forget to include the current directory in the classpath (the leading period), the JVM will not be able to find the sprites, maps, or conf files, and you will be in a world of hurt. We are aware that the current simulator is quite slow on some Athena machines; we recommend running it on one of the newer Linux boxes.

You can configure the map by reading and modifying the file maps/paleriver.map. It is a plaintext file with one directive per line; each directive has one or more parameters.

You may use your mouse to drag the map around in the scroll pane, or you may use the minimap in the lower-right corner. Units show up as green dots on the minimap and static sprites on the main map.

Submitting Your Solution

NOTE: The submission procedure has changed slightly from the preliminaries. Please read this section again.

Your submission consists of one jar file which contains all your team's source code (not bytecode) and documentation. The directory structure should look like:

  • <jar root directory>/
    • README - plaintext file describing any compilation issues, the location of any documentation or tests, and whether or not you would like to be used for academic judging.
    • Player.java - your primordial player.
    • <other source files>

Do not include any enclosing directories or directory trees, as Java compilers will generate these automatically for object bytecode.

Note that documentation is not necessary for the preliminary submission, and is only required for the final submission if you would like your entry to be judged for academic merit (note this in your README file).

To pack your solution into a jar file for submission, type:

jar cvf team<xx>.jar -C <path to files> .

Note that the trailing '.' means the current directory, not the end of a sentence :)

Note the two submission deadlines listed in boldface on the Calendar.

You should submit your jar file to your team directory in the IEEE locker, like so:

athena% add ieee
athena% cp teamxx.jar /mit/ieee/6.370/teams/teamxx/

Please do this before the submission deadline. You will receive an e-mail within a few hours after submission telling you either that your solution has been validated and successfully compiled or that there are some problems you need to fix.

Troubleshooting

If you are experiencing trouble with the software, please make sure you have downloaded the most recent version first here.

Problem: Receiving the following stack trace:

Uncaught error fetching image:
java.lang.NullPointerException
    at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:102)
    at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:111)
    at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:254)
    at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:217)
    at sun.awt.image.ImageFetcher.run(ImageFetcher.java:185)

Solution: Be sure to include the current directory, denoted by a period (.) in your classpath, as in:

-classpath .:classes

Problem: Can't find class colony.simulator.SimClient

Solution: Be sure you are using the Sun JDK 1.3.0 (or later) JVM by typing

add -f java

Problem: Can't use inherited interfaces in casts.

Solution: This is a known issue but we are unable to fix it at this time. Please modify your solution so that it doesn't have to use inherited interfaces in casts. Sorry for the inconvenience.

Helplines

First make sure your questions are not answered in these specifications (keeping in mind that they may change over time, as recorded in the Change Log). If you are experiencing problems with our software, make sure you have downloaded the latest jar file, then check the Troubleshooting section for some common remedies.

If you have a technical question about the specs of software, you can e-mail the 6.370 developers at 6.370-devs@mit.edu. If you have an administrative question about the contest, you can e-mail the 6.370 organisers at 6.370@mit.edu.

Organisers and developers may sometimes haunt the 6370 Zephyr instance. You can write to them by typing:

zwrite -i 6370

There is also an Athena mailing list (6370-discuss@mit.edu) for both teams and organisers to discuss technical issues and answer questions about the contest. We hope that competitors will help participate in the technical support effort.

Please keep in mind that 6.370 is currently completely student run, so we might not have all the resources to answer your questions. Also, the contest organizers assume you have a basic knowledge of Java and/or have reference materials to consult.

If you have a question about the Java programming language, you might want to try Sun's Java forums and tutorials at: http://java.sun.com

Appendix A: Downloads

Revision 2.8, 27 January 2003

  • Map ending fixed
  • HEMLOCK_RADIO_RANGE corrected to 50.

NOTE: Downloading with Netscape (4.7x and lower) in Windows mangles the jar file. Mozilla If you are using Windows, use another browser or file transfer method to get this file.

6370.jar, 1.0 MB

To extract this file, type:

jar xvf 6370.jar

Appendix B: Javadoc HTML Class Documentation and Examples

Javadoc-generated HTML documentation

Appendix C: Development Environment

The programming contest will be conducted entirely in the Java language. You are free to use any development platform, but your solutions must compile and run in a Sun-certified Java 2 Platform, Standard Edition 1.3. We recommend using Sun's free JDKs for Solaris, Linux, and Win32 available at: http://java.sun.com/j2se/1.3/ or IBM's Developer Kit for Linux, Java 2 Technology Edition, Version 1.3.

Specifically, we will be using IBM's high-performance Java compiler called jikes (v1.15) with Sun's 1.3.0 runtime libraries. You can learn more at the Jikes Homepage.

We recommend working on Athena workstations, which already have all the necessary tools available. However, we can provide limited support for development on private Linux and Win32 platforms using the tools described here.

To use JDK 1.3.0 on Athena (and optionally the jikes compiler) add the following to your .environment file:

add java
add jikes
setenv JIKESPATH /mit/java_v1.3.0/jre/lib/rt.jar

Then log out and log back in, or type source ~/.environment.

If you prefer to work in a POSIX-compliant environment within Windows with GNU development tools (make, cvs, etc.) we recommend the free Cygwin environment from Redhat at http://sources.redhat.com/cygwin/.

Appendix D: Configuring the Game Engine and the Statuary Map

Many parameters in the game engine and the Statuary map used in the simulator can be configured by reading and altering the plaintext conf files in the conf and maps directories, respectively.

  • sim.conf - teams used in the simulator
  • scion.conf - abilities and properties of Scions.
  • hemlock.conf - abilities and properties of Hemlocks.
  • seadragon.conf - abilities and properties of Sea Dragons.
  • beetle.conf - abilities and properties of Beetles.
  • ore.conf - abilities and properties of Ore.

Change Log

  • 1.0—6 January 2003:
    Initial revision.
  • 2.0—13 January 2003:
    New goal and maps. Sea dragon no longer starts in water.
  • 2.5—14 January 2003:
    New reference player released. MapPoint and Moniker now implement Comparable for use in collections, the equals method, and the hashCode method. Ore naming bug fixed in statuary1.map. Clarification: matches are won by the closest mature hemlock to the goal point.
  • 2.6—20 January 2003:
    Droid starting positions fixed to be within circle with radius of 10 spans; map shape clarified to be rectangular. Seeding tournament format corrected to single-elimination, as described in the contest rules; ranking of teams in both tournaments in clarified. Droid properties clarified to include allowed travel terrains and allowed attack terrains. Inherited interfaces cannot be used in casts. No guarantees are made about terrain of destination point or the terrains around it.
  • 2.7 - 22 January 2003
    Preliminary map released.
  • 2.8 - 27 January 2003
    Map ending fixed. PlayerConstants.HEMLOCK_RADIO_RANGE corrected to 50. Submission procedure changed.