Robot Wars 2025 – Documentation

Build. Battle. Improve.

📑 Table of Contents

Overview

Robot Wars 2025 is a real-time robot battle game where you build strategies using easy, drag‑and‑drop blocks. Create your program, send your robot into the arena, and see whose strategy wins.

Good to know:
  • Four execution lanes run in parallel: Thread 1, Thread 2, Event Handlers, and Custom Blocks.
  • All angles are in degrees (0°=East, 90°=North, 180°=West, 270°=South).
  • Each match lasts up to 5 minutes or until a robot's health reaches 0.
  • Use hit_obstacle to detect collisions with walls, rocks, and turrets.

Getting Started

Match Rules

Understanding the Four-Thread System

Robot Wars uses a powerful four-lane execution model that allows your robot to multitask and respond to events in real-time.

The Four Execution Lanes

🧵 Thread 1 (Main Logic)

Your primary logic lane. Typically used for movement patterns, positioning, and main strategy loops.

🧵 Thread 2 (Secondary Logic)

Runs in parallel with Thread 1. Commonly used for combat logic: scanning, aiming, and firing.

⚡ Event Handlers

Special blocks that trigger automatically when specific events occur (getting hit, hitting an enemy). Run independently of threads.

📦 Custom Blocks

Reusable subroutines you define once and call from any thread or event handler. Great for reducing code duplication.

How Threads Work Together

Common Thread Patterns

🎯 Recommended Thread Usage:
  • Thread 1: Movement and positioning
    • Patrol patterns (square, circle, random)
    • Evasive maneuvers
    • Collision avoidance using hit_obstacle
    • Positioning relative to enemies
  • Thread 2: Combat and targeting
    • Continuous scanning for enemies
    • Aiming at detected targets
    • Firing when in range
    • Tracking enemy movement
  • Event Handlers: Reactive behaviors
    • when_hit: Dodge, return fire, or call for help
    • when_i_hit_enemy: Celebrate, track hits, adjust strategy
  • Custom Blocks: Reusable subroutines
    • "evade_hit" - Complex evasion maneuver
    • "scan_and_fire" - Combined scan + aim + fire sequence
    • "return_to_center" - Navigate back to arena center

Example: Dual-Thread Strategy

Thread 1 (Movement):              Thread 2 (Combat):
repeat 100 times                   repeat 100 times
  move_up 100 pixels                 scan (range: 400)
  if hit_obstacle = true             if enemy_detected = true
    then                               then
      move_down 50 pixels                aim_variable enemy_direction
      move_right 50 pixels               fire
      set hit_obstacle to false        wait 0.1 seconds
  wait 0.5 seconds

In this example, Thread 1 handles movement and collision avoidance while Thread 2 continuously scans and fires at enemies. Both run simultaneously!

Using hit_obstacle for Collision Detection

The hit_obstacle system variable is your robot's primary way to detect when it has collided with an obstacle, allowing you to implement intelligent collision avoidance.

What Triggers hit_obstacle?

The hit_obstacle variable is automatically set to true when your robot collides with:

How hit_obstacle Works

⚙️ Collision Detection Flow:
  1. Movement Attempt: Your robot tries to move (e.g., move_forward 100)
  2. Collision Check: The game engine checks if the new position would collide with an obstacle
  3. If Collision:
    • Movement is blocked (robot stays in place)
    • hit_obstacle is set to true
  4. If No Collision:
    • Movement succeeds (robot moves to new position)
    • hit_obstacle remains false (or stays true if previously set)

⚠️ Important: You Must Reset hit_obstacle!

Critical: Once hit_obstacle is set to true, it stays true until you manually reset it to false. The game engine does NOT automatically reset it!

🚨 Common Mistake:

If you don't reset hit_obstacle to false after handling a collision, your robot will think it's stuck forever and your evasion logic will keep triggering!

Basic Collision Avoidance Pattern

Thread 1:
repeat 100 times
  move_forward 100 pixels
  
  if hit_obstacle = true
    then
      // Evasion maneuver
      move_backward 50 pixels
      turn_right 45 degrees
      
      // CRITICAL: Reset the flag!
      set hit_obstacle to false
  
  wait 0.2 seconds

Advanced Collision Avoidance Example

Thread 1:
repeat 100 times
  move_toward_variable enemy_direction for 50 pixels
  
  if hit_obstacle = true
    then
      // Call custom evasion block
      call my block "evade_hit"
      
      // Reset flag after evasion
      set hit_obstacle to false

Custom Block "evade_hit":
  // Back up
  move_backward 30 pixels
  
  // Try moving perpendicular to current direction
  turn_right 90 degrees
  move_forward 50 pixels
  
  // If still stuck, try opposite direction
  if hit_obstacle = true
    then
      turn_right 180 degrees
      move_forward 50 pixels

Using hit_obstacle with Turrets (Levels)

In Levels mode, turrets are solid obstacles. You can use hit_obstacle to detect when you've bumped into a turret, then back up and destroy it:

Thread 1:
repeat 100 times
  move_forward 100 pixels
  
  if hit_obstacle = true
    then
      // Back up to get firing distance
      move_backward 80 pixels
      
      // Scan to detect the turret
      scan
      
      // If turret detected, destroy it
      if nearest_turret_detected = true
        then
          aim_variable nearest_turret_direction
          repeat 5 times  // Turrets need 5 hits
            fire
            wait 0.2 seconds
      
      // Reset flag
      set hit_obstacle to false

Best Practices

Debugging hit_obstacle Issues

If your robot seems stuck or keeps executing evasion logic:

Levels & Scoring

Challenge yourself against AI opponents in progressively harder levels. Earn points for every hit and level completion!

How to Play Levels

Scoring System

Your score accumulates across levels in a single session:

💥 Hit Score: 200 Points

Earn 200 points for each successful hit on an AI bot (10 points × 20 damage).

💣 Turret Destruction: 500 Points

Earn 500 bonus points for destroying a turret (requires 5 hits). Destroyed turrets stop firing.

🏆 Victory Bonus: 1,000 Points

Earn 1,000 bonus points for completing a level (destroying all AI bots).

🔫 Turret Mechanics:
  • Turrets have 5 health points - requires 5 direct hits to destroy
  • Hit counter appears above turret showing progress (1/5, 2/5, etc.)
  • Destroyed turrets explode and stop firing
  • Use scan to detect turrets and get their direction/distance
  • Strategic tip: Eliminate turrets early to reduce incoming fire

Score Display

How Scoring Works

Per-Level Scoring:
  • Each level tracks its own score independently - your score resets to 0 when starting each new level
  • Best score saved: Your highest score for each level is saved to your account
  • Replay anytime: Replay any unlocked level to improve your high score
  • Leaderboards: Compete for the top score on each individual level
  • Total Levels Points: Your profile shows the sum of your best scores across all levels

Level Difficulty

Tips for Success

Saving & Loading Robot Programs

Robot Wars provides multiple ways to save and manage your robot programs.

Save to Database (Cloud)

Export to Disk (Local Backup)

Import from Disk

JSON File Format

Exported robot programs use the following JSON structure:

{
  "name": "MyRobot",
  "description": "",
  "program": {
    "visualProgram": {
      "thread1": [
        {
          "command": "scan",
          "params": {}
        },
        {
          "command": "aim_variable",
          "params": {
            "variable": "enemy_direction"
          }
        },
        {
          "command": "fire",
          "params": {}
        }
      ],
      "thread2": [
        {
          "command": "move_to_xy",
          "params": {
            "target_x": 0,
            "target_y": 0
          }
        }
      ]
    },
    "dualThreadProgram": { ... },
    "userVariables": {
      "my_var": {
        "type": "persistent",
        "value": 100,
        "numericValue": 100
      }
    }
  },
  "exportedAt": "2025-01-07T14:30:00.000Z",
  "version": "1.0"
}

JSON Structure Explained

💡 Pro Tip: You can manually edit JSON files in a text editor to make bulk changes or create robots programmatically!

Downloading Battle Replays

After every battle, you can download a comprehensive JSON replay file containing complete battle data. This is especially useful for analyzing strategies, training AI models, or developing robot programs externally.

How to Download Replays

What's Included in Replay Files

Each replay file contains comprehensive battle data in JSON format:

🤖 Robot Programs

The actual thread1/thread2 command structures used by both players - perfect for studying winning strategies!

📊 Battle Events

Frame-by-frame events including game updates, bullet fires, robot hits, and more.

📈 Game State Frames

Complete snapshots of robot positions, health, bullets, and obstacles at regular intervals.

ℹ️ Metadata

Battle configuration including duration, winner, timestamps, game speed, and player information.

Use Cases for Replay Files

Replay File Structure (Simplified)

{
  "metadata": {
    "battleId": "abc123",
    "battleType": "ai",
    "duration": 120000,
    "timestamp": "2025-01-21T..."
  },
  "players": [
    { "name": "MyRobot", "isAI": false },
    { "name": "AI Bot", "isAI": true }
  ],
  "winner": { "name": "MyRobot" },
  "programs": [
    {
      "robotName": "MyRobot",
      "program": {
        "thread1": [ ... ],
        "thread2": [ ... ]
      }
    }
  ],
  "events": [ ... ],
  "frames": [ ... ]
}
📚 Advanced Documentation:

For detailed technical documentation on the replay format, including complete schema reference and LLM training workflows, see the Battle Replay Format Documentation.

You can also download the documentation file for offline reference.

Tips for Using Replay Files

Controls & UI

Templates & AI Co‑Pilot

Commands Reference

Below are the supported blocks/commands and how to use them. Some commands also accept variables or computed values via math/variable blocks.

Movement

move_up / move_down / move_left / move_right

Move the robot by N pixels in the given cardinal direction. Speed limit: 100 pixels per command.

move_forward / move_backward

Move the robot forward or backward relative to its current angle by N steps (10 pixels per step). Speed limit: 100 pixels per command.

move_to_xy

Move the robot to specific (X, Y) coordinates. Auto-continuing movement at 50px per cycle. Automatically continues until target reached or obstacle hit. No loop required! Params: target_x, target_y (range: -500 to 500).

move_toward_degrees

Move a distance toward an absolute angle. Speed limit: 100 pixels per command. Params: angle (deg), pixels.

move_toward_variable

Move toward the angle stored in a variable (degrees). Speed limit: 100 pixels per command. Params: variable, pixels.

wait

Pause this thread for N seconds.

⚡ Movement Speed Explained:
  • move_to_xy uses auto-continuing movement - moves 50px per cycle and automatically repeats until reaching the target. No loop needed!
  • Other movement commands (up/down/left/right) are capped at 100 pixels per execution for tactical control.
  • To move more than 100 pixels with standard commands, use them multiple times or place in a repeat loop.

Combat & Aiming

fire

Fire the cannon at the current aim direction. Damage ~20 HP on hit.

scan

Scan for enemies, mines, and turrets within 400px range. Updates multiple system variables (see below).

set_cannon_angle

Instantly aim the cannon to an absolute angle (deg).

move_cannon_cw / move_cannon_ccw

Rotate the cannon by N degrees clockwise/counterclockwise.

aim_variable

Aim the cannon using an angle stored in a variable (deg). Param: variable.

📡 Scan Function Details:

The scan command detects enemies, mines, and turrets within a 400-pixel radius and updates these system variables:

  • Enemy Detection:
    • enemy_detected - Boolean (true/false)
    • enemy_distance - Distance in pixels to nearest enemy
    • enemy_direction - Direction in degrees to nearest enemy
    • most_recent_enemy_direction - Last known enemy direction (persists after enemy leaves range)
    • previous_enemy_direction - Direction from scan before the most recent one
  • Mine Detection (Levels only):
    • nearest_mine_detected - Boolean (true/false)
    • nearest_mine_distance - Distance in pixels to nearest mine
    • nearest_mine_direction - Direction in degrees to nearest mine
  • Turret Detection (Levels only):
    • nearest_turret_detected - Boolean (true/false)
    • nearest_turret_distance - Distance in pixels to nearest active turret
    • nearest_turret_direction - Direction in degrees to nearest active turret

Note: Only active turrets (health > 0) are detected. Destroyed turrets are ignored.

Control & Logic

repeat_container

Repeat nested commands a fixed number of times. Param: count (a.k.a. times).

repeat_until

Repeat nested commands until a condition is met. Params: condition, operator, value, plus nested commands.

if_then

Run nested THEN commands if a condition is true. Params: condition (or variable), operator, value.

if_then_else

Run THEN or ELSE nested commands based on a condition. Same parameters as if_then.

Variables & Math

set_variable_to_value

Set a variable to a literal value (number/boolean) or a system variable.

set_variable_to_variable

Copy the value of one variable to another.

add_to_variable

Compute target = source op number. Operators: +, −, ×, ÷.

math_function

Apply a math function using variables. Params: targetVariable, mathFunction, sourceVariable.
Functions: sin, cos, tan (input in degrees); arcsin, arccos, arctan (output in degrees); abs, int.

Events

Event handlers are special blocks that run automatically when specific game events occur. They execute independently of Thread 1 and Thread 2.

when_hit

Event container: runs nested commands when your robot is hit by an enemy bullet. Triggers immediately upon taking damage.

Common uses: Evasive maneuvers, return fire, health monitoring, defensive positioning.

when_i_hit_enemy

Event container: runs nested commands when your shot successfully hits an enemy robot. Triggers immediately upon confirmed hit.

Common uses: Continue firing, track hit count, aggressive pursuit, celebration.

⚡ Event Handler Details:
  • Independent Execution: Events run separately from Thread 1 and Thread 2. They don't block or pause your main threads.
  • Immediate Trigger: Events fire as soon as the condition occurs (getting hit, hitting enemy).
  • Shared State: Events can read and modify the same variables as your threads.
  • Multiple Events: You can have both when_hit and when_i_hit_enemy active simultaneously.
  • Nested Commands: Place any commands inside event blocks - they'll execute when the event triggers.

Example: Reactive Combat with Events

Thread 1 (Movement):           Thread 2 (Combat):           Event: when_hit:
repeat 100 times               repeat 100 times             // Dodge when hit!
move_forward 100 pixels        scan                         turn_right 90 degrees
if hit_obstacle = true         if enemy_detected = true     move_forward 80 pixels
  then                           then                       turn_left 45 degrees
    move_backward 50 pixels        aim_variable enemy_dir
    turn_right 45 degrees          fire                     Event: when_i_hit_enemy:
    set hit_obstacle to false    wait 0.1 seconds           // Keep firing!
wait 0.3 seconds                                            fire
                                                            wait 0.1 seconds
                                                            fire

In this example, the robot patrols and fires normally, but immediately dodges when hit and continues firing when it lands a hit!

Custom Blocks

Custom blocks let you define reusable subroutines that can be called from any thread or event handler. This is the fourth execution lane in the system.

define_myblock

Define a named sequence of commands you can reuse. Nested contents become the block's body. The block doesn't execute until called.

Param: blockName - Unique name for your custom block (e.g., "evade_hit", "scan_and_fire")

call_myblock

Execute a previously-defined custom block by name. Can be called from Thread 1, Thread 2, or event handlers.

Param: blockName - Name of the block to execute

📦 Custom Block Benefits:
  • Code Reuse: Write complex logic once, use it everywhere
  • Cleaner Code: Keep threads focused by extracting common patterns
  • Easier Debugging: Fix bugs in one place instead of multiple copies
  • Modular Design: Build libraries of useful behaviors

Example: Custom Block for Evasion

Custom Block "evade_hit":
  // Back up from obstacle
  move_backward 40 pixels
  
  // Try right
  turn_right 90 degrees
  move_forward 60 pixels
  
  // If still stuck, try left instead
  if hit_obstacle = true
    then
      turn_left 180 degrees
      move_forward 60 pixels
  
  // Reset collision flag
  set hit_obstacle to false

Thread 1:
repeat 100 times
  move_forward 100 pixels
  if hit_obstacle = true
    then
      call my block "evade_hit"  // Reuse the evasion logic!
  wait 0.2 seconds

Event when_hit:
  call my block "evade_hit"  // Same evasion when hit by bullet!

Example: Custom Block for Combat

Custom Block "scan_and_fire":
  scan
  if enemy_detected = true
    then
      aim_variable enemy_direction
      fire
      wait 0.1 seconds
      fire  // Double tap!

Thread 2:
repeat 100 times
  call my block "scan_and_fire"
  wait 0.3 seconds

Event when_i_hit_enemy:
  // Hit confirmed! Keep pressure on!
  call my block "scan_and_fire"

Best Practices for Custom Blocks

System Variables Reference

System variables are automatically updated by the game engine and can be used in conditionals, math operations, and movement commands.

Position & Orientation

Robot Status

Enemy Detection (from scan)

Mine Detection (Levels only, from scan)

Turret Detection (Levels only, from scan)

Special Variables

💡 Usage Tips:
  • Boolean variables (enemy_detected, hit_obstacle, nearest_mine_detected, nearest_turret_detected) can only be compared to "= true" or "= false" in conditionals.
  • Numeric variables (distances, directions, positions, health) can be compared using >, <, =, or ≠ operators.
  • Direction variables are in degrees using mathematical coordinates: 0°=East, 90°=North, 180°=West, 270°=South.
  • Scan frequently to keep enemy/mine/turret detection variables up to date.
  • Use most_recent_enemy_direction to pursue enemies that move out of scan range.
  • Use Thread 1 for movement patterns (patrol/kiting) and Thread 2 for aiming and firing.

FAQ

Q: My robot doesn’t move.
A: Make sure a Movement block is in Thread 1 or 2 with a non‑zero distance.

Q: My robot keeps missing shots.
A: Use scan to update enemy_direction and aim toward that angle before firing.

Q: The IF condition never triggers.
A: Check the operator and value type (number vs. boolean). For example, enemy_range < 200 uses a numeric value.

Q: My score reset when I started a new level.
A: Each level tracks its own score independently. Your best score for each level is saved to your account.

Q: I can't beat a level.
A: Try different strategies: kiting (hit and run), corner camping, or aggressive rushing. Use the Templates for inspiration.

Q: How do I unlock more levels?
A: Complete the previous level to unlock the next one. Level 1 is always unlocked.

Examples

Two quick patterns expressed in blocks: