- Converted 13 individual .adoc section files to .md via asciidoctor→docbook5→pandoc(gfm) + post-processing, placed alongside the .adoc sources in Docs/Architecture/ - Rebuilt architecture.md from the individual section .md files - Ran prettier --write on all .md in the repo (23 files changed): normalised table column alignment, trailing whitespace, line breaks - Added .agents/ to .prettierignore (vendored third-party content) - All .md now passes prettier --check
5.8 KiB
Build
Fresh-checkout build procedure. Completed 2026-11-07 after the pinned engine was installed and a blank Game/GigLine build was packaged and launch-tested.
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 -allmaps -build -stage -pak \
-archive -archivedirectory="/run/media/system/DATA/Builds/GigLine" \
-unattended
# Expected: "BUILD SUCCESSFUL" (~1 min for the blank project; archive ~1.1 GiB)
# Launch test (plain, no -map): /run/media/system/DATA/Builds/GigLine/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 |
six FBXs, one per mesh |
| Hero façade | Tools/hero_facade_build.py |
Art/blender/hero/hero-facade-*.blend + JSON report |
| Site import | Tools/ue_import_site.py |
/Game/Hollywood/Site/* |
| Hero import | Tools/ue_hero_facade_import.py |
/Game/Hollywood/ElCapitan/SM_HeroFacade |
| Demo map | Tools/ue_build_demo_map.py |
/Game/Hollywood/DemoMap |
| Review shots | Tools/ue_build_review_map.py + Tools/render_screenshots.sh |
Screenshots/ |
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
- 2026-11-07: blank
Game/GigLineDevelopment build packaged via the command above; 1.1 GiB archive at/run/media/system/DATA/Builds/GigLine/Linux;GigLine.shlaunched on the desktop session, Vulkan swapchain created, 759 frames rendered across a 60 s smoke test. Controls document to be written with the first playable (0.1.0Gameplay section).