How to write a sockey team

Here's everything you need to know to write your own sockey team:
  1. The game field
  2. RoboSockey rules
  3. Finding your way around
  4. Controlling your player
  5. Sending messages
  6. Setting up to write a team
  7. What you need to write
  8. Testing your team

The SoccerClient API

Send suggestions/comments to wessler@ai.mit.edu.


Quick and dirty instructions


The Game Field

RoboSockey is played on an enclosed field with rounded corners:

The sizes of the lines on the field are all related to the field height. (Because the field is layed out with its major axis pointing horizontally, the "height" measurement is what you may be more used to calling "width". Sorry. Live with it.)

The center circle has a diameter of (height/2), and a radius of (height/4). The goalie zones start at (height/6) from the edges, and stick out (height/3) from the back wall. The goal is currently set at a width of (height/3), although this value may change.

Forward is in the +x direction. The forward angle is 90 degrees. Reverse is -x or 270 degrees, or (equivalently) -90 degrees.

If your player is facing forward, then right is at 0 degrees, in the +y direction. Left is therefore at 180 degrees, in the -y direction. All of these coordinates are shown in pink in the picture above.

You should always write code as if you are the orange (left-hand-side) team. If your team happens to be blue, the physics server will automatically convert all coordinates to look as if your team were on the orange side.


RoboSockey Rules

Each team has six players: a center, two forwards, two defensemen, and a goalie. Once every player has lined up, the ball will appear in the kickoff spot (which appears as a small green circle in the middle of the field), and play begins. [Note: although the positions have been given descriptive names, there is no need to make the players behave as their name suggests. Only the goalie has special privaleges, described below.]

The idea, of course, is to kick the ball into the other team's goal, while preventing the other team from getting the ball into your own goal. To kick the ball, a player must hit it with the solid half of its body. The ball can slide right into the empty half, but other players bounce off. A player can give the ball a good strong kick by spinning its flat edge into the ball. Run the game a few times to see how this works.

Periods
There are two halves. Each half lasts 5 simulated minutes, at 60 frames per simulated second. The real-time speed of the game depends on the speed of your processor and your Java VM implementation.

Game time does not advance after a goal, or while the sides are setting up for a free kick. If any player does not get into position and signal the referee that it is ready after a significant amount of time, the game is declared void, and the simulator quits. Players have about 60 simulated seconds to get into position (more than enough time).

The length of a period can be set as an applet parameter.

Kickoff
Kickoff happens at the beginning of each half, and whenever a team scores a goal. The orange team kicks off at the start of the first half; the blue team kicks off at the start of the second half, and any team that gets scored on kicks at the next kickoff.

At any kickoff, every member of the team must be on its half of the field, and the receiving members must be fully outside the kickoff circle (height/4+getRadius() away from the kickoff location). There are no other restrictions, but the default player lines up as shown above.

Penalties
There are three conditions under which play is stopped and a free kick awarded.

If the ball is within or partially within any player's empty half for 3 consecutive simulated seconds without the player touching it, the opposing team is awarded a free kick from the ball's current position. If the ball would have been kicked off by a team from within its large goalie box, the kickoff position is moved to the nearest corner of the goalie box.

If the ball is within or partially within the goalie's empty half for 3 consecutive simulated seconds without the goalie touching it, then the goalie's team gets a free kick from the closest corner of the goalie's large box. This rule is only in effect if the goalie is within the large goalie box.

If the ball is within the small goalie's box and the goalie does not touch the ball for 5 consecutive simulated seconds, then the opposing team is awarded a free kick from the center of the far edge of the goalie box.

Free Kicks
During a free kick, the kicking team may position itself wherever it wishes; the other team must be at least height/3 from the kickoff location.

Weird effects
If the ball is within or partially within a player's empty half, that player's acceleration strength is reduced to about 80% of other players. This is meant to emulate the concentration a real player might need to dribble the ball.

The goalie is twice as strong as every other player as long as it is within the larger goalie box. The goalie may leave this box, but its power is reduced to that of the other players while it is outside.

The goalie's inner box has a force field around it that keeps all other players (of both teams) out of the goalie's way. The force field begins somewhat beyond the marked lines, and builds up in strength to prevent a single player from staying inside the goalie's inner box. Multiple players could probably line up to push a single player within the box, but the goalie could easily knock them aside.


Finding your way around

To navigate, your player "pings" one of a large number of invisible beacons on the field. Your player refers to these beacons by their ping ID, and can get either the (x, y) distance to the beacon, or the straight-line distance and angle to the beacon. [For more on the coordinate system of the game field,
see above.] The lettered beacons are described below:

A: ID_BALL The ball location
B: ID_CENTER The center of the field
C: ID_THEIR_GOAL_LEFT The left-hand corner of the other team's goal.
D: ID_THEIR_GOAL The center of the opposing team's goal line.
E: ID_THEIR_GOAL_RIGHT The right-hand corner of the other team's goal
F: ID_OUR_GOAL_LEFT The left-hand corner of our team's goal
G: ID_OUR_GOAL The center of our team's goal line
H: ID_OUR_GOAL_RIGHT The right-hand corner of our team's goal
Wall beacons are located at the point on the wall closest to the player.
J: ID_LEFT_WALL The closest spot on the left-hand wall
K: ID_RIGHT_WALL The closest spot on the right-hand wall
L: ID_FWD_WALL The closest spot on the other team's goal line
M: ID_BACK_WALL The closest spot on our team's goal line
N: ID_KICKOFF_LOC Where the ball will be placed for the next kickoff or free kick
Beacons are also attached to every player on the field. You are not obliged to make your players behave as their names suggest.
0: ID_PCTR The center player
1: ID_PFWDL The left-side offensive player
2: ID_PFWDR The right-side offensive player
3: ID_DEFL The left-side defensive player
4: ID_DEFR The right-side defensive player
5: ID_GOALIE The goalie.
To ping a player on the opposing team, add the constant THEIR_TEAM to the player IDs given above.


Controlling your player

Players move by accelerating in a certain direction with a certain strength. Players spin by specifying a desired angle.

Think of acceleration as if each player is a space ship. To move to a specific point, find the angle from the player to the point, and accelerate in that direction. When you stop accelerating, the player will take a while to slide to a stop; it's often a good idea to check the distance against your player's velocity. Make a "guesstimate" of where the player will be in several steps, based on its current location and velocity. If your guesstimate is beyond the point you'd like the player to stop at, accelerate in the opposite direction.

The wannabe function incorporates this idea.


Sending messages

Good team members coordinate their actions instead of acting independently all the time. Your player can send messages to any or all of the other members of your team through the sendMessage and receiveMessage methods.

For example, suppose each player on your team needs to know where all the other players on your team are (perhaps so you don't all bunch up). You might keep the current locations of all of the players in an array. You could have each player ping every other player at each time step, but this is a tremendous waste of time. It makes much more sense to have each player figure out where it itself is, and then broadcast that location to each of the other players.

Here's how it might work. As the first part of the player's step, it pings the ID_CENTER beacon. It now sends this location as a message to the entire team (including itself).

The receiveMessage method identifies the ID of the sender, along with the message. In this case, the message is simply the location of the sender, so you can put the information in its proper place in the array.

Instead of each player making six pings, each player only makes one ping, and shares the information with the other players.

[Knowledgeable Java programmers will be tempted to use static class variables to pass data around. Through the magic of Java reflection, the sockey server will detect this and disallow your player. You must use the sendMessage / receiveMessage method for communication.]


Setting up

Get in touch with your team Sockey sub-captain. Your sub-captain will tell you where to create your team directory. The directory must have the same name as your Sockey team. You or your sub-captain can edit the html file to tell the sockey applet about your team. Now you're ready to start programming!

Each java class must be in the package MyTeam (or whatever you chose your team name to be). To create a player, extend sockey.SoccerClient, and override the step method. If you want to be clever, you can also override freekick, receiveMessage, or regroup.

You can use a template file to help you get started. There is also full player code for (in incresing code complexity) a Goalie, a Wanderer, and a Forward, all from the Flash sockey team of an imaginary Riddlers olympics team.


What you need to write

Each of your players is a subclass of the SoccerClient class [
API]. To make your player do anything, you will need to override the step method. This method should think briefly about what to do, do it, and exit. The step method (or one of the other two methods below) will be called repeatedly until the game is over. If you don't override anything, you'll get a fully functional placebo.
public void step()
This method gets called while the game state is GAME_PLAYING. By default, this method doesn't do anything, and your players will just sit there like idiots. Override this to make your player do something interesting (like scoring goals).

public void freekick()
This method gets called while the game state is GAME_FREEKICK. The default behavior of this method is to send every player except the goalie a distance of height/3 away from the kickoff location. Depending on the kickoff location, one player from the kicking team (either the left defender, the right defender, or the center) will approach the ball for the kick. If you'd like the other players to do something interesting, override this method.

public void regroup()
This method gets called when the game state is GAME_STARTING or GOAL_SCORED. By default, each player moves to its standard starting position. If you don't like the standard starting position, you can have the players move to other locations, or even have them wander around.

The only other overridable method is receiveMessage(int from, String message, int a, int b, int c). If your players talk to each other, you'll need to override this method to do something interesting with the information.

You'll definitely want to check out the full API of SoccerClient.

To add some pizaz to your team, create a gif or jpg logo for your team. This logo must be called team.gif or team.jpg. Put it in the directory with your team file (see below) and .class files. For best results, make the logo 32x32 pixels, although the logo can be any size you want.


Testing your team

Once you've written your player classes, you'll want to test them to see if they work, and how well they play. To do this, you'll first need to create a file that tells the sockey applet what class to assign each player. This is called the team file. See the
team file documentation page for information on how to write this file.

If you've set up your CLASSPATH environment variable correctly, you just need to type java Sockey Spider.MyTeam if you're on the Spiders and your Sockey team is called "MyTeam". If you want to see your team play against someone else, include their sockey team after yours as another argument.

There are a few extra flags you can supply to the Sockey application. Try java Sockey -help to list them.

Your team sub-captain may have set up an applet file so that you can run the full interface. If so, you'll need to edit the applet file so that it knows about your team. (The applet file is probably called "applet.html" in your $TEAM_DEV_DIR).

Let's suppose the name of your team is "MyTeam". The applet needs to look like this:

<applet archive="SoccerApp.jar" code="SoccerApplet.class" width=500 height=180>
<param name="TEAMS" value="MyTeam">
</applet>

If you have more than one team that you'd like to add to the list, use a vertical bar ( | ) to separate the names:

<param name="TEAMS" value="MyTeam|GoodGuys">

To run the applet, use appletviewer applet.html