One directory with sixty scripts stopped being navigable, and the grouping is also the sandbox boundary:
Tools/unreal/ commandlets and the two map builders, with ue_common.py and ue_placement.py as the
shared imports (they need the engine)
Tools/blender/ builders, exporters, the FBX preset, the MPFB character pipeline, blender_screenshots
(they need the Blender Flatpak)
Tools/review/ the visual loop: render_screenshots.sh, judge_screenshot.py, hero_compare.py,
build_comparison_md.py, e2e_asset_check.py, hero_iterate.sh, visual_loop.py,
visual_targets.json
Tools/gen/ image and texture generation: the ComfyUI driver, deterministic texture writers,
reference fetching
Tools/input/ OS-level input injection
root _common.py, check-lfs.sh, addon_compat_probe.py, sibling_asset_audit.py, tests/
Every moved script now resolves the repository root as ../.. and puts the tools root plus its siblings on
sys.path, so 'import ue_common' still works from unreal/. The test suite bootstrap does the same for the five
folders. render_screenshots.sh takes the folder as a third argument to run_cmdlet, and the e2e driver,
hero_iterate.sh and the comparison generator were repointed.
51 README rows now link to their new location, the README gains a Layout section naming each folder's
sandbox, and the architecture notes and Blender README follow the moves.
Verified: 108 tests pass, prettier is clean, judge_screenshot.py and hero_compare.py run from their new
homes, and the e2e run was aborted mid-way (it had been rebuilding an empty DemoMap for 15 minutes) and is
being rerun against the new layout.
107 lines
6.2 KiB
Markdown
107 lines
6.2 KiB
Markdown
# Building Block View
|
||
|
||
## Whitebox Overall System
|
||
|
||
The system decomposes into five top-level building blocks:
|
||
|
||
| **Name** | **Responsibility** |
|
||
| --- | --- |
|
||
| Gameplay | Player pawn, movement, camera, input bindings, HUD, game mode |
|
||
| Site | Terrain, road, sidewalks, kerbs, crossing markings, site-level collision |
|
||
| Façades | Hero façade (El Capitan), south block frontage, north-side buildings |
|
||
| Art Pipeline | Blender models, geographic data, export scripts, import scripts |
|
||
| QA & Review | Screenshot pipeline, self-test harness, visual review workflow |
|
||
|
||
### Gameplay
|
||
|
||
C++ classes in `Game/GigLine/Source/GigLine/`:
|
||
|
||
| Class | Responsibility | Key detail |
|
||
| --- | --- | --- |
|
||
| `AGigLineCharacter` | First-person player pawn | 1.75 m capsule, 4.5 m/s walk, Enhanced Input bindings, reset, pause, `-qaselftest` harness |
|
||
| `AGigLineGameModeBase` | Sets game mode and HUD class | `HUDClass = AGigLineHUD` |
|
||
| `AGigLineHUD` | HUD text overlay | `DrawText` every frame: controls bottom-right, and an F3 debug readout top-left (`gigline.Debug`, on for `-perf`/`-qaselftest`) |
|
||
| `AGigLineNPCPerson` | NPC prefab (future) | Capsule + visible MPFB body, feet on Z 0 |
|
||
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
||
| `UGigLineAssetTools` | C++ collision helpers | `SetComplexCollisionAsSimple` on `StaticMesh` assets |
|
||
|
||
Input assets in `/Game/Input/`: `IA_Move`, `IA_MoveBack`, `IA_Strafe`, `IA_StrafeLeft`, `IA_Look`, `IA_Jump`, `IA_Reset`, `IA_Pause`, `IA_ToggleCamera`, `IA_ToggleDebug`, bound in `IMC_Default`.
|
||
|
||
Player-facing bindings: **WASD** move, **mouse** look, **Space** jump, **R** reset, **Escape** pause, **V** swap first/third person. The camera and body work landed with `0.2.0` (see ADR-9): the shipped default view stays first person, and `-thirdperson` starts the pawn in the third-person rig — used by the screenshot run so the review is reproducible.
|
||
|
||
### Site
|
||
|
||
Static meshes and materials in `/Game/Hollywood/Site/`:
|
||
|
||
| Asset | Role |
|
||
| --- | --- |
|
||
| `Terrain_DEM` | Ground heightfield (complex-as-simple collision) |
|
||
| `Road_Hollywood` | Carriageway surface (block-all collision) |
|
||
| `Sidewalk_North`, `Sidewalk_South` | Pedestrian surfaces (block-all collision) |
|
||
| `Kerb_North`, `Kerb_South` | Kerb edges |
|
||
| `Crossing_Markings` | Zebra markings at signalised crossing |
|
||
| `M_Asphalt`, `M_Concrete`, `M_KerbConcrete`, `M_Ground`, `M_RoadPaint`, `M_Stucco`, `M_FacadeStone` | Procedural materials (world-space-noise blend + roughness) |
|
||
|
||
### Façades
|
||
|
||
| Asset | Role |
|
||
| --- | --- |
|
||
| `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade |
|
||
| `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) |
|
||
| `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) |
|
||
| `SM_Retail_LeeDrug`, `SM_Retail_6806` | Retail trim over 6800 and 6806–6820, modelled from their own photograph (`Tools/blender/retail_frontage_build.py`, staged as `RetailTrim_*`). `6822 Budget` stays a bare volume: no photograph exists. |
|
||
|
||
### Art Pipeline
|
||
|
||
Python scripts in `Tools/` drive the content pipeline:
|
||
|
||
| Script group | Purpose |
|
||
| --- | --- |
|
||
| `export_*`, `hero_facade_build` | Blender headless export (FBX) |
|
||
| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement |
|
||
| `character_anim_build`, `ue_character_anim_import` | Character animation clips (`GigLine_Idle`, `GigLine_Walk`) and their import |
|
||
| `export_*`, `hero_facade_build`, `retail_frontage_build`, `theatre_trim_build`, `facade_kit_build` | Blender headless export (FBX); trim builders work in world coordinates |
|
||
| `ue_import_*`, `ue_hero_facade_import`, `ue_import_retail_detail` | Unreal headless import + placement |
|
||
| `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) |
|
||
| `ue_create_input_assets` | Enhanced Input actions + mapping context |
|
||
| `render_screenshots.sh` | Screenshot capture pipeline |
|
||
| `judge_screenshot.py` | Vision-model pre-check (optional) |
|
||
| `input_emulation.py`, `input_test.py` | OS-level virtual keyboard/mouse injection for input verification |
|
||
| `Tools/_common.py` | Pure helper shared by Blender builders, importable without Blender (bay layout) |
|
||
| `Tools/tests/` | Stdlib `unittest` tests for the pure parts of the tools (`requirements-tools.txt`) |
|
||
| `Geo/tools/mapbox_buildings.py` | Second height source: Mapbox `mapbox-streets-v8` building data vs our OSM heights |
|
||
|
||
Source data: `Art/blender/` (`.blend` files), `Geo/` (OSM extracts, DEM, verification docs). Tool rules (one script one job, result files for commandlets, clean worktree for generators, documented inventory, tests for the pure parts) are in [`AGENTS.md`](../../AGENTS.md#python-and-shell-tooling).
|
||
|
||
### QA & Review
|
||
|
||
- `AGigLineShotActor` walks fixed cameras in `-game` mode, captures PNGs, and quits.
|
||
|
||
- `-qaselftest` switch on `AGigLineCharacter` runs a core-ticker harness: walk 2 s, reset, pause/unpause, ground transect — all PASS/FAIL logged.
|
||
|
||
- `Screenshots/` holds committed PNGs and `README.md` approval table.
|
||
|
||
## Level 2
|
||
|
||
### White Box Gameplay — Input Flow
|
||
|
||
1. `AGigLineCharacter::SetupPlayerInputComponent` binds `IA_*` actions to `MoveForward`, `MoveBack`, `MoveStrafe`, `MoveLeft`, `Look`, `StartJump`/`StopJump`, `ResetToStart`, `TogglePause`.
|
||
|
||
2. Movement delegates to `ApplyMove(Forward, Strafe)` → `AddMovementInput`.
|
||
|
||
3. Look applies yaw/pitch scaled by `LookSensitivity` (Y invertable via `bInvertLookY`).
|
||
|
||
4. `ResetToStart` teleports to `StartLocation` (captured on first grounded frame), clears velocity, resets control rotation.
|
||
|
||
5. `TogglePause` toggles `APlayerController::SetPause`, swaps input mode between `FInputModeGameOnly` and `FInputModeUIOnly`, shows/hides mouse cursor.
|
||
|
||
### White Box Site — Collision Model
|
||
|
||
- Every site mesh (road, sidewalks, kerbs, crossing) is `STATIC` with `BlockAll` collision.
|
||
|
||
- `Terrain_DEM` uses `CTF_UseComplexAsSimple` (forced by `UGigLineAssetTools` at build time, saved on the asset).
|
||
|
||
- The terrain corridor is carved to half-width 10.7 m around the road centreline so the player can walk the carriageway and both sidewalks.
|
||
|
||
- Ground Z: north sidewalk 395, road 366, south sidewalk 317 (3.94 m fall along the block, matching the DEM).
|