Quick Start
Get started with radarcontrol.io in 5 minutes.
Your First Script
When you open radarcontrol.io, you'll see the default script already loaded. Here's what it does:
onSpawn((aircraft) => {
log(`${aircraft.cs} (${aircraft.type}) at FL${aircraft.altFL}`);
// Set up handover at exit
aircraft.over(aircraft.plan.exitPoint, (ac) => {
ac.handover();
});
});This code:
- Logs when each overflight aircraft spawns from entry points
- Sets up automatic handover when aircraft reach their exit point
Note: Aircraft spawn from two sources: entry points (overflights at cruise altitude) and airports (departures). Overflights trigger
onSpawn, while departures triggeronDepartureControllablewhen they reach 10,000ft and become controllable.
Loading Your Script
Press Ctrl+Enter or click "Load Script" to run your code.
Basic Traffic Management
Let's add some actual traffic management. Replace the default script with this:
// Handle overflights entering from entry points
onSpawn((aircraft) => {
// Climb to cruise altitude
aircraft.climb(fl(aircraft.plan.cruiseFL));
// Set cruise speed
aircraft.speed(420);
// Direct to exit point
aircraft.direct(aircraft.plan.exitPoint);
// Auto-handover at exit
aircraft.over(aircraft.plan.exitPoint, (ac) => {
ac.handover();
});
});
// Handle departures when they become controllable at 10,000ft
onDepartureControllable((aircraft) => {
log(`${aircraft.cs} checking in`);
// Give climb clearance
aircraft.climb(fl(aircraft.plan.cruiseFL));
aircraft.speed(420);
// Route to exit
aircraft.direct(aircraft.plan.exitPoint);
aircraft.over(aircraft.plan.exitPoint, (ac) => {
ac.handover();
});
});
onTick(({ traffic }) => {
const flights = traffic.all();
// Maintain spacing with speed control
for (let i = 0; i < flights.length - 1; i++) {
const lead = flights[i];
const trail = flights[i + 1];
const dist = distance(trail.pos, lead.pos);
if (dist < 8) {
// Too close - slow down
trail.speed(Math.max(lead.targetIASKts - 30, 320));
}
}
});Load it and watch the sim handle traffic on its own.
Understanding the Code
onSpawn()
Called when overflight aircraft enter your sector from entry points (already at cruise altitude). Use it for initial clearances:
onSpawn((aircraft) => {
// aircraft has properties: cs, type, altFL, plan, etc.
// aircraft has methods: climb(), speed(), direct(), etc.
});onDepartureControllable()
Called when departure aircraft reach 10,000ft and become controllable. Departures spawn from airports and are uncontrollable during initial climb-out:
onDepartureControllable((aircraft) => {
// Departure just checked in - give climb clearance
aircraft.climb(fl(aircraft.plan.cruiseFL));
aircraft.speed(420);
});onTick()
Called every ~0.5 seconds. Use it for continuous management:
onTick(({ traffic, time, weather, fixes }) => {
// Access all aircraft: traffic.all()
// Get specific aircraft: traffic.byCallsign("AAL123")
});Aircraft Control Methods
Control aircraft using method chaining:
aircraft
.climb(fl(350)) // Climb to FL350
.speed(420) // Speed 420 knots
.direct("KMART"); // Direct to KMARTCommon Patterns
Vertical Separation
onTick(({ traffic }) => {
const flights = traffic.all();
for (let i = 0; i < flights.length - 1; i++) {
const a = flights[i];
const b = flights[i + 1];
const lateral = distance(a.pos, b.pos);
const vertical = Math.abs(a.altFt - b.altFt);
// If lateral separation is tight, ensure vertical
if (lateral < 5 && vertical < 1000) {
a.climb(a.altFt + 2000);
}
}
});Conflict Resolution
onConflict((pair) => {
const acA = traffic.byCallsign(pair.a);
const acB = traffic.byCallsign(pair.b);
if (acA && acB) {
// Climb the higher aircraft
if (acA.altFt > acB.altFt) {
acA.climb(acA.altFt + 2000);
} else {
acB.climb(acB.altFt + 2000);
}
}
});Waypoint Actions
onSpawn((aircraft) => {
// Descend before reaching waypoint
aircraft.before("KMART", 30, (ac) => {
ac.descend(fl(240));
});
// Change speed at waypoint
aircraft.over("MERGE", (ac) => {
ac.speed(320);
});
// Ensure altitude constraint
aircraft.reach("EXIT").altitude(fl(240));
});Debugging
Use log() to output messages to the activity panel:
log(`${aircraft.cs} is at FL${aircraft.altFL}`);
log(`Distance: ${dist.toFixed(1)}nm`);
log(`Conflict between ${pair.a} and ${pair.b}`);The activity panel at the bottom shows all your log messages and errors.
Interactive Mode
Want to take direct control of aircraft? Switch to Interactive mode using the tabs at the top!
In Interactive mode, you can:
- Click aircraft to select them
- Type instructions like
AAL123 cfl200 s400 dr KMART - Use buttons for quick altitude, speed, and routing instructions
- Control aircraft just like a real air traffic controller!
Tip: Hover the Spawn button for the traffic intensity slider - 0% (no auto-spawn) to 100% (max traffic rate).
Watch for readback errors
Just like in real ATC, pilots occasionally make readback errors. Listen carefully to what they read back - if a pilot reads back the wrong altitude or heading, you'll need to correct them!
See the Interactive Instructions reference for all available instructions.
Next steps
- Arrivals & ILS Approaches - vector aircraft to landing
- Tower mode - ground operations at 300+ airports
- API Reference - full scripting docs
- Interactive Instructions - manual control reference
- Audio & Radio Effects - TTS with PTT click sounds
- Emergencies - MAYDAY and PAN PAN declarations