Plane sprite has misplaced pixels
Two bytes in the player's plane sprite data contain incorrect pixel values. The errors are at $83BB (frame 1) and $83CB (frame 2), corrected via ofix directives. The visual effect is subtle — a few pixels are misplaced in the plane's wing area.
Fighter sprite has wrong pixels in multiple frames
Six bytes across both left-facing and right-facing fighter sprite frames contain incorrect pixel data:
  • Left-facing: $8736 and $8739 (frame 1)
  • Right-facing: $8916 and $8919 (frame 1), $891F (frame 1), $893A (frame 2)
All corrected via ofix directives. The errors affect the fighter's wing and fuselage outline in certain animation frames.
Collision detection works on raw screen pixels
The game detects collisions during the sprite rendering phase by checking whether OR-ing a new sprite's pixels onto the screen encounters any non-zero existing pixels (see render_object and jp_collision_dispatcher). There is no separate collision map — the framebuffer itself serves as the collision surface.
This means that anything drawn on screen is collidable, including data written via POKE during a pause. If you pause the game and POKE non-zero bytes into screen memory at the plane's position, the plane will collide with them when the game resumes.
Shooting a fuel depot while refueling can kill you
While refueling (GAMEPLAY_MODE_REFUEL), the plane's collision detection remains active with COLLISION_MODE_FUEL_DEPOT set. If the player fires a missile at the fuel depot being used for refueling, the resulting explosion fragments are rendered via OR blending. If an explosion fragment's pixels happen to overlap the plane's pixel position on screen, the rendering pipeline detects the overlap and triggers a player death.
This bug is intermittent because the explosion fragments must land at exactly the right pixel position to overlap with the plane sprite. Most of the time, the fragments fly past harmlessly.
See hit_fuel (fuel depot collision handler), handle_collision_mode_fuel_depot (fuel depot collision mode setup), render_object (render with collision detection).
Off-by-one in island element lookup
The island element search loop at locate_island_element has an incorrect branch condition, corrected by the ofix at $697A (JR NZ with corrected target). The original code can skip past the intended island entry under certain conditions.
Speed-dependent plane Y coordinate is dead code
The terrain rendering routine (60C9) computes the plane's Y position as $88 minus the current speed setting, which would place the plane 1-3 pixels lower at higher speeds. However, all three movement handlers — handle_right (handle_right), handle_left (handle_left), and render_plane (render_plane) — immediately overwrite this with the fixed PLANE_COORDINATE_Y ($80), making the speed-dependent calculation dead code with no visible effect.
Pressing left and right simultaneously shows banked plane sprite
When both left and right are held at the same time, the plane appears banked despite no net movement. Both handle_right (handle_right) and handle_left (handle_left) are called in sequence: handle_right moves the plane +2 pixels and renders the banked sprite, then handle_left moves it −2 pixels and renders the banked sprite again, leaving the plane at its original position. However, both handlers always set state_plane_sprite_bank (state_plane_sprite_bank) to $04, which causes the main render pass in render_plane to select the banked sprite rather than the centered one. Since neither handler checks whether the opposing direction is also active, there is no way for the net-zero input to produce the level sprite. Contrast with up+down, where the last-evaluated key wins outright — see Pressing up and down simultaneously always results in slow speed.
Pressing up and down simultaneously always results in slow speed
When both up and down are held at the same time, the plane always slows down. scan_keyboard (scan_keyboard) evaluates up before down: handle_up (handle_up) writes SPEED_FAST and clears CONTROLS_BIT_SPEED_NOT_FAST, then handle_down (handle_down) immediately overwrites with SPEED_SLOW and sets both speed control bits. Last writer wins unconditionally.
This is inconsistent with the left/right case (see Pressing left and right simultaneously shows banked plane sprite), where the two moves cancel each other out and the net position is unchanged. Here there is no cancellation — one input simply silently overwrites the other. The outcome in both cases is an accident of evaluation order, not a deliberate design choice.
Wrong addresses in Player 2 status line
When displaying the Player 2 status line, the code at $65A1 uses incorrect source address and byte count parameters for the memory copy. The ofix directives at $65A1 (LD DE) and $65A4 (LD BC) correct these values to properly copy the status line text.