Keyboard-only drone FPV low-altitude high-speed flight experience built with Godot Engine 4.
![]() |
![]() |
![]() |
![]() |
Drone FPV footage looks fun. This project tries to capture something like that feeling with just h, j, k, l — familiar keys for vi users. :god and :auto make it even easier; combine both and it practically flies itself.
- Godot Engine 4.4+
- Linux, Windows, or Web browser
- Android 10+ (API 30+) — see ANDROID.md
chmod +x vfpv.x86_64
./vfpv.x86_64Run vfpv.exe.
Open index.html via a local HTTP server:
cd Web && python3 -m http.server 8000Then open http://localhost:8000 in your browser.
See ANDROID.md.
| Key | Action |
|---|---|
h / l |
Yaw left / right |
H / L |
Sharp yaw left / right (2.5x) |
j / k |
Pitch down / up |
J / K |
Sharp pitch down / up (3x) |
Space |
Boost (consumes fuel, auto-recovers) |
p |
Pause / unpause |
<digits>g |
Set speed (e.g. 100g = 100 m/s) |
gg |
Set max speed |
G (Shift+g) |
Set min speed |
. |
Repeat last action for 1 second |
: |
Enter command mode |
| Command | Action |
|---|---|
:speed <n> |
Set base speed (20-400) |
:reset |
Respawn at start position |
:auto |
Toggle auto-avoidance mode |
:god |
Toggle god mode (bounce on collision) |
:fpv |
Switch to FPV camera |
:follow |
Switch to follow camera |
:stage terrain |
Switch to natural terrain stage |
:stage city |
Switch to urban city stage |
:stage canyon |
Switch to canyon stage |
:stage tube |
Switch to tube tunnel stage |
:quality low/mid/high/auto |
Set rendering quality (default: auto) |
:audio music |
BGM music |
:audio drone |
Drone propeller sound (pitch linked to motor output) |
:audio off |
Mute all sound |
:quit or :q |
Quit game |
Escape |
Cancel and return to normal mode |
- Vi-style controls — Navigate with familiar vim keybindings
- Stage selection —
:stage terrainfor natural terrain,:stage cityfor urban flying,:stage canyonfor towering rock walls,:stage tubefor enclosed tunnel racing - Procedural terrain — Infinite Perlin noise terrain with 3 biomes (canyon, mountain, plains)
- City stage — Dense urban grid with buildings 15–100m tall, tight 8–15m street gaps
- Canyon stage — Sharp ridged rock walls rising up to ~170m, red-brown to sandy palette, 30–60m valley gaps
- Tube stage — Infinite enclosed circular tunnel (diameter 40m) with coaster-style curves; colored ring markers and white spine line make curvature readable; up to 5 rival aircraft fly ahead slightly slower than the player
- Dynamic chunk loading — Terrain generates/destroys around player position
- Speed-linked FOV — Field of view widens with speed (80° - 110°)
- Motion blur — Radial blur intensifies with speed
- Chromatic aberration — RGB channel split at high speed
- Low altitude particles — Parabolic debris particles when flying low and fast
- Bank — Camera/drone tilts during turns; deeper bank on sharp turns
- Crash effects — Screen flash + camera shake + crash sound on terrain collision
- Auto mode —
:autotoggles automatic obstacle avoidance (raycast-based, last-moment, lateral preferred) - God mode —
:godtoggles invincibility (bounce off terrain instead of crashing) - Racing drone model — X-frame drone with spinning propellers and neon LED accents
- FPV overlay — Drone frame silhouette visible in FPV view
- BGM — Looping synthwave track with seamless crossfade
- Pause —
pto pause, auto-pause in command mode - Boost system — Temporary 1.5x speed with fuel gauge and engine sound
- Hyperspeed effects — Speed lines, drone glow, and music pitch up when boosting over 200 m/s
- Procedural SFX — Crash noise and boost engine sweep (generated at runtime)
- Quality settings —
:quality low/mid/high/autoadjusts render distance and mesh resolution; auto mode adapts to FPS - HUD — Speed, time, boost gauge, quality level, command line
project.godot
scenes/
main.tscn # Main scene
pause_menu.tscn # Android pause menu
settings_screen.tscn # Android settings screen
scripts/
main.gd # Scene initialization
player.gd # Flight physics, boost, crash/respawn
vi_input.gd # Vi-style input handling (desktop)
android_input.gd # Accelerometer + touch input (Android)
settings_manager.gd # Persistent settings via ConfigFile (Android)
terrain_manager.gd # Procedural terrain chunk management
city_manager.gd # Urban city stage chunk management
canyon_manager.gd # Canyon stage chunk management
tube_manager.gd # Tube stage: procedural tunnel + rival aircraft
hud.gd # HUD display
pause_menu.gd # Android pause menu logic
settings_screen.gd # Android settings screen logic
auto_pilot.gd # Raycast-based obstacle auto-avoidance
post_process.gd # Shader uniform management, crash FX, hyperspeed effects
sfx.gd # Procedural sound effects (crash, boost, wind)
low_altitude_particles.gd # Speed/altitude-linked particles
music/
bgm.ogg # BGM: "Future Travel" by Zodik (CC-BY 3.0)
shaders/
motion_blur.gdshader
chromatic_aberration.gdshader
speed_lines.gdshader
- Web (Compatibility renderer): Shadows disabled — Due to a Godot engine bug (godotengine/godot#90259), shadowed lights cause surfaces to appear overbright/white on the Compatibility renderer (WebGL). Shadows are automatically disabled when running on this renderer.
- Web: BGM does not play until first user input — Browser autoplay policy blocks audio until a user interaction (key press, click, etc.). BGM will start automatically after the first input.
- Web: BGM loop restarts from the beginning — The
loop_offsetsetting is not supported on the Web backend. On desktop, BGM loops seamlessly from a mid-point; on Web, it restarts from the beginning.
- Music: "Future Travel" by Zodik (CC-BY 3.0) — https://opengameart.org/content/zodik-future-travel




