Merged PR #32: 0.1.5 — hero detail, scene audit, material orphaning fixed Co-authored-by: Zwitschi <zwitschi82@gmail.com>
10 KiB
Build
Fresh-checkout build, content-pipeline and packaging procedure for the walkable demo. Begun 2026-11-07 from a blank build and extended through the 0.1.x patches; the release checks that exercise it are in release-checks.md.
Constraints
- Engine installation is external to the repository. Record its path and exact version in toolchain.md.
- Build output (
Binaries/,Intermediate/,Saved/,DerivedDataCache/) is never committed. - Large content is LFS-tracked, so a fresh clone needs
git lfs install && git lfs pullbefore any build.
Engine
Pinned install: Unreal Engine 5.8.4 (CL 58902052, promoted build) at /run/media/system/DATA/Engines/UE_5.8.4. The engine bundles no Linux clang; the system clang (23.1.4, Fedora 45) is the game-code toolchain. Game targets must use BuildSettingsVersion.V7 to share the installed editor's build environment.
Fresh-checkout build
git clone <remote> gig-line && cd gig-line
git lfs install && git lfs pull
Tools/check-lfs.sh # must pass before any content build
# Compile the project's editor target (first build also proves the toolchain)
cd /run/media/system/DATA/Engines/UE_5.8.4
Engine/Build/BatchFiles/Linux/Build.sh GigLineEditor Linux Development \
-project="$PWD/../../Documents/06-games/gig-line/Game/GigLine/GigLine.uproject" \
-WaitMutex
# Expected tail: "Result: Succeeded"; module binary lands in
# Game/GigLine/Binaries/Linux/libUnrealEditor-GigLine.so
# Open in the editor (GUI, Vulkan)
./Engine/Binaries/Linux/UnrealEditor \
/run/media/system/DATA/Documents/06-games/gig-line/Game/GigLine/GigLine.uproject
Adapt the -project= path to the actual checkout location.
Package a Linux build
cd /run/media/system/DATA/Engines/UE_5.8.4
Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \
-project="/run/media/system/DATA/Documents/06-games/gig-line/Game/GigLine/GigLine.uproject" \
-noP4 -platform=Linux -clientconfig=Development \
-cook -build -stage -pak \
-archive -archivedirectory="/run/media/system/DATA/Builds/GigLineQA" \
-unattended
# Expected: "AutomationTool exiting with ExitCode=0 (Success)" and "EXIT=0", ~90 s
# Launch test (plain, no -map): /run/media/system/DATA/Builds/GigLineQA/Linux/GigLine.sh
Launch test must open the DemoMap. A plain ./GigLine.sh should load /Game/Hollywood/DemoMap (set via DefaultEngine.ini GameMapsSettings). If it instead opens /Engine/Maps/Templates/OpenWorld, the game shows an empty non-interactive "stuck" scene — check that GameDefaultMap is in DefaultEngine.ini, not DefaultGame.ini. Confirm the loaded map in the engine log: .../Linux/GigLine/Saved/Logs/GigLine.log (LoadMap: /Game/Hollywood/DemoMap). The archive directory is deliberately outside the repository; never archive into the checkout.
Headless content checks
Both content-acceptance tests run headless and are the template for all asset import verification:
# Static-mesh scale test (Blender export -> Unreal import -> measure)
# Blender: Tools/scale_test_export.py, Unreal: Tools/ue_scale_test_import.py
# MPFB character (generate -> rig -> bake -> export -> skeletal import)
# Blender: Tools/mpfb_character_export.py, Unreal: Tools/ue_character_import.py
# Unreal side of any test:
./Engine/Binaries/Linux/UnrealEditor-Cmd \
/run/media/system/DATA/Documents/06-games/gig-line/Game/GigLine/GigLine.uproject \
-run=pythonscript -script=<repo>/Tools/<script>.py -nullrhi -unattended -nopause -stdout
# Note: 5.8 swallows Python print() in the commandlet; scripts write result files to /tmp.
Content pipeline (current)
The hero block and the demo level are built by a fixed sequence. Each step writes a result file under /tmp/gigline/; read it, because the commandlet's own stdout can be swallowed.
| Step | Tool | Output |
|---|---|---|
| OSM blockout | Art/blender/blockout/blosm_blockout.py |
Art/blender/blockout/blockout-*.blend |
| Terrain | Art/blender/terrain/terrain_from_dem.py |
Art/blender/terrain/terrain-*.blend |
| Street | Art/blender/street/street_mesh.py |
Art/blender/street/street-*.blend |
| Site assembly | Art/blender/site/site_assembly.py |
Art/blender/site/site-*.blend |
| Site export | Art/blender/site/export_site_fbx.py |
seven FBXs, one per mesh (terrain, road, both sidewalks, both kerbs, crossing) |
| Hero façade | Tools/hero_facade_build.py |
Art/blender/hero/hero-facade-*.blend + JSON part report |
| Block frontage | Tools/export_block_frontage.py |
six frontage FBXs from the blockout |
| North buildings | Tools/export_north_buildings.py |
TCL and Tussaud's FBXs from the blockout |
| Site import | Tools/ue_import_site.py |
/Game/Hollywood/Site/* |
| Frontage import | Tools/ue_import_block_frontage.py |
/Game/Hollywood/Frontage/* |
| North import | Tools/ue_import_north_buildings.py |
/Game/Hollywood/North/* |
| Hero import | Tools/ue_hero_facade_import.py |
/Game/Hollywood/ElCapitan/SM_HeroFacade |
| Demo map | Tools/ue_build_demo_map.py |
/Game/Hollywood/DemoMap |
| Façade kit assembly | Tools/ue_apply_facade_kit.py |
kit actors in DemoMap |
| Theatre trim | Tools/ue_stage_theatre_trim.py |
marquee + blade sign actors |
| Scene audit | Tools/ue_audit_scene.py |
materials, placement spans, labels (gate) |
| Review shots | Tools/ue_build_review_map.py + Tools/render_screenshots.sh |
Screenshots/ |
Order matters. ue_build_demo_map.py rebuilds the site materials, so any actor staged by another tool must be (re)staged after it, or it keeps a reference to a material that no longer exists — that is how 604 actors once ended up untethered from their materials while the map only looked slightly flat. Tools/render_screenshots.sh runs the full chain in the right order and gates on ue_audit_scene.py.
Every Blender exporter calls Tools/fbx_export_preset.py (ue_metric_v1 / ue_character_v1) instead of repeating the FBX argument block — one place for the scale conversion, the axis mapping and mesh_smooth_type="FACE" (without which every Unreal import warns about missing smoothing groups and round geometry arrives faceted).
Two rules that the pipeline enforces rather than documents:
- One conversion. Metres to Unreal centimetres happens only in
Geo/tools/osm_common.py::to_unreal_local. Sidecars (<asset>.geo.json) record the result andGeo/tools/asset_metadata.py auditre-derives it. - Collision is decided at import, not later: terrain, road and sidewalks are complex-as-simple; kerbs and props stay simple. A simple hull over a kerbed street ramps straight across the kerb.
Known engine quirks (2026-11-07)
- One handled
PSOPrecacheensure fires at packaged-build exit only; not blocking. - Interchange 5.8 does not create material/texture assets for skeletal FBX imports —
Tools/ue_character_import.pyfinishes that chain explicitly. - Android Turnkey status errors and datarouter DNS warnings in logs are benign.
Packaged Linux build
Current QA archive: /run/media/system/DATA/Builds/GigLineQA. A plain ./GigLine.sh opens /Game/Hollywood/DemoMap; controls are in controls.md and shown in-game bottom-right. The packaged log is written relative to the wrapper's working directory, i.e. <archive>/Linux/GigLine/Saved/Logs/GigLine.log — not into the repository.
Behaviour check without a human at the keyboard:
cd /run/media/system/DATA/Builds/GigLineQA/Linux
./GigLine.sh -windowed -ResX=1280 -ResY=720 -nosplash -qaselftest
# then read <archive>/Linux/GigLine/Saved/Logs/GigLine.log for "GigLine QA:" lines
-qaselftest walks for 2 s, resets, pauses/unpauses, sweeps a 16-row seam transect, fires a ground-referenced 21 m wall probe along the street, fires 40 m façade-occlusion traces sideways from the road centre wherever a building is staged, and writes a frame-time series to Saved/Profiling/. Every phase logs ... PASS/FAIL and the run ends with RESULT.
Traps that cost real time in 0.1.x
| Symptom | Cause | Fix |
|---|---|---|
| A builder reports success but the asset is unchanged | .blend/.umap are LFS-tracked and check out read-only; Blender and Unreal fail the save quietly |
chmod u+w <file> first — ue_build_*/ue_hero_facade_import and every Blender builder need it |
File format is not supported when reopening a .blend |
hero_facade_build.py --out writes the FBX; putting the .blend path there overwrites it with FBX bytes |
--out /tmp/…fbx --save-blend Art/…blend --report Art/…json |
Add-on not loaded: "bl_ext.blender_org.mpfb" |
mpfb_character_export.py needs the MPFB add-on visible to Blender |
export BLENDER_USER_SCRIPTS (see the invocation in ../Art/blender/README.md) |
| The packaged run exits after a couple of seconds during QA | GigLineShotActor runs its screenshot list and quits (bQuitWhenDone) |
it skips its rounds when -qaselftest is on the command line — keep that guard |
Headless -nullrhi traces report no hits for everything |
the null RHI has no physics scene | verify traces in the packaged run (-qaselftest), never in a commandlet |
| Import logs "No smoothing group information" for every mesh | mesh_smooth_type="OFF" in the FBX export |
use Tools/fbx_export_preset.py (FACE) |
PIE input test (compare editor vs packaged input intake)
Use to isolate whether the "no controls respond" bug is the packaged standalone's input intake or the Enhanced Input wiring generally.
Tools/run_pie.shopens the editor on/Game/Hollywood/DemoMap. Press the green Play (PIE) button and walk / mouse-look.- Interpretation:
- PIE works -> the Enhanced Input wiring is fine and the standalone packaged build's SDL input intake is the environment-dependent bug.
- PIE fails too -> the Enhanced Input setup itself is broken; rebuild the input config / character from scratch.
- The DemoMap is PIE-ready as committed:
GlobalDefaultGameMode+GameDefaultMap=/Game/Hollywood/DemoMap, and the map stages a PlayerStart at(-13336,-1150,600)on the cut sidewalk with the walkableAGigLineCharacter.