Airwave
Airwave is a gamified airport simulator with airport management and realistic air traffic control (ATC) powered by your voice.

Status
Airwave is under active development. However, it's still fully usable as a simulator rather than a game, so if you're into that, be our guest!
Here's how you can try it out: Installation.
Contribution and Community
We're always excited to welcome new contributors! Here's how you can help:
- Report Bugs or Suggest Features: Open an issue.
- Join the Discussion: Contact us on Bluesky.
- Lend Your Expertise: If you're an aviation or ATC enthusiast, we'd love your insights to make Airwave more realistic.
License
Airwave is licensed under the GNU AGPLv3 license.
Copyright (C) 2025 the Airwave contributors
Installation
Building from source
- Backend: Rust and Cargo
- Frontend: NodeJS and pnpm (you can install both with volta!)
- Build: Just
Step 1:
Clone the repository.
git clone https://github.com/airwavegame/airwave
Step 2:
Build the release for your system.
# For Linux
just release-linux
# For Windows
just release-windows
Step 3:
Enter the directory of the release, such as dist/linux or dist/windows. This will contain all necessary files for Airwave to run, including all game assets and configuration.
Set-Up and Configuration
AI Features (requires OpenAI API key)
To use AI features that allow you to speak to aircraft and have your commands be interpreted via an LLM, it is required for you to bring your own OpenAI API key.
Note: In our testing of games with two players at an hour each, we've found that Airwave uses less than $0.30 per hour of gameplay, so you don't need to worry about high usage, even if you are constantly communicating with aircraft!
Once you have obtained your API key, you will need to add it to an .env as shown in the .env.example:
# .env
OPENAI_API_KEY="<YOUR API KEY HERE>"
Game-specific Configuration
Airwave provides a config spec to change things like the main airport, default frequencies, and other options for startup and gameplay. We include a config.toml file in the release directory, with the default options.
Airwave will read the config.toml on startup, changes to the config won't be read at runtime.
Running a Singleplayer instance
To start a singleplayer (client and server) instance of Airwave, run the client-server script in the release directory (e.g. dist/windows/client-server.exe or dist/linux/client-server.sh).
Now, to access the game, go to http://localhost:8080 in your browser of choice.
Running a Multiplayer instance
Airwave always starts a multiplayer server under the hood, just like Minecraft. If you run the singleplayer instance, other players can connect, as long as you have set the server address to bind to 0.0.0.0 and you have forwarded port 8080 in your router.
Connecting to a server
You can connect to an Airwave server by running the client script which will launch Airwave without the background game and server, relying on an external host to provide the game data.
Once you run the client, you can add the URL or IP of the server you are connecting to to the connection string of your client, like so: localhost:8080?api=12.34.56.78:8080.
Running a client-less server
The Airwave game client is simply an extension to the server that serves static files (HTML, CSS, JS) and does not introduce any extra performance whether enabled or disabled.
Though not common and definitely not expected, you can run an Airwave server without serving the client by running the server script.
Interface
Airwave has four major parts of the interface:
- Radar
- Frequency Panel
- Stripboard
- Chatbox
- Flight Panel
Radar
To view aircraft in the air and on the ground, you will utilize the radar. The radar is the paramount for situational awareness, if not already obvious. Most of your time will be spent looking at the radar and issuing commands to aircraft based on their state and position on it.
Controls
You can click and drag to move the view around, and use the scroll wheel to zoom in and out.
When you zoom in far enough into an airport, the radar type will switch from air to ground, allowing you to view taxiways, terminals, and gates. You can also use PageUp and PageDown to switch between air and ground views respectively.
Blips
Air blips include an aircraft's callsign, currant and target altitude, and the current speed.
Aircraft arriving at your airport will be displayed green, aircraft leaving your airport displayed blue, and if you've selected an aircraft, it will be displayed yellow. If an aircraft is not on your frequency, it will be displayed as a simple grey dot, without any further information (unless selected). Finally, if two or more aircraft encounter a TCAS RA (collision avoidance resolution), the involved aircraft will be colored red.
This color pattern of green, blue, yellow, and red carries throughout the other tools in Airwave such as the stripboard and partially in the chatbox.
The line extending from the dot of a blip points in the direction of travel and is extended per one minute of travel. You can use this line to predict where an aircraft will be in a minute, or further out into the future using the line as a scale.
Ground blips are shown as white for contrast and visibility in the ground mode of the radar. They only include the callsign of the aircraft. The size of the line from the center of the blip is arbitrary in the ground view and only shows the direction of travel.
Airspace
In the airspace view, you will see the runways of your airport plus blue and grey lines extending from them. The blue lines indicate the localizer beams of the ILS, where the aircraft will need to line up with in order to land on the runway. The grey lines around an ILS line show the range of the localizer, where aircraft will be able to detect and intercept it.
The blue circle on a blue ILS line indicates the point at which an approach has to be 4,000 ft or below. If an aircraft at 4,000 ft is vectored to the area of the line between the blue circle and the runway, it might initiate a go-around for being too high.
Frequency Panel
This panel is second to the radar. Here you will manage the frequencies you occupy. It can hold up to 10 total slots, which you can switch between using the number row of your keyboard. To the right of every frequency box is a dropdown selector to choose a named frequency set up by the server config.
Stripboard
The stripboard is the core part of your workflow. It allows you to organize aircraft into discreet steps, see aircraft that need attention in the inbox, and reference when giving commands. You can click & drag headers and strips as you please. You can also rename, add, and remove headers to customize the stripboard to your workflow.
The only hard-coded header is the Inbox as it is required for providing you with incoming strips that you are given control over.
The stripboard includes an options section (toggleable via the Opts button) that tells it which kind of aircraft you are looking to control. For example, if you check the "Approach" box, Airwave will create strips for all aircraft on approach, keeping your stripboard up to date with approach operations.
By default, the stripboard includes all major segments of flight: approach, departure, landing, takeoff, parked, and ground. This is to allow any player to jump in and customize as they'd like while ensuring all aircraft within their control are added to the stripboard. However, these defaults can easily be changed and will be saved to the client storage between sessions.
The Clr button will remove any aircraft that is in a state of flight that is not checked by options. This allows players to quickly discard strips that they no longer have control over, or clear the stripboard between game sessions. Headers and aircraft that are still under your control will not be removed and will stay the way you might have them sorted.
Chatbox
The chatbox displays a log of all of your messages between aircraft and allows you to toggle between your current frequency and all frequencies. The chatbox includes an input box to send text commands instead of using your voice.
ATC messages are shown in red and aircraft messages are shown in green (blue is not used here). You can click a callsign in the log to select the aircraft that sent the message and the callsign will be displayed as yellow (because of selection).
Flight Panel
In the flight panel, you can decide whether to divert approaches, delay departures, or keep both running normally. By default, under normal operations, aircraft will come from arrival into your approach airspace, where you will need to sequence them in for approach. Aircraft parked in a gate, will be scheduled to depart randomly by the server. It will give you a ~1-5 minute window to see the departure and plan for sequencing.
When approaches are diverted, right when an aircraft is about to enter your airspace, it will be diverted to another airport.
When departures are delayed, departures will not be scheduled.
Both above options do not affect existing approaches or departures. Both approaches and departures can be turned on and off as needed to suit workflow and throughput. The difficulty is in your hands.
Handling Approaches
By default, both approaches and departures will be enabled. Once an arriving aircraft enters your airspace, it will be categorized as an approach. If the stripboard is set to accept approaches, you will see a strip come up as the aircraft enters your airspace.
You will also see the aircraft call out to approach in the chatbox (audible message if TTS is enabled), reporting its position.
Initial Vectors
Once an aircraft enters your airspace, you should set them on initial vectors to the active runway (of your choosing). Also, descending them to four or five thousand feet will save you time later, so it is best to initiate their descent very early on.
You can group instructions into one transmission that looks something like this:
SkyWest Twelve Thirty Four, descend and maintain four thousand feet, and turn left heading three zero zero.
This way, you can ensure that they are at the correct altitude and are pointed towards the general direction for an approach.
Sequencing
Sequencing is essential when managing a busy airspace. It is important to keep aircraft spaced far enough apart that you can coordinate takeoffs and landings with enough time between each. This also allows incoming aircraft to merge info the sequence if they fall within it, instead of having to tack them on at the end of the line.
The two main ways of ensuring correct spacing is speed and heading. The speed of an aircraft in your airspace is limited from 250 knots to 180 knots (both inclusive). You can use any speed within that range to aid in keeping your aircraft spaced evenly. You can also utilize heading for spacing, such as having an aircraft make a slightly wider turn, giving it more distance to travel while maintaining the same speed.
Landing
Every runway is equipped with localizer and glideslope beacons (ILS). The max landing altitude for a runway is 4,000 ft. It is also recommended to slow down incoming aircraft to 200 knots once they are within the localizer so that they can descend down safely to the runway.
Go-Around
If sequenced improperly, an aircraft might be too fast or too high for an approach. In this case, it will initiate a go-around on its own (speed: 250, altitude: 4000). It will also broadcast this message to you, stating that it had to perform a go-around (you will see this in the chatbox, and hear it if TTS is enabled).
In this case, it is your job to vector the aircraft for another approach as you would normally, ensuring that it doesn't come too close to any departing aircraft (always keep an eye out!).
Handling Ground and Taxiing
Post-landing
As soon as an aircraft lands on a runway, you need to taxi them off of runway, clearing it for further approaches. In this case, you instruct them to taxi to their gate via a defined path in the airport. For example, you can tell an aircraft to taxi to the open gate A1 via taxiways A and B like so: <callsign>, taxi to gate alpha one via alpha then bravo.
Note: The "then" is not required. It is a pattern that I personally use as it's quicker than pausing between instructions.
If no gates are open, you can still get the aircraft off of the runway by instructing them to taxi to and optionally hold short of another taxiway: <callsign> taxi to and hold short of alpha.
Handling Departures
When a parked aircraft is ready for departure, it will show up on the stripboard (as long as the "parked" and "ground" options are checked) and its timer will be greater than zero. A departure with a timer less than zero indicates that it is currently waiting (boarding, refueling, etc) and is not ready for taxi.
Once a departure is ready, you will need to taxi them to a runway.
Commands
Commands are mirrored from common ATC phraseology. For example, to instruct an aircraft to descend to 4,000 feet, you might say: "SkyWest twelve thirty four, descend and maintain four thousand feet."
Because commands are sent through an LLM (GPT-4o-mini), the syntax for the commands is very loose. As long as you make your intentions clear, the LLM should understand and generate the approprate response.
Available Commands:
All commands should be prefixed with an aircraft's callsign, such as SkyWest Twelve Thirty Four, or `SkyWest One Two Three Four.
Air
Altitude
Normal Syntax:
<climb|descend> [and maintain|to] <feet> feet<climb|descend> and maintain flight level <flight level>
Shorthand Syntax: a, alt, altitude: descend and maintain 4000 feet = a 040
Changes the altitude of the aircraft.
Examples:
climb and maintain flight level one four zerodescend and maintain four thousand feet
Turn
Normal Syntax: turn [direction] heading <heading>.
Shorthand Syntax: t, turn, h, heading: turn right heading 360 = t 360
Changes the direction of the aircraft.
Speed
Normal Syntax: maintain <knots> knots
Shorthand Syntax: s, spd speed: maintain 250 knots = s 250
Changes the speed of the aircraft.
Direct
Normal Syntax: direct <waypoint>
Shorthand Syntax: d, dt, direct: direct waypoint = d waypoint
Changes the aircraft's flight plan to fly directly to a waypoint (that is already in the flight plan).
Frequency
Contact Named Controller
Normal Syntax: contact <controller> [on] [frequency]
Shorthand Syntax: f, freq, frequency, tune, contact: contact departure = f departure
Changes the frequency the aircraft is tuned to, using the frequency configured for that controller in the server config.
Examples:
contact departure
Contact Frequency
Normal Syntax:
contact <controller> on <frequency>tune to <frequency>
Shorthand Syntax: (same as above): contact departure on 123.4 = f 123.4
Changes the frequency the aircraft is tuned to, forcing a specific frequency.
Examples:
tune to 123.4contact departure on 123.4
Approach and Landing
Cleared to Land
Normal Syntax:
cleared to land, runway <runway>cleared ILS approach runway <runway>
Shorthand Syntax: l, cl, land: cleared to land runway 22L = l 22L
Clears the aircraft for ILS approach and landing1.
Examples:
cleared to land, runway zero onecleared to land, runway one four left
Go Around
Normal Syntax: go around
Shorthand Syntax: g, ga, go: go around = g
Instructs the aircraft to abort their landing. Any further commands should follow after go around.
Examples:
go aroundgo around and turn right three six zerogo around, turn right heading zero four zero, climb and maintain four thousand feet
Taxi
Taxi
Normal Syntax: taxi to [and hold short of] <runway|gate|taxiway> [via] <taxiway> [then] <taxiway> [then]...
Shorthand Syntax: tx, taxi: taxi to and hold short of runway one two left via alpha then bravo = tx short 12L via a b
Instructs the aircraft to taxi to a runway via a list of taxiways.
Examples:
taxi to and hold short of runway one two left via alpha then bravo then charlietaxi to runway one two left via alphataxi to gate A1 via alpha bravo charlietaxi to and hold short of alpha
Shorthand Examples:
tx short 12L via a b ctx short 12L via atx gate A1 via a b ctx short a
Hold
Normal Syntax: hold position
Shorthand Syntax: th, hold, stop: hold position = th
Instructs the aircraft to hold position.
Continue
Normal Syntax: continue taxi
Shorthand Syntax: c, tc, continue: continue taxi = c
Instructs the aircraft to continue taxiing.
Takeoff
Both takeoff and line-up clearances can be given while an aircraft is holding at or taxiing to a runway.
Cleared for Takeoff
Normal Syntax: cleared for takeoff, runway <runway>
Shorthand Syntax: ct, to, takeoff: cleared for takeoff runway 22L = ct 22L
Clears the aircraft for takeoff.
Line Up and Wait
Normal Syntax: line up and wait, runway <runway>
Shorthand Syntax: lu, line, wait: line up and wait runway 22L = lu 22L
Tells the aircraft to taxi onto the runway, line up (to its heading), and wait (until instructed for takeoff).
Departures
Resume As Filed
Normal Syntax: resume as filed
Shorthand Syntax: r, raf, resume, own: resume as filed = r
Clears the aircraft (departure) to climb to their filed altitude and follow their departure waypoints.
Note: This will happen automatically as an aircraft departs to save on workload, but can be overridden by changing its speed, heading, or altitude, and resumed by issuing this command.
Miscellaneous
Ident
Normal Syntax: ident or identify
Shorthand Syntax: i, id, ident: ident = i
Selects the aircraft on the client.
-
Airwave combines the clearence procedures for approaches and landings such that they are interchangable. Once an aircraft is cleared for approach, it does not need to be cleared to land. Thus, the phraseology can be used where "cleared to land runway 22L" and "cleared ILS approach runway 22L" will mean the same thing. ↩