A public, adversarial audit of VectorHeavy's rules against real FAA guidance.
Design doctrine
VectorHeavy prioritizes rule accuracy over data accuracy, and both over completeness. The separation logic, phraseology, and procedural gates are modeled on the real orders, where we simplify, we simplify deliberately and we write it down here. A simplification is only acceptable if it does not teach the player something false about how the system works. A wrong rule is a bug; a documented, bounded simplification is a design decision.
This ledger exists so that:
- a real controller playing the game can see exactly where the model stops, and trust that nothing outside those lines is faked; and
- an ATSA/FAA-applicant student using the game for exposure knows which behaviors are safe to learn from and which are game-shaped abstractions.
Primary sources: FAA Order JO 7110.65 (current edition, BB), 14 CFR 91.117, and the AIM. Paragraph numbers are given per the current 7110.65; they are stable across recent editions unless noted. This document does not change game code, it audits the code as it stands.
Verdict key:
- FAITHFUL: matches the real rule within the game's resolution.
- SIMPLIFIED-OK: a deliberate abstraction; rationale given.
- NEEDS-REFINEMENT: a divergence worth a future batch; suggested fix + roadmap era given (v0.2 = wind/weather era, v0.3 = procedural depth, Academy = the strict-mode toggle).
1. Radar separation minima
| Game behavior | Real rule + cite | Verdict |
Flat 3.0 nm lateral minimum everywhere in the radar environment (LATERAL_MIN_NM = 3, separation.ts). | 7110.65 5-5-4: 3 nm when less than 40 nm from the antenna; 5 nm at 40 nm or more. Terminal work is almost entirely inside 40 nm, so 3 nm is the terminal number. | SIMPLIFIED-OK. The whole playfield is terminal airspace inside 40 nm; the 5-nm en-route band never applies on-scope. Correct number for the modeled environment. |
| No 2.5 nm reduced minimum on final. | 7110.65 5-5-4 (reduced-separation-on-final): 2.5 nm is authorized between aircraft established on the final approach course within 10 nm of the runway, when specific site/aircraft conditions are met. | NEEDS-REFINEMENT (Academy / v0.3). We are conservative, we hold 3 nm where the real world sometimes allows 2.5. That never creates a false "safe" call, but it under-rewards tight final sequencing, a core controller skill. Suggested fix: allow 2.5 nm between two established-on-final arrivals inside 10 nm, gated behind an Academy toggle so casual play keeps the simpler rule. |
1000 ft vertical minimum (VERTICAL_MIN_FT = 1000). | 7110.65 5-5-4: 1,000 ft vertical below FL410. | FAITHFUL. Our band tops out at ~17,000 ft, so the 2,000-ft RVSM-ceiling case never arises. |
Diverging-course exemption: a pair whose present gap is opening is not flagged (closureRateNmPerSec >= 0 gates the tower exemption and the CA predictor). | 7110.65 5-5-7 (Passing or Diverging): separation may be discontinued when courses diverge by 15° or more and targets have passed / will not touch. | SIMPLIFIED-OK, leaning NEEDS-REFINEMENT. Real 5-5-7 keys on a 15° angular divergence plus a passed-targets test; we use a pure closure-rate sign. Our test is stricter in some geometries and looser in others (two nearly-parallel tracks with a tiny opening rate pass our test but would fail the 15° test). Suggested fix (v0.3): replace the raw closure sign with the 15°-divergence-plus-target-resolution test the order actually uses. |
2. Wake turbulence: in-trail (radar)
| Game behavior | Real rule + cite | Verdict |
Three legacy weight classes (small / large / heavy) with an in-trail matrix: heavy-behind-heavy 4, large-behind-heavy 5, small-behind-heavy 6, small-behind-large 4 nm; everything else falls back to 3 (wakeSeparationNm, separation.ts). | Current standard is Consolidated Wake Turbulence (CWT), folded into 7110.65 5-5-4, a nine-category (A–I) pairwise system (Super, Upper/Lower Heavy, B757, Upper/Lower Large, Upper/Lower Small). Representative radar minima: behind Super 5–8 nm; behind Heavy 4–5 nm; small behind B757 4 nm. | SIMPLIFIED-OK. Our 3-class matrix is the pre-2019 legacy weight-class scheme, not current CWT. The values we do impose (4/5/6 behind a heavy, 4 for small-behind-large) sit correctly inside the real CWT envelope, so no call the game makes is unsafe. But the taxonomy is a generation out of date: we have no Super (A380/An-225) category and no B757 special case. NEEDS-REFINEMENT (v0.3): add a Super class and a B757 pairwise exception, then migrate the matrix to the CWT A–I categories. This is the single largest "a controller would notice" gap in the model. |
Wake in-trail requires same 1000-ft band and a ±45° in-trail cone behind the generator (WAKE_ALT_BAND_FT, WAKE_INTRAIL_CONE_DEG). | CWT wake application is for a following aircraft directly behind and at/below the leader on the same track/approach. | SIMPLIFIED-OK. A 45° cone plus a 1000-ft band is a reasonable geometric proxy for "directly behind, same or lower altitude." Real application is also distance/altitude-below sensitive in ways we don't model, but the abstraction is honest. |
3. Wake turbulence: same-runway departure intervals (TIME)
| Game behavior | Real rule + cite | Verdict |
Modeled. When a heavy departs (rotates) off a runway end, that end carries a 120-second wake departure interval: a following takeoff from the same end is rejected ("unable, wake turbulence") until it elapses. The rule is non-waivable, clicking TKOF during the interval issues the clearance, the pilot refuses, and a countdown ("wake interval: 1:23 remaining") shows the wait. LUAW is allowed during the interval (you may position the aircraft; the readback appends "expect one minute twenty for wake"). Blocked departures show a "WAKE m:ss" note on the strip. The gate is universal (the pattern/AI world respects it too) and time-based off the generator's rotation (WAKE_DEP_INTERVAL_SEC, sim.ts; wakeIntervalRemaining). | 7110.65 3-9-6/3-9-7 & AIM 7-4: 2 minutes for a small departing behind a heavy (full-length, same runway); 3 minutes for a small behind a heavy/large from an intersection or opposite-direction on the same runway, and that 3-minute intersection interval may not be waived. Behind a Super, 4 minutes. | FAITHFUL (shipped 2026-07-06). The 2-minute full-length behind-a-heavy interval, the case our single-runway/parallel model actually reaches, is modeled exactly, non-waivable, from wheels-up. Documented bounds: we have no intersection-departure model, so the 3-minute intersection/opposite-direction case does not arise (noted in code for when it does); we have no Super class yet (§2), so the 4-minute behind-a-Super case is deferred with it; and a following heavy-behind-heavy is held at a flat 120s (the real value carries CWT-pair nuance), all deliberate simplifications inside the real envelope, never teaching a false rule. A student can no longer learn from VectorHeavy that you may roll a Skyhawk right behind a departing 767. Pairs with the in-trail radar wake model already in the game. |
4. Successive / simultaneous departure release
| Game behavior | Real rule + cite | Verdict |
Parallel-pair departures fly a 15° divergent initial climb (left runway 15° left, right runway 15° right) until 3,000 ft AGL or 5 nm, then own-nav (DIVERGE_TURN_DEG = 15, divergentInitialHeading, sim.ts). | 7110.65 5-8-3: between successive departures off the same runway or parallels < 2,500 ft apart, 1 nm separation is authorized if courses diverge by 15° or more immediately after departure (the divergent turn must commence no later than 2 nm from the departure end). | FAITHFUL in spirit, well-modeled. The 15° divergence number is exactly right and is the actual mechanism controllers rely on. We model the geometry (aircraft physically splitting) rather than the 1-nm reduced-separation credit, which is the right call for a visual game. The one soft edge: our divergence completes by 3,000 AGL / 5 nm, whereas the rule's trigger is the turn commencing within 2 nm, close enough that no false lesson is taught. |
The tower visual-separation exemption: a non-converging pair with either aircraft in the initial-climb/short-final "tower regime" (below 1,500 AGL, within 4 nm) is exempt from the flat 3-nm radar rule (towerSeparationExempt, separation.ts). | Tower separates by visual separation (7110.65 Ch. 7) and same-runway rules (3-9-6) on and near the runway, not by radar 3-nm/1000-ft. Two parallels rotating together, or an arrival to one runway while a departure rolls the parallel, are routine. | SIMPLIFIED-OK / FAITHFUL intent. This is the correct concept, radar minima do not own the runway environment, implemented as a bounded exemption rather than a full visual-separation model. The convergence guard keeps a genuine low-altitude head-on a violation, which is the right safety floor. The 1,500-AGL / 4-nm ring is a game constant, not a published boundary; that's an honest abstraction of "the tower's airspace." |
5. Same-runway separation (tower, arrivals/departures)
| Game behavior | Real rule + cite | Verdict |
An arrival inside 2 nm final with the runway occupied (a departure rolling/lined-up, or another arrival in rollout) goes around on its own (PILOT_GOAROUND_NM = 2, runwayOccupied, sim.ts). | 7110.65 3-9-6: a departure may not begin roll, and an arrival is not "separated," until the preceding aircraft has crossed the runway end / turned, or the preceding arrival is clear of the runway. Landmark-distance alternative: airborne + 3,000 ft (Cat I), 4,500 ft (Cat II), 6,000 ft (Cat III). | SIMPLIFIED-OK. We enforce the outcome the rule protects (don't put two aircraft on one runway) via a pilot go-around, rather than the controller-side "don't clear it in the first place" gate. The 2-nm trigger is a game constant, not the rule's actual "clear of the runway" test. NEEDS-REFINEMENT (v0.3): model the anticipated-separation gate (allow a landing clearance when the preceding departure will be airborne-and-past by threshold), and the Cat I/II/III landmark distances, so the player is rewarded for tight-but-legal single-runway sequencing instead of only being punished by the go-around. |
5A. VFR separation regime (see-and-avoid)
VectorHeavy's traffic is a mix of IFR airline/GA and VFR aircraft (light singles in the pattern, VFR full-stop arrivals, VFR departures). The 3 nm / 1,000 ft radar minimum is the IFR-to-IFR standard. A VFR aircraft is see-and-avoid: it is responsible for its own separation from other traffic, receives traffic advisories and safety alerts rather than radar minima, and the controller cannot even assign it an altitude (an altitude command answers "unable, VFR"). Holding a VFR pair to the IFR 3 nm / 1,000 ft rule is wrong: it ended sessions for a "loss of separation" the player had no tool to prevent. So a pair that involves any VFR aircraft is judged on a lighter proximity regime instead.
| Game behavior | Real rule + cite | Verdict |
A pair with either aircraft VFR does not use 3 nm / 1,000 ft. Instead: an alert at 1.5 nm AND 500 ft (both must be violated, VFR separation is see-and-avoid in the vertical too, so a comfortable altitude split alone clears the pair), a scored safety event (vfrConflicts, a lighter deduction than an IFR deal) between the alert and the near-midair, and a near-midair (NMAC) inside 0.5 nm AND 300 ft as the only session-ending outcome (VFR_ALERT_NM/FT, VFR_NMAC_NM/FT, pairThresholds/detectConflicts, separation.ts). The amber-predict / red-loss visual ladder uses the pair's applicable thresholds, so it stops over-warning on VFR pairs. | AIM 4-4-1, 5-5-2; 7110.65 2-1-6 (safety alert), 5-5-1: VFR aircraft in Class C/D/E are separated by see-and-avoid; ATC provides traffic advisories and, when the controller is aware of a hazard, a safety alert, not radar separation minima. IFR-to-VFR target-resolution/500 ft service applies in Class C (500 ft/target resolution) and Class B (1.5 nm / 500 ft); Class D is runway separation + advisories. | FAITHFUL-with-bounds. Modeling VFR as a proximity/advisory regime rather than radar minima is the correct concept and fixes a real false lesson (that you must hold 3 nm on a VFR Skyhawk). The specific 1.5 nm / 500 ft alert mirrors the Class B IFR-vs-VFR number, and the 0.5 nm / 300 ft NMAC is a tuned game floor, not a published boundary, an honest abstraction of "too close." Bounds: we apply one blended proximity rule to all fields rather than switching by airspace class (Class C 500 ft/target-resolution vs Class B 1.5 nm/500 ft vs Class D runway-separation), because airspace-class geometry is not modeled yet (§7). NEEDS-REFINEMENT (v0.2/v0.3): split the VFR thresholds by drawn airspace class once the airspace layer lands. |
Wake separation still applies behind a heavy for a VFR pair, the wake in-trail matrix (§2) is evaluated regardless of VFR status and is never relaxed by the proximity regime (wakeRequirement in both detectConflicts and predictConflicts). A light single trailing a heavy is flagged at the wake distance and scored as a wake deal, not a VFR safety event. | AIM 7-4, 7110.65 5-5-4 (CWT): wake turbulence is physics, not a procedural minimum, it does not care whether the trailing aircraft is IFR or VFR. A light aircraft behind a heavy is the textbook wake-encounter accident. | FAITHFUL. Keeping the wake matrix authoritative for VFR pairs is correct and is the one place the VFR pair is held to a distance, because the hazard is real regardless of flight rules. The tower visual-separation exemption (§4) still takes precedence where it applies. |
6. Line up and wait (LUAW)
| Game behavior | Real rule + cite | Verdict |
LUAW (W command) is unrestricted: any holding-short departure can be told to line up and wait on any runway end, day or night, with no traffic-advisory requirement (applyLineUpWait, commands.ts). | 7110.65 3-9-4: when an aircraft is authorized LUAW, inform it of traffic within 6 flying miles requesting the same runway (full-stop/T&G/option/low approach). Do not LUAW when the intersection isn't visible from the tower; night-intersection LUAW needs specific approval and a departure-only runway; no simultaneous LUAW on intersecting runways. | NEEDS-REFINEMENT (v0.3 / Academy). We model none of the 3-9-4 constraints. In the current single-runway/parallel airports the "intersecting runways" and "intersection visibility" cases rarely bite, but the 6-nm traffic advisory is a routine, teachable requirement we skip. Suggested fix: require/emit the "traffic N-mile final" advisory when LUAW is issued with an arrival inside 6 nm, and (once intersecting-runway airports exist) reject simultaneous LUAW on crossing runways. |
7. Speed
| Game behavior | Real rule + cite | Verdict |
Assigning > 250 kt below 10,000 ft is refused ("unable, two five zero below one zero thousand"), except a declared emergency (applySpeed / SPEED_250_LIMIT, commands.ts). | 14 CFR 91.117(a): 250 kt max indicated below 10,000 ft MSL. | FAITHFUL. Correct threshold, correct value, correct emergency carve-out. |
| No enforcement of 200 kt below Class B / in the surface area. | 91.117(b)–(c): 200 kt at or below 2,500 ft AGL within 4 nm of a Class C/D primary airport, and beneath Class B shelves / in a VFR corridor. | SIMPLIFIED-OK. Airspace-class speed limits require modeled Class B/C/D geometry, which arrives with the airspace layer. Documented gap, not a wrong rule. NEEDS-REFINEMENT (v0.2/v0.3) once airspace rings are drawn. |
A cleared-to-land arrival's assigned speed releases to its own approach speed inside 5 nm final (FINAL_RELEASE_NM = 5, sim.ts); the player can no longer usefully assign speed there. | 7110.65 5-7-1: do not assign speed adjustments inside the final approach fix, or a point 5 nm from the runway, whichever is closer. | FAITHFUL. Our 5-nm release is exactly the controller-side "hands off the speed" boundary the order draws. Well matched. |
No minimum-speed floor within 20 nm (170 kt turbojet / 150 kt turboprop) modeled as a controller constraint; instead each type has an approach-speed floor for assignment (approachSpeedFloor). | 7110.65 5-7-3: don't assign less than 170 kt (turbojet) / 150 kt (turboprop/recip) within 20 nm of the threshold. | SIMPLIFIED-OK. Our per-type minimum-assignable-speed accomplishes the same protective effect (you can't slow a jet to a stall) via a cleaner mechanism. The specific 170/150-within-20-nm numbers aren't surfaced, but no false lesson results. |
8. Altitude floors: MVA / MIA
| Game behavior | Real rule + cite | Verdict |
Not modeled. Altitude assignment is clamped to a per-airport band floor (altitudeBand), a flat number, with no terrain/obstruction floor and no minimum vectoring altitude. | 7110.65 5-6-3 / 5-6-1: aircraft must be kept at or above the MVA/MIA except on approach; MVA charts are terrain- and obstruction-derived and vary by sector. | SIMPLIFIED-OK (documented major omission). Terrain separation is a whole subsystem requiring an MVA grid (see AIRPORT_RULES.md, "terrain grid later (MVA/MSAW)"). Our flat band floor is a placeholder, not a claim that terrain is safe. NEEDS-REFINEMENT (v0.3+): an MVA polygon layer + a low-altitude alert (MSAW analog). Until then, VectorHeavy should not be read as teaching terrain avoidance at all, flagged prominently for ATSA-prep users. |
9. Approach vs landing clearance; missed approach
| Game behavior | Real rule + cite | Verdict |
Two-step (batch 4) with a one-step shortcut. CA arms the published approach ("cleared ILS runway X approach", with "maintain … until established" when vectoring), then the tower's L clears the landing separately (§14). The legacy single-step L (accepted within ±60° of runway heading and ≤ 3,000 ft AGL, APPROACH_ANGLE_MAX/APPROACH_AGL_MAX, commands.ts) is preserved as a casual shortcut. | Real ops are two-step: approach control issues the approach clearance ("cleared ILS runway X"), which authorizes the published missed approach (7110.65 4-8-1); the tower separately issues "cleared to land" (Ch. 3). "Maintain [alt] until established" and intercept phraseology precede it. | FAITHFUL (batch 4), with a SIMPLIFIED-OK shortcut. The real two-clearance model ships in normal play (see §14 for the full row set), including the 4-8-1 vector-to-intercept phrasing and the go-around when the landing clearance never comes. The one-step L stays as the documented tower shortcut so casual play and the tutorial are untouched. |
Go-around (controller A or pilot-initiated) climbs to field + 3,000 ft on runway heading and awaits vectors (applyGoAround; pilotGoAround, ~3,000 AGL runway heading). | A real missed approach flies the charted MAP for that specific approach (a published track/altitude/hold), not a generic runway-heading climb. | SIMPLIFIED-OK. Runway-heading-climb-to-3,000-then-vectors is exactly how a radar-vectored missed approach is often handled in practice ("climb runway heading, maintain 3,000, expect vectors"), so it isn't false, it just isn't the charted MAP. Modeling per-approach charted missed-approach procedures is a v0.3 depth item. Phraseology "go around, go around" is faithful. |
10. Holding
| Game behavior | Real rule + cite | Verdict |
H/H <fix> puts the aircraft in an orbit (circular loiter) at the fix or present position; readback "hold at FIX as published" (applyHold, commands.ts; code comment notes "orbit approximates v1"). | AIM 5-3-8: a holding pattern is a racetrack, standard right turns, a specified inbound course, 1-minute legs at/below 14,000 ft (1½ min above), with direct / parallel / teardrop entries determined by arrival geometry. | SIMPLIFIED-OK, self-acknowledged. The code itself flags the orbit as a v1 approximation. An orbit holds the aircraft in the same airspace (the operational point of a hold), which is what the game needs, but it teaches nothing about racetrack geometry, entries, or leg timing. NEEDS-REFINEMENT (v0.3): a real racetrack with a published/assigned inbound course and standard right turns; entry selection is an Academy-depth nicety. Readback "as published" is faithful phrasing. |
11. Handoffs / point-outs
| Game behavior | Real rule + cite | Verdict |
Departures become handoff-eligible at their exit fix and above a field-relative floor (depHandoffFloor, ~5,000 ft at KSTL); F completes to "contact [Center] [freq], good day." Arrivals hand to ground after rollout. Auto-completes late if ignored (tickDepartureHandoff, contactCenter, contactGround). | Real handoffs are a coordination action (7110.65 Ch. 5-4): transferring radar identification to the receiving controller, with radar contact/point-out protocols, not a simple frequency-change-at-a-fix. | SIMPLIFIED-OK. In a single-controller game there is no adjacent human sector to coordinate with, so "hand off at the exit fix" collapses correctly to a frequency change. The phraseology ("contact Denver Center one three four point five, good day"; "turn left when able, contact ground point niner") is faithful, including reading back the frequency. Point-outs have no meaning without a second controller, correctly absent. |
12. ATIS
| Game behavior | Real rule + cite | Verdict |
ATIS letter advances A→B→C… every ~12–18 min; altimeter nudges slightly; controller broadcasts "Attention all aircraft, information Bravo is current, altimeter…" and one pilot acks (tickAtis, rollAtis, atisBroadcast, atisAck). | 7110.65 2-9-3: a new ATIS code is issued on the hour or when conditions change; pilots report the current code on initial contact so the controller may omit items already in the ATIS; sequential letter progression is standard. | FAITHFUL (texture-level). The rollover mechanic (sequential letters, altimeter change, "information X is current" broadcast) is right, and pilots acking the code is real. Where it's simplified: our roll is on a timer rather than weather-change-driven (weather isn't modeled yet), and pilots don't yet report the code on check-in to let the controller omit items. NEEDS-REFINEMENT (v0.2): drive the roll off actual wind/weather changes once the weather layer lands, and add code-on-checkin. |
13. Phraseology spot-check
| Game behavior | Real rule / convention | Verdict |
Digits spoken individually; "niner" for 9 (spokenNiner); headings always three digits ("two seven zero", "zero niner five"); airspeed and frequencies digit-by-digit; frequency "point". | 7110.65 2-4-x radio phraseology / ICAO digit table. | FAITHFUL. Correct across headings, speeds, runways, frequencies. |
Altitude grouping: "one one thousand" for 11,000; "niner thousand"; "one zero thousand five hundred" (spokenAltitude). | 7110.65 altitude phraseology: thousands spoken as individual digits + "thousand" + hundreds. | FAITHFUL. This is exactly the correct grouping, a common thing sims get wrong ("eleven thousand"), and VectorHeavy gets it right. |
Deliberately omits "over" on routine VHF exchanges (documented decision in phraseology.ts). | Correct, domestic VHF ATC does not say "over" on routine transmissions. | FAITHFUL. A controller-pleasing detail; "over" would make one wince. |
| Uses "three"/"five", not the stricter "tree"/"fife" (documented; reserved for an Academy strict mode). | ICAO/7110.65 strict pronunciation is "tree"/"fife". | SIMPLIFIED-OK. A conscious readability choice for general players, with the strict forms parked behind Academy mode. Not wrong for a US-domestic casual read; a purist would prefer the option. |
Instruction/readback structure: controller callsign-first, full wording; pilot callsign-last, compressed but full value on required items (heading/alt/speed/runway/hold); advisory items get terse seeded acks (csLast, readback fns). | 7110.65 2-4-3 (readback of required items) and standard exchange structure. | FAITHFUL. The callsign-first/last split and the "required items always read back in full, advisories may be terse" rule are exactly right, including reading back hold-short/runway assignments. |
Heavy appends "Heavy" in all phraseology; GA leads with type ("Skyhawk four five two one bravo") (spokenCallsign, spokenNNumber). | 7110.65 2-4-20 (heavy/super suffix); GA type-prefix convention. | FAITHFUL. Correct; missing only the "Super" suffix (tied to the absent Super wake class in §2). |
| No explicit hold-short readback enforcement beyond content: the game voices the assignment but doesn't require the pilot to read back "hold short of runway X" as a graded item. | 7110.65 2-4-3 / runway-safety guidance: hold-short instructions are a mandatory readback item. | NEEDS-REFINEMENT (Academy). The pilot lines contain the runway, but a hearback/readback-verification mechanic (does the player catch a wrong readback?) doesn't exist yet. Flagged for the Academy hearback feature. |
14. Published procedures: descend-via STARs (batch 2), climb-via SIDs (batch 3), two-clearance approaches (batch 4)
VectorHeavy flies published RNAV STARs with descend-via. A share of IFR arrivals at a field that has STARs (KSTL/KATL/KDEN/KSEA) check in already established on a real charted arrival ("descending via the AARCH TWO arrival"), fly its leg sequence to the runway transition, and manage their own altitude/speed to the charted crossing restrictions until the controller takes them off it. Data provenance is the CIFP cycle (docs/PROCEDURES.md); the engine never invents a fix or a restriction.
| VectorHeavy behavior | Real rule | Verdict |
STAR assignment. A seeded share of IFR arrivals spawn ON a published STAR whose enroute-transition entry best matches the origin bearing, with the runway transition for the expected flow runway. They enter at the TRACON boundary already compliant, descending via the profile (tryAssignStar, selectStar, sim.ts/star.ts). | STARs are the standard arrival structure; a flight is on its filed STAR when handed to approach, already having met the enroute crossings on Center. | FAITHFUL (batch 2). The arrival appears on a real named procedure consistent with where it came from, established descending-via, exactly the picture a TRACON controller inherits. |
Lateral compliance. The aircraft flies the flattened leg sequence (enroute → common → runway transition) as TF/CF/DF/IF legs; the selected arrival's remaining procedure path draws as the dashed route line; the strip shows the STAR (e.g. AARCH2·30L) (steerStar, drawSelectedRoute, strips.ts). | RNAV lateral navigation flies the charted legs to each fix in turn. | FAITHFUL, with the batch-1 RF bound. RF (radius-to-fix arc) legs are flown as a straight track to the terminating fix (no arc geometry yet, docs/PROCEDURES.md §4); every other leg is faithful. |
Vertical, descend-via. On a descend-via clearance the aircraft manages its own altitude to meet at / atOrAbove / atOrBelow / between crossings and honors published speed caps, interpolating on a ~2.9° glide between restrictions (descendViaProfile, maybeDescendVia). Check-in and re-clear phraseology follow 7110.65 4-5-7 ("descending via the CARDS TWO arrival"). | AIM 5-4-1 / 7110.65 4-5-7: on a descend via clearance the pilot descends at their discretion to comply with every published altitude and speed restriction on the arrival. | FAITHFUL (batch 2). The aircraft meets each in-band charted crossing within a game tolerance; the check-in/readback wording is the real 4-5-7 phrasing. |
Controller interplay. A heading vector takes the aircraft off the arrival laterally (the lateral leg-following suspends); an altitude assignment takes it off the descend-via vertically ("descend and maintain" cancels the vertical). DV ("descend via the arrival") and R ("resume own navigation") re-clear it onto the profile when it is still rejoinable to the lateral path (applyHeading/applyAltitude/applyDescendVia/applyResumeNav, commands.ts). | Real ops: a vector cancels the lateral portion of the arrival; "descend and maintain" cancels the vertical descend-via; the controller re-clears "descend via the … arrival" to put the pilot back on the profile. | FAITHFUL (batch 2). The two-axis take-off/put-back-on is the actual skill the position trains, modeled on the real cancel/re-clear semantics. |
| The STAR-to-vectors seam. When the charted legs end (typically a ~5,000-ft crossing near the FAF), the descend-via is complete: the aircraft levels at its last charted altitude and holds course; the controller then issues normal descent + vectors to final. If left level too long the pilot nags ("level 5,000, request lower"). It does not auto-descend to the runway. | The published portion ends where radar vectors to final begin; below the last fix the controller owns the descent and the turn-on. | FAITHFUL by design. The seam is the gameplay, the game deliberately does not fly the aircraft to touchdown for you. |
Unmeetable restriction honesty. If a late re-clear (a high vector then DV) makes a crossing geometrically impossible, the pilot calls "unable [fix] restriction" once and levels rather than silently busting it (logged as descendViaUnable). | A pilot who cannot meet a restriction must advise ATC and will not fabricate compliance. | FAITHFUL. Never a silent bust; the miss is announced and recorded. |
Documented bounds (batch 2).
- Compressed altitude band → upstream crossings satisfied on Center. The game flies a compressed terminal band (e.g. KSTL ~2,000–12,000 ft), so crossings at or above the band ceiling (e.g. BOOSH at or above 14,000 at KSTL) belong to Center airspace upstream of the TRACON. The aircraft complied with them on Center frequency before the handoff and enters boundary-compliant, they are marked satisfied-upstream at assignment (deterministic, documented), never "ignored." That 14,000 crossing becomes the player's job in a future Center mode.
- Edge case, nothing in-band. A STAR whose every restriction is out-of-band at a given field still flies the lateral procedure (named, on the strip) but has no descend-via to fly: the arrival checks in normally ("with you, [altitude]") and is descended conventionally.
- RF-as-track (above) and speed windows flattened to their cap (
docs/PROCEDURES.md §4) carry over from the batch-1 data bounds.
- Approaches / missed approaches are not this batch (two-clearance ILS + charted misses = batch 4; SID climb-via shipped in batch 3, below).
The departure side: published SIDs with climb-via (batch 3)
VectorHeavy also flies published SIDs with climb-via. A seeded share of IFR airline departures at the SID fields (KSTL/KATL/KDEN/KSEA) file a real charted departure consistent with their exit fix / destination bearing; the takeoff readback carries "climbing via the COLLE SIX departure", and off the runway the aircraft flies the TRACON portion of the procedure. Same data doctrine: never an invented fix or restriction.
| VectorHeavy behavior | Real rule | Verdict |
SID assignment. A seeded share of IFR airline departures spawn holding short with a filed SID whose runway transition serves their assigned departure end and whose outermost TRACON leg best matches the filed exit fix's bearing (tryAssignSid, selectSid, sim.ts/sid.ts). A re-taxi re-fits the SID to the new end (or honestly drops it). | Departures at these fields are cleared via an RNAV SID in the route clearance before taxi. | FAITHFUL (batch 3). The departure holds short already carrying its real named procedure ("ready for departure, COLLE6 departure"), the picture the local controller inherits. |
Divergent initial climb → join (coexistence). Off the rotation the departure flies the divergent initial climb exactly as before (the parallel-departure LOS fix: left runway ~15° left, right ~15° right, until ~3,000 AGL / 5 nm), and only then joins the SID lateral path at the nearest sensible leg (joinIndex, maybeOwnNav). Wake departure intervals (§3) are untouched. | Real RNAV SIDs open with a climb on heading to an altitude, then direct a fix; parallel departures diverge immediately. | FAITHFUL, with the join simplification. The charted climb-on-heading legs (VA/VI/VM) are dropped by the CIFP pipeline (docs/PROCEDURES.md §4); the tower's divergent climb stands in for them, then the join. Documented bound. |
Lateral compliance. The aircraft flies the flattened TRACON legs (runway transition → common → enroute, truncated at the exit-fix ring) as TF/CF/DF/IF (RF as track); the selected departure's remaining path draws as the dashed route line; the strip shows COLLE6→SAGME (steerSid, drawSelectedRoute, strips.ts). | RNAV lateral navigation flies the charted legs to each fix in turn. | FAITHFUL, with the batch-1 RF bound. |
Vertical, climb-via. The departure manages its own climb to the charted in-band restrictions: it levels at an upcoming ceiling until the fix is crossed (e.g. KDEN's at or below 10,000), meets floors in stride, and honors published speed caps on top of the 250-below-10k rule (climbViaProfile, maybeClimbVia). | AIM 5-2-9 / 7110.65 climb-via: the pilot climbs at their discretion to comply with every published altitude and speed restriction on the SID. | FAITHFUL (batch 3) within the band; the readback/own-nav call is the real "climbing via the [name] departure" phrasing. |
Controller interplay. A heading vector takes the departure off the SID laterally; an altitude assignment ("climb and maintain") cancels the climb-via vertically. CV ("climb via the [name] departure") re-clears it; R rejoins the SID when rejoinable, else resumes the filed direct-to-exit (applyClimbVia/applyResumeNav, commands.ts). | Real ops: a vector cancels the lateral portion; "climb and maintain" cancels the climb-via; the controller re-clears "climb via SID" to restore it. | FAITHFUL (batch 3). The same two-axis cancel/re-clear skill as the arrival side, on the real semantics. GRAMMAR: CV is a distinct command; DV stays arrival-only. |
The seat seam, handoff. Past the last TRACON leg the departure proceeds direct its filed exit fix and the existing handoff machinery ends the story: eligible at the fix ≥ the handoff floor, F to Center. The SID's enroute legs and its charted top altitude above the band are Center's, satisfied downstream after the handoff, never silently busted. | The TRACON owns the departure from rotation to the boundary; Center owns the rest of the SID. | FAITHFUL by design (MODEL-THE-SEAT). Out-of-band is the other frequency's job, satisfied downstream, the same doctrine as the arrival side's satisfied-upstream. |
Unmeetable restriction honesty. If a late re-clear makes a restriction geometrically impossible (already above a downstream ceiling, a climb-via never descends, or a floor needing a steeper-than-performance gradient), the pilot calls "unable [fix] restriction" once and climbs per performance (logged as climbViaUnable). | A pilot who cannot meet a restriction must advise ATC. | FAITHFUL. Never a silent bust; announced and recorded. |
Documented bounds (batch 3).
- TRACON truncation. The flattened SID is cut at the exit-fix ring (~1.25× the exit distance + 5 nm); enroute legs beyond it, and every restriction at/above the band ceiling (including the charted top altitude), are satisfied downstream on Center. A future Center mode makes them the player's job.
- Edge case, nothing in-band. A SID whose every restriction is out-of-band still flies the lateral procedure and still reads back "climbing via" (the clearance is the clearance); the vertical machinery simply has nothing to level for, it climbs to the band cap as any departure does.
- Divergent-climb join (above): the dropped VA/VI/VM initial legs are stood in for by the existing divergent initial climb, then a nearest-sensible-leg join.
- Airline departures only; GA/VFR keep today's filed-direct behaviour (mirrors batch 2's arrival eligibility). Small fields carry no SIDs, correctly unchanged.
The two-clearance model, approach + landing clearances (batch 4)
VectorHeavy separates the approach clearance from the landing clearance, the core realism upgrade of the era. An approach clearance ("cleared ILS runway 30L approach", 7110.65 4-8-1) arms the approach; the tower's "cleared to land" is a distinct gate. A visual approach follows the "report field in sight" exchange. The family (ILS/LOC/RNAV) comes verbatim from the CIFP plates; RNAV(GPS) fields (KJEF/KSPI/KCOU) finally fly their real finals.
| VectorHeavy behavior | Real rule | Verdict |
Approach clearance (CA). Arms the best published approach for the runway (ILS > LOC > RNAV). The aircraft enters the onApproach phase, intercepts the final approach course and descends the glidepath pilot-managed, WITHOUT further altitude commands, exactly like a descend-via but on final (clearApproach, integrateApproach, approach.ts/sim.ts). Issued bare when the aircraft is already established, else with the "fly heading …, maintain … until established" preamble (readbackApproachClearance). | 7110.65 4-8-1: approach control issues the approach clearance ("cleared ILS runway X"), which authorizes the published approach; "maintain [alt] until established" and intercept phraseology precede it when vectoring to final. | FAITHFUL (batch 4). The two-step approach-then-land model the §9 row flagged as NEEDS-REFINEMENT now ships in normal play, with the real 4-8-1 vector-to-intercept phrasing. |
Landing clearance stays separate (L). An aircraft on an approach clearance still needs the tower's L before the threshold; L transitions it to the normal landing phase (no re-check of alignment/altitude, it is already established). Without L by short final the pilot goes around ("going around, no landing clearance"), the existing uncleared-go-around machinery wired to the two-clearance radio (applyLand, approachGoAroundNoClearance). | The tower separately issues "cleared to land" (Ch. 3); an aircraft established on the approach without a landing clearance executes the missed approach. | FAITHFUL (batch 4). Approach authorization and landing authorization are genuinely distinct gates, and the missing landing clearance produces the correct go-around, never a silent uncleared touchdown. |
Backward-compatible tower shortcut. An L issued to an aircraft NOT on an approach clearance behaves exactly as before batch 4, one-step to the landing phase and down to touchdown (applyLand, unchanged legacy path). | Real ops are two-step, but a blended tower/approach single-controller game may collapse them for casual play. | SIMPLIFIED-OK (by design). The one-step L is preserved as the documented "tower shortcut" so casual play and the tutorial are untouched; the two-clearance flow is opt-in on top. |
Visual approach (PF → field in sight → VA). The controller points out the field ("airport twelve o'clock, one zero miles, report it in sight"); the pilot reports the field in sight after a seeded delay/probability by distance; then a visual approach clears pilot-managed own navigation + descent to the field (pointOutField, clearVisualApproach, reusing the VFR self-descent picture). It still needs L. | AIM 5-4-23 / 7110.65 7-4: a visual approach requires the pilot to have the airport (or preceding traffic) in sight; the pilot then provides own navigation to the runway; a landing clearance is still required. | FAITHFUL (batch 4). The field-in-sight exchange gates the visual, and it stays honest, own navigation to final, still needing the landing clearance. VFR traffic (already see-and-avoid) needs none of this, correctly excluded. |
Interplay. A heading vector OR an altitude assignment CANCELS the approach clearance (an approach couples both axes), the aircraft levels / flies the vector and the pilot notes "canceling the approach"; re-clear with CA/VA. R resumes the filed/STAR routing as shipped (cancelApproachIfArmed, commands.ts). | Real ops: a vector or an altitude change off the published profile cancels the approach clearance; the controller re-clears the approach to restore it. | FAITHFUL (batch 4). The same take-off/put-back-on skill as the DV/CV arrival and departure sides, on one coupled clearance rather than two independent axes. |
Documented bounds (batch 4).
- Localizer/glidepath model. The instrument intercept reuses the landing-phase localizer capture (a bounded ~30° cut to the extended centerline, then track it) and a ~320 ft/nm glidepath, not a modeled ILS beam, angular sensitivity, or DA/MDA, the same geometric abstraction the landing phase already uses. Charted missed approaches are still the generic runway-heading climb (§9), a v0.3 depth item; the approach clearance's authorization of the published miss is modeled as that climb.
- Visual approach is own-navigation direct to the threshold with the VFR self-descent glide, not a charted visual segment or a "follow the traffic you have in sight" sequencing, honest and simple.
- Field-in-sight roll draws from a dedicated RNG stream (the delay + the distance-scaled success probability), so it never perturbs the STAR/SID or main seeded sequences (
test:replay unchanged).
- VFR excluded. Approach and visual clearances are IFR-only; VFR aircraft are see-and-avoid and use the runway (
L) directly, as before.
Summary of open refinement items
| Roadmap era | Items |
| v0.2 (wind/weather) | Weather-driven ATIS rollover + code-on-checkin (§12); airspace-class 200-kt limits once rings exist (§7). |
| v0.3 (procedural depth) | CWT/Super/B757 wake taxonomy (§2), now also unblocks the 3-min intersection / 4-min behind-Super departure intervals (§3); real racetrack holds (§10); anticipated-separation same-runway gate + Cat I/II/III (§5); LUAW 3-9-4 constraints (§6); MVA/MSAW terrain layer (§8); 5-5-7 15°-divergence test (§1); charted missed approaches (§9). |
| Shipped | Same-runway wake departure intervals (§3, 2026-07-06); published RNAV STARs + descend-via (§14, the Procedures Era batch 2); published SIDs + climb-via (§14 departure side, the Procedures Era batch 3, 2026-07-12); the two-clearance model, approach + landing clearances and "report field in sight" visuals (§9 / §14, the Procedures Era batch 4, 2026-07-12). |
| Academy (strict mode) | 2.5-nm reduced final (§1); "tree/fife" strict digits (§13); hold-short hearback verification (§13). |
This ledger is maintained alongside the code. When a refinement item ships, its row moves to FAITHFUL with the implementing commit noted. Corrections from the controller community are welcome, accuracy of this document is part of the product.
Sources
- FAA Order JO 7110.65 (Air Traffic Control), current edition, chapters 2 (phraseology, ATIS 2-9-3), 3 (3-9-4 LUAW, 3-9-6 same-runway, 3-9-7 intersection wake), 4 (4-8-1 approach clearance), 5 (5-5-4 minima/wake, 5-5-7 passing/diverging, 5-6-3 MVA, 5-7-1/-3 speed adjustment, 5-8-3 successive departures). Text via faa.gov ATC publications and the pointSixtyFive 7110.65 wiki mirror.
- 14 CFR 91.117 (Aircraft speed), eCFR.
- AIM 5-3-8 (Holding), 7-4 (Wake Turbulence).