A repo in transition from a legacy Android/libGDX prototype to a UE5-first air-defense game with real 3D city ingestion, photoreal material targets, and no static gameplay backdrops.
This project is an early alpha test. Many systems are experimental, incomplete, or actively being migrated, and many or most features may not work as intended. The project is provided as-is, without any responsibility or liability for failures, incorrect behavior, data loss, compatibility issues, or other consequences from using or testing it.
- Agent operating guide:
AGENTS.md - Docs index:
docs/index.md - Agent routing:
docs/reference/ai-agent-context-routing.md - Agent skills:
docs/reference/ai-agent-skills.md - Agent integrations:
docs/reference/ai-agent-integrations.md - Agent web research stack:
docs/reference/ai-agent-web-research-stack.md - Agent upstream sources:
docs/reference/ai-agent-upstream-sources.md - UE5 engine mandate:
docs/planning/ue5-engine-mandate.md - UE5 city sourcing plan:
docs/planning/ue5-city-model-strategies.md - UE5 active city pilot:
docs/planning/ue5-city-pilot-helsinki-kalasatama.md - UE5 evaluated city candidate:
docs/planning/ue5-city-pilot-3dbag-rotterdam.md - UE5 regression root cause log:
docs/planning/ue5-regression-root-cause-2026-04-17.md - UE5 visual acceptance:
docs/planning/ue5-visual-acceptance.md - UE5 Android packaging:
docs/planning/ue5-android-packaging.md - Architecture reference:
docs/architecture.md - Release/install behavior:
docs/release-and-install.md - Benchmark suite:
docs/benchmark-suite.md - Benchmark sources:
docs/benchmark-sources.md - Core detekt priorities:
docs/core-detekt-priorities.md - Android visual QA:
docs/android-visual-qa.md - Android visual QA sources:
docs/reference/android-visual-qa-sources.md - Popular 3D Android game workflows:
docs/popular-3d-android-game-workflows.md - Level asset pipeline:
docs/level-asset-pipeline.md - Level asset source map:
docs/level-asset-source-map.md - Runtime asset attribution:
android/assets/ATTRIBUTION.md - UE5 city pipeline skill:
.agents/skills/ue5-city-pipeline/SKILL.md - UE5 photoreal scene skill:
.agents/skills/ue5-photoreal-city-scene/SKILL.md
- UE5 is the only permitted engine for new runtime, rendering, tooling, editor, prototype, and shipping work.
- The Android/libGDX codebase remains in-repo only as migration input and gameplay reference.
- The active runtime city pilot uses the local Helsinki Kalasatama 3D Tiles dataset through Cesium for Unreal.
- The offline photoreal shipping path remains official mesh or OBJ source -> Blender cleanup -> UE5 Nanite; Helsinki Kalasatama is also the current best candidate for that bake because an official OBJ mesh exists.
- Direct geospatial runtime rendering via Cesium or ArcGIS is allowed for truth-checking, inspection, and bootstrap validation. It is not automatic permission to skip the later shipping bake.
- Install the verified Cesium for Unreal plugin locally:
.\scripts\install-cesium-for-unreal.cmd - Validate the UE5 city pipeline:
py -3 .\tools\ue5_city_pipeline\test_ue5_city_pipeline.py - Verify the UE5 bootstrap path headlessly:
.\scripts\verify-ue5-bootstrap.cmd - Build one storage-safe packaged Win64 runtime:
.\scripts\package-ue5-runtime.cmd4b. Build an Android APK from the UE5 runtime (requires UE 5.7, Android NDK r25b, JDK 17; seedocs/planning/ue5-android-packaging.md):.\scripts\package-ue5-runtime-android.cmd - Capture the packaged runtime:
.\scripts\capture-ue5-runtime-screenshot.cmd -Exe packaged/Win64/ProjectAirDefenseUE5.exe - Capture the packaged menu, battle, and systems states serially:
.\scripts\run-ue5-mobile-ui-proof.cmd - Capture the editor-game runtime without repackaging:
.\scripts\capture-ue5-editor-runtime-screenshot.cmd - Open the UE5 scaffold under
ue5\ProjectAirDefenseUE5\.
Local Helsinki tooling, when the active source needs to be rebuilt or refreshed:
.\scripts\generate-ue5-city-pilot.cmd, .\scripts\download-ue5-city-source.cmd, .\scripts\prepare-ue5-city-tiles.cmd, and .\scripts\upgrade-ue5-city-tiles.cmd.
- Unreal Engine
5.7 - Blender
5.1.0 - Cesium for Unreal
2.25.0
- Default runtime city source: local Helsinki Kalasatama 3D Tiles
- Runtime time controls: systems drawer
TIMEcontrols step solar hour, slow/fast cycle rate, and pause/resume day/night progression throughACesiumSunSky. - Runtime camera controls:
W/A/S/Dor arrow keys to pan,Q/Eto yaw,T/GorNumpad8/Numpad5to pitch,PageUp/PageDownor mouse wheel to zoom,R/Fto raise/lower,Hometo reset - Runtime graphics settings backend:
UProjectAirDefenseGameUserSettingsowns AA method, AO, motion blur, ray-tracing request state, and UE scalability groups on startup for both editor-game and packaged runtime lanes; those toggles are no longer hard-forced inDefaultEngine.ini - Runtime camera settings remain authored in meters in
UProjectAirDefenseRuntimeSettings, butAProjectAirDefenseCityCameraPawnconverts them to Unreal units internally. This avoids the 100x framing error that produced roof-level closeups from Cesium tileset bounds.
These bullets describe the outgoing Android/libGDX prototype that remains in-repo for migration reference.
- Fire-control loop, not point-and-shoot: scan -> track table -> prioritize -> salvo engage -> terminal intercept.
- Live doctrine tuning: engagement range, interceptor speed, launch cooldown, radar refresh interval, blast radius, and salvo size are adjustable while fighting.
- Mixed raids: ballistic, cruise-like, decoy, and anti-radiation missile profiles.
- Counter-battery pressure: about 1 in 20 threat missiles is anti-radiation and can directly damage radar / ECS / launcher capacity.
- Shared simulation core: the GUI battle and the headless Monte Carlo runner now use the same missile, interceptor, damage, and wave logic.
These bullets describe the outgoing renderer only. They are not the target UE5 city scene.
- The old Android renderer uses a textured skyline backdrop and night panorama. That path is deprecated and not permitted in the future UE5 gameplay view.
- Procedural surface materials with diffuse texture detail and roughness response for buildings, roads, metal equipment, debris, and projectiles.
- Dynamic trails, blasts, camera shake, and persistent damage: buildings darken, lean, collapse in height, and emit debris when hit.
- Gameplay-first projectile readability: hostile missiles and interceptors are intentionally oversized and color-separated so they stay legible on mobile screens.
- RTX Patriot overview: https://www.rtx.com/raytheon/what-we-do/integrated-air-and-missile-defense/patriot
- Lockheed PAC-3 product page: https://www.lockheedmartin.com/en-us/products/pac-3-advanced-capability-3.html
- U.S. Army Patriot article: https://www.army.mil/article/171144/patriot_missile_system
android/assets/models/engel_house.objImported from the MIT-licensed Ladybug Tools / 3D Models repository. Source asset:obj/engel-house/AngelHouse_Bauhaus-in-Israel-r2.objReference notes in the source repo identify it as Engel House / Beit Engel, a Bauhaus-in-Israel model associated with Tel Aviv.- Runtime 3D Tiles dataset: Helsinki Kalasatama 3D Tiles, licensed under CC BY 4.0. Required credit: City of Helsinki / Helsinki 3D. The game loads the local prepared dataset through Cesium for Unreal.
- Evaluated remote 3D Tiles candidate:
3DBAG Rotterdam LoD2.2, licensed under CC BY 4.0.
Required credit:
© 3DBAG by tudelft3d and 3DGI.
- ProGuard/R8 enabled: minification and obfuscation for production security.
- Adaptive mobile renderer: GLES 2.0-safe path with quality-tier control and selective MSAA.
- Optimized memory: minimal allocations in the main loop using math buffers and pooled entities.
- Strict repositories: only Google and Maven Central are used for dependency resolution.
- Mandatory Kotlin format/lint: KtLint is the formatting gate; Detekt remains the semantic/code-smell audit.
- Report-oriented benchmark suite: build timing, startup, battle entry, runtime frame telemetry, runtime health capture, simulation sweeps, KtLint, lint, detekt, dependency health, and APK size snapshots.
- Android Gradle Plugin
9.1.0 - Gradle
9.4.1 - Kotlin JVM plugin
2.3.20 - libGDX
1.14.0 - Java
21 - Compile / target SDK
36
Android steps below are legacy maintenance and migration-reference only until the UE5 runtime replaces them.
- Open the project in the latest stable Android Studio.
- Make sure Java 21 and Android SDK 36 are installed.
- Sync Gradle.
- Run
.\gradlew.bat ktlintCheckfor the mandatory Kotlin format/lint gate. - Run
.\gradlew.bat ktlintFormatto apply repository formatting. - Run
.\gradlew.bat :android:testDebugUnitTestfor Android launch-policy and compatibility unit coverage. - Run
.\gradlew.bat :core:testfor gameplay and targeting logic coverage. - Run
.\gradlew.bat :core:runBattleMonteCarlo -Pruns=300 -Pwaves=1 -Pseconds=48 -Pstep=0.05for headless balance sweeps. - Or use
.\scripts\run-battle-monte-carlo.cmd 300 1 48 0.05 20260411on Windows without changing PowerShell execution policy. - Run
.\scripts\run-benchmark-suite.cmdfor the report-oriented benchmark suite. It captures build timings, startup macrobenchmarks, runtime frame telemetry, runtime-health artifacts, Monte Carlo balance metrics, and standards reports underbenchmark-results/. - Use a current Android 15 / API 35 Google APIs emulator. The verified repo lane is Pixel 9 Pro (
airdefense_android15_pixel9pro). - Run
powershell -ExecutionPolicy Bypass -File .\tools\android_visual_qa\bootstrap.ps1once on a Windows workstation that will do emulator QA. - Run
py -3 .\tools\android_visual_qa\visual_qa.py probebefore screen-driven emulator checks. - Run
python3 tools/update_readme_badges.py --checkafter badge metadata changes. - Run
.\gradlew.bat :android:installDebugto install the debug package on an emulator or device. - Clear any first-boot Android full-screen education overlay before OCR-based menu checks.
- Keep emulator proof in landscape; this game does not support portrait.
- Verify navigation with screenshot + OCR before tap, tap-proof JSON, and screenshot + OCR after tap; do not treat a live PID or logcat alone as proof of a usable battle scene.
- Local side-load build:
.\gradlew.bat :android:assembleLocal - Debug install:
.\gradlew.bat :android:installDebug - Production/update-safe build:
.\gradlew.bat :android:printAppIdentity :android:printReleaseSigningSource :android:assembleRelease
Production signing variables can be set in ~/.gradle/gradle.properties, CI secrets, or environment variables:
RELEASE_STORE_FILE=/absolute/path/to/keystore.jksRELEASE_STORE_PASSWORD=...RELEASE_KEY_ALIAS=...RELEASE_KEY_PASSWORD=...
releaseProduction package idcom.airdefense.game. Must use the stable release keystore.localDebug-signed package idcom.airdefense.game.local. Safe for local side-load testing.debugDebug-signed package idcom.airdefense.game.debug.
- This is still a gameplay prototype, not a military simulator.
- Static background images are not allowed in the gameplay battlespace going forward.
- The current UE5 city proof path is real local Helsinki 3D Tiles data through Cesium for Unreal. It is not a static panorama and not a fake skyline.
- The official Helsinki 3D Tiles package requires an explicit Cesium
3d-tiles-tools upgradepass before packaged runtime use because the upstream district payload contains legacyb3dmcontent. - Keep one canonical raw Helsinki archive under
data/external/downloads/and one active runtime dataset, then remove temporary backups after verification. .\scripts\package-ue5-runtime.ps1removesue5/ProjectAirDefenseUE5/Saved/StagedBuildsafter a successful archive by default because it is a duplicate of the packaged build..\scripts\run-ue5-mobile-ui-proof.ps1is the trusted packaged UI proof lane because it runs menu, battle, and systems captures serially under a per-build mutex. Do not launch parallel packaged captures against the same build..\scripts\capture-ue5-editor-runtime-screenshot.ps1is the low-waste iteration lane. Use editor-game capture first; repackage only after a verified scene or runtime change worth shipping.- The current pilot uses the native UE5/Cesium exposure path by default.
PostExposureBiasonly becomes an override when intentionally set to a non-zero value after measured visual proof. - The current renderer targets a high-quality mobile approximation of premium night lighting. Ray tracing is opt-in, off by default, and not the mobile baseline.
- Waterfront building placement and radar orientation are now validated in tests so the city stays inland and the radar reads top-down toward the horizon.
- Android is intentionally wide-only.
AndroidLauncherstays onsensorLandscape, and the manifest carries a targetedDiscouragedApilint suppression on that activity because the game is not intended to support portrait operation. - Android quality selection is now capability-based. High-capacity Android 15 emulator lanes can resolve above
PERFORMANCE, while genuinely low-memory devices still fall back safely. - AI-agent routing is intentionally compact and generated/verified in-repo so external agents do not keep rediscovering the same workflow.
- The repo's concise agent overlay is pinned to caveman
v1.5.0. Upstreamv1.5.0adds configurable default mode,off, and/caveman-help; this repo intentionally keeps only the mandatory instruction-onlylite-equivalent overlay. - Generated
build/,.kotlin/, and copied native-library output are intentionally excluded from git so the repository stays source-clean.