Files
gig-line/Docs/build.md
T
zwitschi 73aca9db80 feat(facades): 0.1.5 — hero detail, scene audit, material orphaning fixed (#32)
Merged PR #32: 0.1.5 — hero detail, scene audit, material orphaning fixed

Co-authored-by: Zwitschi <zwitschi82@gmail.com>
2026-11-08 22:56:08 +01:00

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 pull before 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 and Geo/tools/asset_metadata.py audit re-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 PSOPrecache ensure 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.py finishes 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.sh opens 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 walkable AGigLineCharacter.