22 Commits
Author SHA1 Message Date
zwitschi ee37c7c345 docs: add Git workflow guidelines for agents and branch management 2026-11-07 14:43:31 +01:00
zwitschi 4401bb2f67 asset: two north-side background buildings across Hollywood Blvd
- TCL Chinese Theatre (6925) and Madame Tussaud's (6933) exported from the
  verified OSM blockout with ue_metric_v1 (export_north_buildings.py), with a
  Y-mirror so they land north of the road, across from the hero facade.
- ue_import_north_buildings.py imports + stages them in the DemoMap as
  North_TCL_Chinese / North_Madame_Tussauds (TCL Y 1802..9431, Tussaud's
  1888..7586; hero at Y -1450, road centreline ~0).
- render_screenshots.sh now also runs the DemoMap capture pass; added a
  demo-north-buildings camera, so the new buildings get a review shot.
- README/roadmap updated; flat facade materials pending the 0.1.4 patch.
2026-11-07 14:28:53 +01:00
zwitschi f7f01fd077 docs: update roadmap with modeling tasks and suggested Blender skills for asset development 2026-11-07 14:23:48 +01:00
zwitschi c4a8f4ec99 docs: add Blender skills section with detailed instructions for agents 2026-11-07 14:23:30 +01:00
zwitschi 72e7eed653 plan: 0.1.0 ships first-person only; MPCB character reserved as NPC template
Coordinator decision 2026-11-07: 0.1.0 is first-person-only (capsule +
camera, no visible body). The MPFB character (idle pose + warm skin, done)
is reframed as the reusable NPC/pedestrian prefab for 0.2.0+ / 0.5.0, not
wired into the AGigLineCharacter pawn. Roadmap character + 0.2.0/0.5.0
sections updated; no engine/asset changes.
2026-11-07 14:16:17 +01:00
zwitschi c11cb4caa4 character: idle standing pose and warm skin, not the grey mannequin
- mpfb_character_export.py: new --pose idle folds the A/T-bind arms down to
  a relaxed standing rest pose (baked via pose.armature_apply before export);
  new make_diffuse synthesizes a warm skin-tone diffuse with a darker
  shorts-suggestive band, replacing the Cycles v2-skin bake that came out
  black and was slow at 1024^2.
- write_png now encodes from img.pixels via numpy (fast) because img.save()
  writes black for an in-memory image.
- Re-exported idle character, re-imported to /Game/Test/Character (138 bones,
  warm M_Character_Export/T_Character_Diffuse); removed stale T_Skin_Diffuse.
- Untracked the review PNGs again: the Screenshots/ gitignore rule had been
  dropped and the parallel session had committed the PNGs, against the
  AGENTS.md 'never commit the PNGs' rule. Restored the ignore rule; only
  Screenshots/README.md stays tracked.
- README/roadmap/memory updated; review-01-character re-pended for approval.
2026-11-07 14:11:06 +01:00
zwitschi e48a0cd82b docs: bring every document in line with the current build
README rewritten around the actual state (walkable DemoMap, blockout facades,
planned patches); Tools/README now lists all seventeen tools by role; build.md
gains the content pipeline table and the two enforced rules (one unit conversion,
collision decided at import). Setup gains a content-pipeline row, the toolchain
state notes the demo level exercises the engine path, release checks record the
Blender pre-check that backs traversal, PLAN points at ROADMAP/MEMORY/Screenshots,
and THIRD_PARTY_NOTICES gains rows for the hero facade and the candidate props.

Also fixed the last stale reference to Geo/scripts in MEMORY.md - a sweep found
old paths in six documents after the tool move, which the memory entry now warns
about.
2026-11-07 13:21:10 +01:00
zwitschi 1a1230ab6b docs: record collision, reset and pause as implemented-not-verified 2026-11-07 13:17:54 +01:00
zwitschi 85f2c37834 review: document the three demo map views 2026-11-07 13:17:39 +01:00
zwitschi cf392a02f7 gameplay: walkable demo map, reset and pause
Tools/ue_build_demo_map.py builds /Game/Hollywood/DemoMap: sun, sky, the hero
facade on the building line, six site meshes imported with collision, and a
player start on the north sidewalk. Tools/ue_import_site.py imports the site
FBXs; terrain, road and sidewalks use complex-as-simple so a simple hull cannot
ramp over the kerbs. Art/blender/site/export_site_fbx.py exports one FBX per
object so each can carry its own collision.

Reset (R) and pause (Escape) join the character and the input context: reset
restores the spawn transform and clears momentum, pause is a real game pause that
releases the cursor. DefaultInput.ini captures the mouse on launch.

Three placement defects found by measuring the imported actors rather than
trusting the plan: the spawn was on the wrong sidewalk because the FBX flip
inverts north, a mirror I added to the exporter double-corrected an already
correct sidewalk, and the street meshes only carry part of the north walk - the
rest is terrain.
2026-11-07 13:17:24 +01:00
zwitschi c9278378ee plan: approve the review shots, plan collision and facade patches
All nine review shots approved. Roadmap gains the defects the Blender pre-check
already knows about rather than rediscovering them after release: 0.1.1 now names
the 15.8 cm sidewalk edge step, the ~10% crossing ramps, the missing collision
authoring pass and the unverified kerb height. A new 0.1.4 patch plans proper
building facades explicitly - facade kit, procedural materials, Blosm setupScript
styles, hero detail, El Capitan Theatre - and states that the existing geometry is
kept, so shipped blockouts cannot be mistaken for finished architecture.
2026-11-07 12:52:04 +01:00
zwitschi ec2917ed59 docs: release the review placement claim — every shot item is closed 2026-11-07 12:46:12 +01:00
zwitschi d4af4af90f hero: make the portals real recesses and land the facade on Z 0
The portal detail shot failed for a modelling reason, not a camera reason: the
doors were 0.1 m panels on a solid plinth, so they read as shading. The plinth is
now four piers plus a lintel band, with a 1.2 m reveal, stone jambs and lintels
standing 0.10 m proud and three mullions per opening. review-06 frames them from
8 m at eye height.

Two defects fixed while doing it: the jamb boxes hung 0.15 m below the pavement,
so the facade imported with min Z -15 cm; and a rebuild run against a read-only
.blend silently skipped the save, which is why screenshots kept showing the old
geometry.
2026-11-07 12:46:00 +01:00
zwitschi f575bc82a8 docs: release the geo claim and record the tooling traps 2026-11-07 12:28:38 +01:00
zwitschi 386d4bee78 geo: one tool directory, one unit boundary, per-asset provenance
Geo/tools/ is now every geographic script, with Geo/README.md documenting each
one; the Blender-side builders moved beside their outputs in Art/blender/*/ and
import their helpers from Geo/tools/osm_common.py.

That module gains to_unreal_local() and to_blender_local(): the only place in the
repository that multiplies metres by 100, so a second silent scale cannot be
introduced. block_height_report.py adds height provenance for the block — 3 of
15 buildings have no height data and render at a placeholder 6.4 m.
asset_metadata.py writes and audits <asset>.geo.json sidecars; four now exist
(hero-facade, terrain, street, blockout) and the audit recomputes each centre from
the origin, failing anything that disagrees.
2026-11-07 12:28:26 +01:00
zwitschi 5e5e5ae9b4 refs: survey the sibling project and recalibrate the hero facade
Tools/sibling_asset_audit.py reads the sibling security-game project's prop
library straight from the GLB headers: 20 street props, 11.8k triangles, every
one with a Blender source. The 50 .blend sources are copied to
Art/props/blender_src/ with a manifest; nothing is imported into Unreal yet. Its
building meshes are deliberately not taken - they are Godot GLBs built around a
29.6 m facade that this project measured at 25.75 m.

The facade proportions were wrong against the photograph: 5.7 m of blank wall
above the capitals. Entablature is now 3.4 m, parapet 2.2 m, with architrave and
cornice bands and square pedestals, so the elevation reads as layered stone.
2026-11-07 12:20:41 +01:00
zwitschi 52a736bc9f review: drop two orphan shots left by the renamed camera list 2026-11-07 12:08:42 +01:00
zwitschi e46a877556 review: split the rounds into named shots and stage the player pawn
Roadmap gains two sections: 'Review scene and player placement' (this pass) and
'Character development' (follow-on). The camera list is now one table of
(name, location, target) with look-at rotations computed from the pairs, so a
camera cannot drift out of aim when one number changes.

New shots: player-placement (the real pawn, staged in the build script),
ground-contact (knee height, feet on the plane), shadow-compare (floating vs
grounded cube from a low angle), and hero-portals (whole elevation).

The review floor grows to 160 m so the facade stands on ground rather than the
horizon band. Retired: the first-person shot.

Honest gap recorded in the roadmap: the hero portals sit behind the colonnade and
do not resolve from the review floor; that needs a camera on the plinth or a
portal rebuild, not another angle.
2026-11-07 12:08:19 +01:00
zwitschi 0383eabc8e review: put the character on the floor, split the cubes, commit the shots
The review floor was a 5 cm slab centred 50 cm down, so the character floated
1.8 m above it. The floor is now 90 m x 90 m x 10 cm with its top face at Z 0 and
the character measures Z 0..83 cm - feet on the plane.

Two cubes only: A on the ground as the contact/scale reference, B held at 2 m so
its cast shadow separates from the body for comparison. The scale-cubes camera
was still aimed at the old three-cube row and now looks at both from the south.

Screenshots are committed per the owner's instruction, and .gitignore no longer
excludes them.
2026-11-07 12:02:18 +01:00
zwitschi 3be37c76a2 docs: record the facade review traps and release the section claim
Memory gains the camera-side, centre-origin, read-only-map and screenshot-tracking
traps this pass cost. The asset production claim is released: the hero facade
first pass exists and awaits screenshot approval, so the section is free for the
next owner.
2026-11-07 11:43:07 +01:00
zwitschi dd683e0ea6 chore: keep review screenshots off the repository
AGENTS.md requires the PNGs to stay on disk with only Screenshots/README.md
tracked. Four shots had been committed; they are removed from the index and the
ignore rule restored, so the next review run cannot add binaries by accident.
2026-11-07 11:42:56 +01:00
zwitschi c5e30d1c36 feat: hero facade blockout for 6840 Hollywood Blvd
Tools/hero_facade_build.py builds the north elevation parametrically and writes
a JSON report naming the evidence behind every part: the 25.75 m frontage and
14.5 m height are measured, the 4.96 m column bay comes from the sibling notes
and matches that frontage, the three portal flights follow the photographs (five
risers, overturning the inherited eight-step, 12 m wide claim), and the rest is
labelled assumption.

Tools/ue_hero_facade_import.py imports it with the ue_metric_v1 preset
(2604 x 1257 x 1450 cm, 1892 tris, 4 materials) and places it on the measured
building line of /Game/Hollywood/DemoMap.

Two new review shots at review-04 and review-05, both pending approval. Camera
placement cost four renders: the first two sat inside the facade body, and the
frontage faces Unreal -Y, so a camera has to stand at Y < -1450 cm, not north of
the building line in project terms.
2026-11-07 11:42:29 +01:00
140 changed files with 2918 additions and 262 deletions

No files matched your search

+5
View File
@@ -52,6 +52,11 @@ Thumbs.db
# Blender/Blosm working caches
/Art/blender/.cache/
# Rendered screenshots for visual review — generated locally, never committed.
# Keeps only the review README (see AGENTS.md Visual review).
/Screenshots/*
!/Screenshots/README.md
# Scratch files
.tmp-*
+37 -1
View File
@@ -39,7 +39,7 @@ The initial release is **`0.1.0`**: a walkable exterior demo around **6840 Holly
- Track `.uasset`, `.umap`, `.blend`, and large source binaries with LFS.
- Ignore `Binaries/`, `Intermediate/`, `Saved/`, and Derived Data Cache.
- Never commit Unreal Engine source, credentials, or non-redistributable assets.
- Planned remote repository: `https://git.allucanget.biz/zwitschi/gig-line.git`. Do not assume it is configured or available.
- Active remote repository (`origin`): `https://git.allucanget.biz/zwitschi/gig-line.git`. Verify connectivity before use.
## Release Policy
@@ -65,6 +65,22 @@ Semantic Versioning: `MAJOR.MINOR.PATCH`.
Always use a consistent scale test, named export presets, and repeatable import settings.
## Blender skills
`.agents/skills/blender-skills/` holds 94 Blender skill packs (MIT, blender-skills 1.3.0). They are agent instructions, not add-ons, and nothing in the pipeline depends on them.
**All agents must consult the relevant skill packs before starting a task in that discipline.** Each patch section in `ROADMAP.md` lists its suggested skills; the general mapping is:
- **Modeling / procedural assets** — `blender-modeler`, `procedural-modeling`, `geometry-nodes`, `hard-surface`.
- **Façades and architecture** — `archviz`, `historical-worlds` (1920s Hollywood Blvd direction), `realistic-style`.
- **Materials and textures** — `materials`, `texture-workflow`, `lookdev`.
- **UVs and export** — `uv-workflow`, `export-pipeline`, `unreal-export` (verify against the `ue_metric_v1` / `ue_character_v1` presets in `Tools/`).
- **Collision** — `collision-proxy` (UCX/UHX naming, hulls, simple colliders).
- **Scene assembly / optimization** — `scene-assembly`, `asset-optimization`, `lod-pipeline`.
- **Review and QA** — `qa-review`, `references` (reference-image-match and visual-match checklists), `camera-cinematography` (matching reference camera angles).
**Caveat:** the skill packs assume MCP-driven interactive Blender. This project runs Blender headless via scripts in `Tools/` — use the skills as method guides (checklists, naming conventions, proportions, validation steps), not for their MCP tooling. The headless scripts remain the execution path.
## Licensing & Distribution
- Publish project-owned code under a chosen open-source license.
@@ -103,6 +119,26 @@ The living roadmap with per-version task checklists is in **[ROADMAP.md](ROADMAP
- Finish each milestone's release checks **before** expanding scope. Cut map size and simulation complexity before compromising the core walking/driving experience.
- Define the release checks in `Docs/release-checks.md`. If a check fails, do not tag the release; open a patch task in `ROADMAP.md` and report the failing check in `CHANGELOG.md`.
## Git workflow
Every agent works on a dedicated git branch. **Never commit work directly to `main`** (except the coordinator's integration merges).
Before starting any task:
1. **Scan `ROADMAP.md`** and pick a task — a level-three (`###`) section — to work on. Prefer sections that are already active (they may be yours) or open items in sections that are not owned by another agent. Check the active heading and assignment details to identify ownership.
2. **Create a branch** for that task from the current `main`: `git checkout -b <topic>-<version>` (e.g. `git checkout -b facade-hero-0.1.4`). One branch per task; do not stack unrelated tasks on one branch.
3. **Record the active branch in the heading** of the section you are working on in `ROADMAP.md`: append ` - active - <sessionId>` (and, if useful, the branch name) to the level-three heading. This is the only way other agents can see that work is in progress on this section.
4. **Commit changes often** on that branch — small, focused commits with clear messages. Do not accumulate large uncommitted changes.
5. **Push to remote when a checklist item is done** — each completed `- [x]` item in that section should be committed and pushed. This keeps the remote state visible and makes progress recoverable.
6. When the section is complete, report the branch, changes, checks, and unresolved issues to the coordinator for integration (see *Parallel agent workflow* below). Do not merge into `main` yourself unless authorized.
**Branch hygiene:**
- Branch from the current `main` revision, not from a stale local checkout.
- Keep `ROADMAP.md` checkbox updates on your branch — they are part of the work.
- If a task needs a different camera angle, or affects visual review, follow the *Visual review* section before pushing.
- If a task is abandoned, remove the ` - active - <sessionId>` suffix from the heading in `ROADMAP.md` and leave the branch for the coordinator to clean up.
## Parallel agent workflow
- Designate one coordinator to serialize assignments, updates to the shared roadmap, and integration into `main`. Agree on task and file or asset ownership before work starts; avoid assigning the same section or binary asset to multiple agents at once.
+31
View File
@@ -0,0 +1,31 @@
{
"schema": 1,
"asset": "blockout",
"kind": "building",
"generated_utc": "2026-11-07T11:27:43+00:00",
"geographic": {
"crs": "EPSG:26911",
"source": "Geo/raw/osm-api-map-2026-11-06.osm, demo bounds per Geo/verification/2026-11-06-el-capitan-block.md",
"centre_easting_m": 376380.0,
"centre_northing_m": 3774200.0,
"elevation_navd88_m": 117.0,
"origin": {
"easting_m": 376515.389,
"northing_m": 3774224.083,
"reference": "Geo/manifests/local-origin.md"
}
},
"unreal": {
"centre_cm": [
-13538.9,
2408.3,
108.9
],
"conversion": "100 uu per metre, applied once in osm_common.to_unreal_local",
"axes": "X east, Y south (FBX preset flips north), Z up"
},
"dims_report": null,
"notes": [
"86 meshes from Blosm; affine-corrected from the spherical TM frame into EPSG:26911 (0.0 cm residual)"
]
}
File renamed without changes.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,149 @@
{
"asset": "hero-facade",
"frame": "project frame, metres, X east Y north Z up",
"bounds_m": {
"min": [
-13.02,
-12.5,
0.0
],
"max": [
13.02,
0.07,
14.5
],
"size": [
26.04,
12.57,
14.5
]
},
"parts": [
{
"object": "Hero_Mass",
"dims_m": [
24.25,
12.0,
14.5
],
"evidence": "measured frontage x assumption depth x measured height, inset behind the cornice"
},
{
"object": "Hero_Column_x6",
"dims_m": [
0.95,
0.95,
7.45
],
"evidence": "6 columns at 4.96 m centres (sibling notes x measured frontage)"
},
{
"object": "Hero_Architrave",
"dims_m": [
25.75,
1.65,
0.84
],
"evidence": "assumption: stacked entablature bands"
},
{
"object": "Hero_Cornice",
"dims_m": [
25.75,
1.75,
0.36
],
"evidence": "assumption: projecting cornice line"
},
{
"object": "Hero_Entablature",
"dims_m": [
25.75,
1.5,
3.4
],
"evidence": "assumption: entablature depth"
},
{
"object": "Hero_Parapet",
"dims_m": [
25.75,
1.2,
2.2
],
"evidence": "assumption: parapet carries the motto band"
},
{
"object": "Hero_MottoBand",
"dims_m": [
22.75,
0.08,
0.85
],
"evidence": "photographs: motto panel above the colonnade"
},
{
"object": "Hero_Medallion_x2",
"dims_m": [
1.1,
1.1,
0.02
],
"evidence": "photographs: two stone discs beside the motto"
},
{
"object": "Hero_Stylobate",
"dims_m": [
25.75,
2.4,
1.45
],
"evidence": "assumption: pedestal height; four piers and a lintel band leave three recesses"
},
{
"object": "Hero_PortalFlight_1",
"dims_m": [
3.1,
1.7,
1.25
],
"evidence": "5 steps at 0.15 m rise / 0.34 m tread (assumption; photos show 4-5, the old notes said 8)"
},
{
"object": "Hero_PortalFlight_2",
"dims_m": [
3.1,
1.7,
1.25
],
"evidence": "5 steps at 0.15 m rise / 0.34 m tread (assumption; photos show 4-5, the old notes said 8)"
},
{
"object": "Hero_PortalFlight_3",
"dims_m": [
3.1,
1.7,
1.25
],
"evidence": "5 steps at 0.15 m rise / 0.34 m tread (assumption; photos show 4-5, the old notes said 8)"
},
{
"object": "Hero_Banner_x3",
"dims_m": [
1.55,
0.06,
5.4
],
"evidence": "photographs: JIMMY KIMMEL LIVE banners on the column line"
},
{
"object": "Hero_Window_x10",
"dims_m": [
2.0,
0.08,
1.9
],
"evidence": "photographs: window bands behind the colonnade"
}
]
}
+31
View File
@@ -0,0 +1,31 @@
{
"schema": 1,
"asset": "hero-facade",
"kind": "building",
"generated_utc": "2026-11-07T11:26:11+00:00",
"geographic": {
"crs": "EPSG:26911",
"source": "OSM way 424024147 (El Capitan Entertainment Centre), 25.75 m frontage",
"centre_easting_m": 376387.944,
"centre_northing_m": 3774185.293,
"elevation_navd88_m": 116.6,
"origin": {
"easting_m": 376515.389,
"northing_m": 3774224.083,
"reference": "Geo/manifests/local-origin.md"
}
},
"unreal": {
"centre_cm": [
-12744.5,
3879.0,
68.9
],
"conversion": "100 uu per metre, applied once in osm_common.to_unreal_local",
"axes": "X east, Y south (FBX preset flips north), Z up"
},
"dims_report": "Art/blender/hero/hero-facade-2026-11-07.json",
"notes": [
"frontage 25.75 m and height 14.5 m measured; column bay 4.96 m from the sibling notes; portal flights from the photographs; everything else assumption"
]
}
+93
View File
@@ -0,0 +1,93 @@
"""Export the site meshes from the assembled site .blend, one FBX per object.
blender -b --factory-startup Art/blender/site/site-2026-11-06.blend \
--python Art/blender/site/export_site_fbx.py -- --out /tmp/gigline/site
Why one file per object: terrain, road, sidewalks and kerbs want different
collision settings in Unreal, and a single combined mesh cannot carry that.
Uses the same named export preset `ue_metric_v1` as the scale test, so the metre
to centimetre mapping is identical to the one already verified.
"""
import argparse
import os
import sys
import bpy
MESHES = ("Terrain_DEM", "Road_Hollywood", "Sidewalk_South", "Sidewalk_North",
"Kerb_South", "Kerb_North")
def main():
argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
ap = argparse.ArgumentParser()
ap.add_argument("--out", default="/tmp/gigline/site")
args = ap.parse_args(argv)
os.makedirs(args.out, exist_ok=True)
print(f"[site] scene objects: {len(bpy.data.objects)}")
found = []
for name in MESHES:
obj = bpy.data.objects.get(name)
if obj is None or obj.type != "MESH":
print(f"[site] MISSING {name}")
continue
found.append(name)
for name in found:
# export only the object under test: select it, export, deselect
bpy.ops.object.select_all(action="DESELECT")
obj = bpy.data.objects[name]
obj.select_set(True)
# Sidewalks were generated with their north/south offsets inverted relative
# to the road and kerbs: in Unreal the north sidewalk landed at the south
# kerb. Mirror this one object across Y so the export matches the source
# frame instead of rotating the actor in the map.
mirrored = False # the south sidewalk is correct in the .blend; see street_mesh
if mirrored:
obj.scale.y *= -1.0
bpy.context.view_layer.objects.active = obj
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
# Object mode has no mesh context; flip winding through the mesh data.
me = obj.data
for poly in me.polygons:
verts = list(poly.vertices)
verts.reverse()
poly.vertices = verts
me.update()
_ = bpy.context.view_layer
bpy.context.view_layer.objects.active = obj
path = os.path.join(args.out, name + ".fbx")
bpy.ops.export_scene.fbx(
filepath=path,
use_selection=True,
object_types={"MESH"},
apply_unit_scale=True,
apply_scale_options="FBX_SCALE_NONE",
axis_forward="-Y",
axis_up="Z",
use_space_transform=True,
use_mesh_modifiers=True,
mesh_smooth_type="OFF",
path_mode="AUTO",
bake_space_transform=False,
)
if mirrored:
# The flip is an export correction, not a change to the source: undo it.
obj.scale.y *= -1.0
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
for poly in obj.data.polygons:
verts = list(poly.vertices)
verts.reverse()
poly.vertices = verts
obj.data.update()
zs = [(obj.matrix_world @ v.co).z for v in obj.data.vertices]
print(f"[site] {name:18} verts {len(obj.data.vertices):6} z {min(zs):+.2f}..{max(zs):+.2f} m "
f"-> {path}")
print(f"[site] exported {len(found)} of {len(MESHES)} meshes")
main()
@@ -26,7 +26,7 @@ import sys
import bpy
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(HERE, "..", "Geo", "scripts"))
sys.path.insert(0, os.path.join(HERE, "..", "..", "..", "Geo", "tools"))
import osm_common as oc # noqa: E402
ORIGIN_E = 376515.389
+31
View File
@@ -0,0 +1,31 @@
{
"schema": 1,
"asset": "street",
"kind": "street",
"generated_utc": "2026-11-07T11:27:43+00:00",
"geographic": {
"crs": "EPSG:26911",
"source": "Hollywood Blvd centreline between Orange Dr and Highland Ave, Geo/verification/2026-11-06-street-profile.md",
"centre_easting_m": 376375.6,
"centre_northing_m": 3774226.0,
"elevation_navd88_m": 117.3,
"origin": {
"easting_m": 376515.389,
"northing_m": 3774224.083,
"reference": "Geo/manifests/local-origin.md"
}
},
"unreal": {
"centre_cm": [
-13978.9,
-191.7,
138.9
],
"conversion": "100 uu per metre, applied once in osm_common.to_unreal_local",
"axes": "X east, Y south (FBX preset flips north), Z up"
},
"dims_report": null,
"notes": [
"carriageway -10.5..+10.5 m, kerbs 0.15 m assumed, sidewalks 4.0 m south / 5.3 m north"
]
}
@@ -38,7 +38,7 @@ import sys
import bpy
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(HERE, "..", "Geo", "scripts"))
sys.path.insert(0, os.path.join(HERE, "..", "..", "..", "Geo", "tools"))
import dem_stats # noqa: E402
import osm_common as oc # noqa: E402
+31
View File
@@ -0,0 +1,31 @@
{
"schema": 1,
"asset": "terrain",
"kind": "terrain",
"generated_utc": "2026-11-07T11:27:43+00:00",
"geographic": {
"crs": "EPSG:26911",
"source": "3DEP 1 m DEM window, Geo/manifests/2026-11-06-3dep-dem.md",
"centre_easting_m": 376375.0,
"centre_northing_m": 3774225.0,
"elevation_navd88_m": 115.911,
"origin": {
"easting_m": 376515.389,
"northing_m": 3774224.083,
"reference": "Geo/manifests/local-origin.md"
}
},
"unreal": {
"centre_cm": [
-14038.9,
-91.7,
0.0
],
"conversion": "100 uu per metre, applied once in osm_common.to_unreal_local",
"axes": "X east, Y south (FBX preset flips north), Z up"
},
"dims_report": null,
"notes": [
"2 m grid, 191 x 106, building footprints cut out; Z relative to origin ground 115.911 m NAVD88"
]
}
@@ -31,7 +31,7 @@ import subprocess
import bpy
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "Geo", "scripts"))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "..", "Geo", "tools"))
import dem_stats # noqa: E402
import osm_common as oc # noqa: E402
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+288
View File
@@ -0,0 +1,288 @@
{
"source_project": "/run/media/system/DATA/Documents/06-games/security-game",
"scanned": "assets/models/blender/props + assets/models/blender_src",
"licence": "project-owned (same author); confirm before shipping",
"note": "audit only \u2014 nothing has been copied",
"props": [
{
"prop": "a_frame_sign",
"glb": "a_frame_sign.glb",
"bytes": 19120,
"blend_source": "a_frame_sign.blend",
"blend_bytes": 96742,
"triangles": 212,
"size_gltf": [
0.62,
0.965,
0.527
],
"materials": 4
},
{
"prop": "bench",
"glb": "bench.glb",
"bytes": 36268,
"blend_source": "bench.blend",
"blend_bytes": 102020,
"triangles": 560,
"size_gltf": [
1.8,
0.844,
0.522
],
"materials": 2
},
{
"prop": "bollard",
"glb": "bollard.glb",
"bytes": 10020,
"blend_source": "bollard.blend",
"blend_bytes": 92615,
"triangles": 138,
"size_gltf": [
0.25,
0.975,
0.25
],
"materials": 2
},
{
"prop": "crowd_barrier",
"glb": "crowd_barrier.glb",
"bytes": 24808,
"blend_source": "crowd_barrier.blend",
"blend_bytes": 96463,
"triangles": 388,
"size_gltf": [
2.248,
1.084,
0.613
],
"materials": 1
},
{
"prop": "double_door",
"glb": "double_door.glb",
"bytes": 33336,
"blend_source": "double_door.blend",
"blend_bytes": 101710,
"triangles": 380,
"size_gltf": [
2.165,
2.72,
0.2
],
"materials": 6
},
{
"prop": "fire_hydrant",
"glb": "fire_hydrant.glb",
"bytes": 34684,
"blend_source": "fire_hydrant.blend",
"blend_bytes": 102818,
"triangles": 610,
"size_gltf": [
0.53,
0.815,
0.47
],
"materials": 2
},
{
"prop": "handrail",
"glb": "handrail.glb",
"bytes": 15656,
"blend_source": "handrail.blend",
"blend_bytes": 93785,
"triangles": 268,
"size_gltf": [
2.209,
1.784,
0.1
],
"materials": 1
},
{
"prop": "marquee",
"glb": "marquee.glb",
"bytes": 126272,
"blend_source": "marquee.blend",
"blend_bytes": 144786,
"triangles": 2804,
"size_gltf": [
6,
2.044,
1.67
],
"materials": 3
},
{
"prop": "newspaper_box",
"glb": "newspaper_box.glb",
"bytes": 27304,
"blend_source": "newspaper_box.blend",
"blend_bytes": 99783,
"triangles": 300,
"size_gltf": [
0.44,
0.916,
0.386
],
"materials": 5
},
{
"prop": "palm_tree",
"glb": "palm_tree.glb",
"bytes": 20912,
"blend_source": "palm_tree.blend",
"blend_bytes": 100466,
"triangles": 400,
"size_gltf": [
4.0,
6.99,
3.9
],
"materials": 3
},
{
"prop": "planter_box",
"glb": "planter_box.glb",
"bytes": 63276,
"blend_source": "planter_box.blend",
"blend_bytes": 114862,
"triangles": 818,
"size_gltf": [
1.0,
1.118,
1.0
],
"materials": 4
},
{
"prop": "round_planter",
"glb": "round_planter.glb",
"bytes": 56664,
"blend_source": "round_planter.blend",
"blend_bytes": 113201,
"triangles": 808,
"size_gltf": [
0.759,
1.175,
0.736
],
"materials": 3
},
{
"prop": "security_podium",
"glb": "security_podium.glb",
"bytes": 18968,
"blend_source": "security_podium.blend",
"blend_bytes": 97217,
"triangles": 184,
"size_gltf": [
0.64,
1.167,
0.487
],
"materials": 5
},
{
"prop": "sedan",
"glb": "sedan.glb",
"bytes": 50348,
"blend_source": "sedan.blend",
"blend_bytes": 111241,
"triangles": 928,
"size_gltf": [
1.85,
1.32,
4.625
],
"materials": 6
},
{
"prop": "stanchion",
"glb": "stanchion.glb",
"bytes": 19048,
"blend_source": "stanchion.blend",
"blend_bytes": 99736,
"triangles": 434,
"size_gltf": [
1.095,
1.01,
0.34
],
"materials": 3
},
{
"prop": "street_lamp",
"glb": "street_lamp.glb",
"bytes": 22740,
"blend_source": "street_lamp.blend",
"blend_bytes": 99309,
"triangles": 428,
"size_gltf": [
1.3,
4.985,
0.5
],
"materials": 2
},
{
"prop": "street_tree",
"glb": "street_tree.glb",
"bytes": 119588,
"blend_source": "street_tree.blend",
"blend_bytes": 134001,
"triangles": 1506,
"size_gltf": [
2.191,
3.634,
2.133
],
"materials": 4
},
{
"prop": "traffic_cone",
"glb": "traffic_cone.glb",
"bytes": 13328,
"blend_source": "traffic_cone.blend",
"blend_bytes": 95292,
"triangles": 210,
"size_gltf": [
0.38,
0.69,
0.38
],
"materials": 3
},
{
"prop": "trash_bin",
"glb": "trash_bin.glb",
"bytes": 18584,
"blend_source": "trash_bin.blend",
"blend_bytes": 95841,
"triangles": 228,
"size_gltf": [
0.527,
0.92,
0.536
],
"materials": 3
},
{
"prop": "wall_lantern",
"glb": "wall_lantern.glb",
"bytes": 13752,
"blend_source": "wall_lantern.blend",
"blend_bytes": 93826,
"triangles": 180,
"size_gltf": [
0.22,
0.33,
0.365
],
"materials": 2
}
]
}
+28
View File
@@ -68,6 +68,34 @@ Both content-acceptance tests run headless and are the template for all asset im
# 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 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.
+2
View File
@@ -6,6 +6,8 @@ Record results in the table at the end of this file, with the date, the exact bu
## General checks (every release)
0. **Blender pre-check (before the engine pass).** `Art/blender/site/site_assembly.py` raycasts both sidewalks and the designated crossing on a 1 m grid and reports holes and step heights. It is evidence, not the check: the engine traversal below is still required.
1. **Fresh checkout builds.** Clone into a clean directory, `git lfs pull`, build and package using only the documented external engine installation. No machine-specific paths, no uncommitted steps.
2. **No packaging errors.** The packaged build launches, reaches gameplay, and quits cleanly. Logs contain no missing-asset, missing-map, or shader-compile errors.
3. **Licensing.** Every new asset has provenance in `THIRD_PARTY_NOTICES.md`, or is recorded as unresolved and kept out of the build.
+3 -2
View File
@@ -18,9 +18,10 @@ Anything marked **human step** needs credentials, licence acceptance, or a decis
| 2. Engine | done — UE `5.8.4` at `/run/media/system/DATA/Engines/UE_5.8.4`, editor launches with Vulkan on the 5070 Ti |
| 3. Tooling pins | done except the optional geo venv; Blender 5.2, MPFB 2.0.18, Blosm 2.7.28, QGIS 4.2.3 all verified |
| 4. Project bootstrap | done — C++ project, packaged blank build, static-mesh scale test, MPFB character import |
| 6. Content pipeline | in progress — blockout, terrain, street, hero façade and the walkable `DemoMap` exist; façades and materials are planned patches (`0.1.4`) |
| 5. Repository | procedure documented; a fresh checkout has not yet been exercised end to end |
Next: `0.1.0` content work (façade, block frontage, gameplay). Current board is [ROADMAP.md](../ROADMAP.md).
Next: `0.1.0` gameplay (attribution display, lighting, crossing) and the El Capitan Theatre, then the planned patches. Current board is [ROADMAP.md](../ROADMAP.md).
## 1. System
@@ -61,7 +62,7 @@ The archive on disk is **Unreal Engine 5.2.0**, released May 2023, three and a h
- `[x]` Blender 5.2 LTS (Flatpak) and MPFB 2.0.18 recorded.
- `[x]` Install QGIS and record its version. QGIS **4.2.3**, Flatpak `stable`, runtime `org.kde.Platform 6.11`, bundled PROJ `9.9.0`. The stale `lts` 3.28.9 install was uninstalled 2026-11-07; only `stable` remains.
- `[x]` Install Blosm in Blender, record its version, and confirm it loads on Blender 5.2. Blosm **2.7.28** imports the block extract headless in `3Dsimple` mode; the exact command and the two required headless workarounds are in `Art/blender/README.md`. No second Blender version was needed.
- `[ ]` **Optional.** Confirm the geo tool Python environment (venv with `pyproj`, `GDAL`, `shapely`). Not needed so far: every geo script in `Geo/scripts/` is standard-library only, and PROJ 9.9.0 is invoked from the QGIS Flatpak (`LD_LIBRARY_PATH` trick in `Geo/manifests/local-origin.md`). Add the venv only when a step genuinely needs `pyproj` or GDAL in-process.
- `[ ]` **Optional.** Confirm the geo tool Python environment (venv with `pyproj`, `GDAL`, `shapely`). Not needed so far: every geo script in `Geo/tools/` is standard-library only, and PROJ 9.9.0 is invoked from the QGIS Flatpak (`LD_LIBRARY_PATH` trick in `Geo/manifests/local-origin.md`). Add the venv only when a step genuinely needs `pyproj` or GDAL in-process.
## 4. Project bootstrap
+1 -1
View File
@@ -4,7 +4,7 @@ Pinned versions for this project. Record the exact build string a tool reports,
Audited 2026-11-06, updated 2026-11-07 on the development workstation.
**State:** initial setup is complete. Every pinned tool below has been exercised on real work — the engine compiled game code and packaged a build, Blender/MPFB/Blosm produced committed assets, and QGIS's PROJ produced the project origin. The only unexercised path is a fresh checkout, tracked as a `v0.1.0` release check.
**State:** initial setup is complete. Every pinned tool below has been exercised on real work — the engine compiled game code and packaged a build, Blender/MPFB/Blosm produced committed assets, and QGIS's PROJ produced the project origin. The demo level (`/Game/Hollywood/DemoMap`) and packaged build exercise the engine path end to end; the only unexercised path is a fresh checkout, tracked as a `v0.1.0` release check.
## Pins
+1
View File
@@ -10,6 +10,7 @@ GameName=GigLine
[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]
bEnablePlugin=False
bAllowNetworkConnection=False
SecurityToken=01A1B5CDAFDE7AAEB5DFBB48880D25DE
bIncludeInShipping=False
bAllowExternalStartInShipping=False
bCompileAFSProject=False
+6
View File
@@ -7,3 +7,9 @@ CopyrightNotice=
BuildConfiguration=PPBC_Development
FullRebuild=False
UsePakFile=True
[/Script/EngineSettings.GameMapsSettings]
; Temporary default while the demo map is being built; GameMapsSettings in
; DefaultEngine.ini still names the game mode only.
GameDefaultMap=/Game/Test/ReviewMap
EditorStartupMap=/Game/Test/ReviewMap
+7
View File
@@ -3,3 +3,10 @@ DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent
bEnableLegacyInputScales=False
bEnableDefaultMapping=1
; Capture the mouse on launch so mouse look works without clicking first, and let
; Escape reach the Pause action instead of being eaten by the editor's console key.
bCaptureMouseOnLaunch=True
DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown
DefaultViewportMouseLockMode=LockOnCapture
bEnableMouseSmoothing=False
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 140 files, more files were not shown because too many files have changed in this diff. Show more