Robo Home | Changes | Preferences | AllPages


Robocode Processing Loop

The order that Robocode runs is as follows:

  1. All robots execute their code until taking action
  2. Time is updated (currentTime++)
  3. All bullets move and check for collisions
  4. All robots move (heading, accel, velocity, distance, in that order)
  5. All robots perform scans (and collect team messages)
  6. The battlefield draws

Time and distance measurements in Robocode

Time (t) Robocode time is measured in "ticks", which are equivalent to frames displayed on the screen. Each robot gets one turn per tick. 1 tick = 1 turn = 1 frame.

Distance Measurement Robocode's units are basically measured in pixels, with two exceptions. First, all distances are measured with double precision, so you can actually move a fraction of a pixel. Second, Robocode automatically scales down battles to fit on the screen. In this case, the unit of distance is actually smaller than a pixel.

Robot Movement Physics

Acceleration (a) Robots accelerate at the rate of 1 pixel/tick. Robots decelerate at the rate of 2 pixels/tick. Robocode determines acceleration for you, based on the distance you are trying to move.

Velocity Equation(v) v = at. Absolute velocity can never exceed 8. Note that technically, velocity is a vector, but in Robocode we simply assume the direction of the vector to be the robot's heading.

Distance Equation (d) d = vt.

Robot, Gun, and Radar rotation


Robot Collisions

In short: when two robots collide, each takes .6 damage. If either of them is moving toward the collision, it will be stopped and awarded ram damage for scoring. If they are both moving toward each other, they will both take 1.2 damage and both be awarded .6 for scoring.

In detail: a robot is moving "toward" the collision if its velocity is non-zero and less than 90 degrees away from the enemy. Each bot takes turns (in a random order each tick) deciding if it collided with another, by determining if its bounding box intersects that of another on the field (after they have all moved for that tick). When an intersection is found, and the bot is at fault, it gets moved back to its original position. Therefore, it is possible that even if the second bot moved toward the collision it will not detect it because the bounding boxes no longer intersect, and therefore not be awarded the ram damage for scoring.

Wall Collisions

AdvancedRobots? take Math.abs(velocity) * .5 - 1 damage (but never < 0)

Bullets Hitting Robots

Robots are 36x36 squares centered on the (x,y) coordinate. Even when you have rotated, you collide with walls and robots and are hit by bullets based on 18 pixels in all four directions. Bullet collisions are based on whether the line between the bullet's last position and its new position intersect that square.

Note: If you are using virtual bullets and taking a short cut of estimating a hit based on a bullet passing within 18 pixels distance (as though the Tank were a circle) you are losing a significant amount of area. A robot has an area of 1296 pixels (square) as opposed to a circle of 18 radius having an area of 1018, or about 79%. -- Martin Alan Pedersen

I think a quick way to get around this would be to model your virtual bullets as Point2D objects and the other bot as a 36x36 Rectangle2D. Then you can just use the Rectangle2D.contains(Point2D) method to check for hits. I used this method in Stampede, which feeds its gun data with VBs.--wcsv

I don't check for collisions with a bot, I just mark down the angle the gun shot at on the virtual bullet (actually, I use a factor index, but it works the same); when the virtual bullet / wave passes the bot, I find the min and max angles that would have hit the bot, and check if the angle was between those. It seems quite a bit less CPU intensive to do it this way, and it fits well into my wave-based targeting systems... (I highly doubt I'm the first to do it this way.) -- Voidious

That is indeed what I do with waves in PowerHouse, but using VBs that way is essentially the same as using waves; at least the way I understand it. --wcsv

Theres alot of good stuff on the [Robocode FAQ] with regards to physics. I will try to include this stuff and rework the page if I have time -- Jokester

Does anyone know if there is a size limit fo team message, because my bot throws exception when I try to broadcast my hashmap containing all the scan stores of the last survivor at the begining of the next round. Note that all the objects contained in the hash map are serializable. -- Florent

I will try those ideas, but I have some doubts regarding Loki's one. -- Florent

Why do you doubt that it works? --Loki

I remember reading that Robocode loads each bot with a separate classloader. This elimates the possibility of reading into another bot's statics and allows bots of the same class to compete in the same battle without static variable conflicts. (It also takes away your ability to share statics.) So, you are correct about Java statics but Robocode hijacks their behavior for its own purposes. --Corbos

I found this info on JavaAPI as well.

I'm working on team play right now... look for it soon. Messages will be
through serializable objects.

A static class works fine? This is a bug, if that's the case.
Each robot is loaded in a separate classloader to prevent this.


-- Florent

ok, thanks for the info. So there is room for a little improvement. --Loki

I think there is a size limit, after a few experiment here is what I get when I transfer the gun date at the begining of round 2.

java.io.IOException: Buffer is full.
    at robocode.io.BufferedPipedOutputStream.write(BufferedPipedOutputStream.java:54)
    at java.io.OutputStream.write(Unknown Source)
    at java.io.ObjectOutputStream$BlockDataOutputStream.write(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)

After looking at code on sourceforge, I found that the limit is 32768 bytes and it is set in robocode.peer.robot.RobotMessageManager.java.

-- Florent

A quick question: From the list at the top of this page, it looks like a bot's max turn rate is computed using the previous tick's velocity. Is that right? (this is probably really obvious, so I apologize in advance) --wcsv

You are correct. Your turn rate is based on your velocity before acceleration / deceleration. The distance you travel is based on your adjusted velocity though. -- Martin

I think I've found a way to (sort of) exploit the movement system. A robot's acceleration is one, but its deceleration is 2. This means going from velocity 2 to 0.1 to -1.9 is faster than going 2 to 0 to -1. I don't know of any robots that do this, but it could be useful trick for moving a little faster. Does this work? -- Kev

Probably - I know a tank can vibrate between 1 and -1 velocities. Not sure it's worth the trouble of implementing it, but a neat idea for sure :) -- Voidious

You could probably use it to throw off people using guess factors. You'd be able to squeeze 7-8 additional units of distance if you went from -2 to -0.00001 to 1.99999 rather than -2 to 0 to 1. The additional nearly 1 unit of velocity would give you that edge. If someone were limiting their guess factors to aim for your rear corner rather than your center they be hard pressed to hit you, and you might even make them throw an exception. Still, that's a very small set of bots (if any at all). -- Martin

FYI your suspicions were correct, that does indeed work. I tried it. A small trick to increase escape angles. Nice thought, Kev! -- Simonton

Thanks! Although it might be a lot of work to implement (in WaveSurfing at least), every little improvement counts. -- Kev

One thing I thought worth noting is that onHitByBullet? events are not sent immediately upon being hit by a bullet. They are sent after all of your instructions have been processed (e.g. movement, turret rotation). They are also sent before onScannedRobot events. The significance of this is that calls to this.getX(), for example, don't reflect the robot's position at the time of being hit, even though you are calling it while processing an onHitByBulletEvent?. It is your bots position after being hit and then moving. In the event that the bullet killed you and you can't move, I think that rather than getting an onHitByBullet? event you are instead given an onDeath event. In the event that your energy is <= 0.0, you can't move anyway so the observation is moot. -- Martin

About the Collisions part from above - if you are moving away from the collision, it will not be stopped - what exactly does that mean? Does it mean when you hit a robot and you try to move away, you can't? --Starrynte

I think it refers to another robot rear-ending you - in that case, you shouldn't abruptly stop (they will, though). -- Kawigi

A question: Sometimes when ramfire hits my bot, my bot is "stuck" to ramfire and can't move away. Sometimes it can move away, though. Does it have to do with e.isMyFault?()? --Starrynte

[v1.5.4] I was under the impression that you were not allowed to fire bullets with less than 0.1 energy, but in testing just now one of my bots fired a shot in round 735 with a power of 0.06049954275264291. That is the power returned by the event's bullet.getPower() method, reported from both the BulletHit? and HitByBullet? events, from their respective perspectives. I speculate that the shot was fired immediately after being hit by a bullet, and the host didn't bother to check the firepower constraints. Alternatively, it may be that a robot can fire it's last energy regardless of the 0.1 constraint. -- Martin

Yes, I think the only time a robot can fire less than 0.1 power bullets is when firing the bullet disables the bot. I've tried specifying less than 0.1 and it didn't work =) -- Skilgannon

Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited September 5, 2008 4:04 EST by Simonton (diff)