100 Commits
Author SHA1 Message Date
Cursor Agentand西风逍遥游 95b061678b Fix architecture contracts for road types.
Document roadMaterialGroup ownership/lifetime and rename RoadLaneLink to
RoadLaneConnection so value-typed turn records are not treated as Links.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 14:18:13 +00:00
Cursor Agentand西风逍遥游 cfe6e97c31 Document Cloud Lavapipe host-RAM OOM for interchange+piers.
Clarify that the kill is Linux OOM on ~15Gi system memory, not GPU VRAM.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 14:12:19 +00:00
Cursor Agentand西风逍遥游 0f24effbd5 Tune interchange for denser pier bake: wider pier spacing and lighter elevated junctions.
Keeps piers enabled for real GPUs; Cloud Lavapipe OOM is host RAM (~15Gi), not VRAM.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 14:09:07 +00:00
Cursor Agentand西风逍遥游 587ba56758 Polish interchange: filleted ground cross and example key 5
Rebuild makeInterchange so the ground hub reuses the makeCross fillet
sizing and axis arms, smooth the elevated ring/ramps, wire scene key 5
in the example, and cover bake with an interchange scene test.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:53:36 +00:00
Cursor Agentand西风逍遥游 91f581855c Drop tip pads that reintroduced corner holes
Keep tip-disk removal, double-sided arc skirts, sidewalk top overhang,
shoulder tip caps, and exact jr trim — rectangular tip pads made more
salmon holes than they sealed.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:07 +00:00
Cursor Agentand西风逍遥游 78c809937e Own cross turn transitions with junction tip pads
Trim arms past jr so stub ears disappear, bridge with tip pads whose
outer skirts continue the curb-return tangent, and overhang the sidewalk
top past r2 so the gray arc edge no longer shows through.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:07 +00:00
Cursor Agentand西风逍遥游 f7e5e37cdd Close curb/sidewalk shoulders on large junction trims
Skip full U-caps on big trims still, but emit shoulder-only tip caps so
open arm ends stop showing through at the outer gray corner arcs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:07 +00:00
Cursor Agentand西风逍遥游 57087faa2d Seal curb-return skirts with double-sided walls
Emit both windings for asphalt curb, curb riser, and outer sidewalk
skirts so overhead views cannot cull them, overlap curb/sidewalk tops
at r1, and densify the arc. Tip disk to (±jr,±jr) stays removed.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 e812657827 Face curb-return skirts toward the hub camera
Overhead views were backface-culling property-facing skirt normals into
a thin silhouette; flip curb riser and outer gray skirts toward the hub.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 60a6deaf20 Meet curb returns at exact jr and close arc skirts
Drop rectangular tip pads that reintroduced turn spikes. Trim arms at
full junctionRadius so outer edges stay G1 with the sidewalk arc, and
emit the curb-to-sidewalk riser plus outer gray skirt on each segment.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 502b1e4edd Bridge arm tip stubs into outward curb-return arcs
Cover the square curb/sidewalk stub left by jr-0.2 arm trim with tip
pads and close the open tip faces so turn corners lose the sharp spur
and the outer gray skirt no longer shows through.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 c83da07ee4 Trim cross corner sidewalk tip and fix outer arc skirt
Drop the sidewalk fan to (±jr,±jr) that made a sharp property-corner
spike, and emit a walk-height sidewalk vertical on the outer gray arc
so the skirt faces render instead of showing through.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 3bebb8704c Restore outward-center curb returns at cross junctions
Revert convex (ah,ah) arcs that flipped the curb returns again.
Keep concave corners with centers at (±jr,±jr), sidewalk disks toward
the property corner, plus exact trim tips, seal strips, and U-cap skip.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 f399a11d3f Skip hub-facing U-caps on large junction trims
Full-profile end caps at the cross apron drew a dark tip bar that
read as a seam from above; the apron and tip pads already close the
opening.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 a6aa2a7f60 Seal cross tip faces and overlap arms into the apron
Snap trim tips 20cm into the junction, add curb/sidewalk pads along
each arm tip face, and fill the shoulder between tip outers and the
arc so salmon gaps cannot show at the corner joints.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 d36e3dbf9d Restore convex curb arcs and keep exact arm/apron tips
Outward-center (concave) returns left salmon seams at the corners.
Put circle centers back at asphaltHalf so the apron bulges convexly,
keep snapped trim endpoints plus tip seal strips, and retarget the
corner sidewalk test.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:51:06 +00:00
Cursor Agentand西风逍遥游 cf532a7b0d Close cross arm/apron seams with exact trim tips
Uniform path samples skipped the true junctionRadius, leaving ~0.2m
salmon gaps. Snap loft endpoints to the trim distances and add thin
asphalt seal strips under each arm tip.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 75e8a92539 Remove unused up vector in bakeJunction
Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 0fa7fb0764 Fix junction face winding to match mesh3D normals
Orient apron and curb-return quads so geometric winding agrees with
the stored normal (object-space CCW). Drop the dual-winding hack that
left dark/flipped corner faces under lit shading.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 569552dbeb Fill sidewalk disk toward outward curb-return centers
Cap the leftover quarter-disk at each corner so the property-side
pad is solid instead of showing through to the ground tint.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 8a207d4dac Flip curb returns so circle centers sit outward
Use corner centers at (asphaltHalf+R) so the asphalt edge is concave
and sidewalks wrap toward the property corner instead of bulging out.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 b3f11ac8bb Fix cross apron fill and arc face winding
Trim arms by the full junctionRadius so tips meet the fillet, build the
asphalt hub from simple rectangles plus quarter-disks, and emit both
face windings so Lavapipe keeps curb/sidewalk arc tops visible.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 6c02983a90 Fillet cross junction: push arms out and add curb arcs
Trim the four arms past asphalt half-width so sidewalks no longer
stack at the hub, fill a filleted asphalt apron, and rebuild the
corners as quarter-circle curb/sidewalk returns.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:37 +00:00
Cursor Agentand西风逍遥游 d6c220be90 Rebuild cross junction: asphaltHalf apron, corner pads, end caps
Size the hub trim to driving-lane width so arms meet a square asphalt
apron without a gap. Add raised curb corner platforms and profile end
caps so jersey-barrier U-channels are not see-through at the hub.
Paint zebra stripes on every arm approach.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 18f042fc9b Fix upright bridge piers and fill the cross junction apron
Piers now use a world-up orthonormal basis so columns stay vertical.
Axis-aligned crosses get a hub-fan square asphalt apron plus sidewalk
corner pads (single large strip-quads were dropping out under Lavapipe).

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 96c1fabc05 Add four simple road debug scenes before complex interchange
Replace the all-in-one interchange demo with straight/curve/bridge/cross
scenes, fix junction baking to a degree-gated asphalt disc (no unsorted
fan), and let the example switch scenes with keys 1-4.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 59e41eadb9 Fix asphalt group tagging and material-driven road look
Prefer asphalt on horizontal loft strips so the driving surface is not
tagged as curb, and render each mesh group with Material.setTint plus
high-angle camera, red ground, and translucent water in the example.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 c788cf0943 Match procedural road rendering to reference materials
Raise jersey-barrier profile defaults, add yellow center markings and
vertex colors, thicken nav overlays, and render each mesh group with
its own tint plus red ground/water and a high-angle camera.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 41634ca391 Ignore procedural-road example screenshot PNG
Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 d1b43e18a0 Harden procedural road navigation bake and example
Clamp nav arrow placement against non-finite/huge frame steps (seed 7 hang),
prefer same-lane turn links, fix the procedural-road example mesh upload path,
and cover seed-7 navigation termination in unit tests.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 80ce3bce34 Include ImageData.h in procgen.road texture recipe tests
Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 904ab63ef6 Fix RoadBake length Result shadowing V3 length helper
Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 a118a4876a Add procedural road network system under procgen
Introduce math-only road baking (profile loft, piers, markings,
navigation overlays) with mesh.roadNetwork / tex.roadMarkings recipes,
design docs, unit tests, and a procedural-road example.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-18 13:50:36 +00:00
Cursor Agentand西风逍遥游 45c56aa3f0 Match MapFog to cotton-puff FoW: cover islands, not alpha wash
Stop multiplying fog by soft unlock (that made a muddy fade). Gate by
cloud cover instead so deep fog stays opaque cotton with valley peek-
through, and the unlock rim breaks into sparse islands. Cast puff
silhouette shadows from offset cover samples onto unlocked ground only,
and harden clearCore so the hole stays clean.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-15 05:51:18 +00:00
Cursor Agentand西风逍遥游 1e4e7c07d8 Fix MapFog hole leftovers and dirty shadow smear
Hard clearCore from unwarped mask kills warp-pulled fog islands inside
the unlock hole. Shadow is rim-contact only (tiny offset) so soft
penumbra no longer paints a ghost of the hole onto the fog sheet.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-15 03:55:36 +00:00
Cursor Agentand西风逍遥游 3ed7b8b2ab Add gradual MapFog rim sparseness toward unlock
Deep fog stays a dense lit cotton sheet. Across a wide soft unlock
band, hard-clear only deep inside the hole; the approach frontier
raises the cover gate so fog breaks from sheet → clumps → sparse
islands — without a global fogAlpha wash.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-15 03:22:12 +00:00
Cursor Agentand西风逍遥游 cc46722d2d Fix MapFog: luminous cotton cores, not global alpha wash
User asked for partial luminous translucency (透亮) in soft valleys
between lit metaball puffs — not lowering fogAlpha / capping body
alpha, which muddied the whole sheet. Restore bright lit shading,
drive peek-through from height coverage alpha, keep fogAlpha high.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-15 01:50:25 +00:00
Cursor Agentand西风逍遥游 cd54c40d1b Make MapFog metaball puffs translucent with density falloff
Drive coverage from puff luminance so valleys stay see-through, thin the
sheet toward the unlock rim, and keep peak alpha partial — closer to the
reference cotton FoW where terrain peeks between frontier blobs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-15 01:25:57 +00:00
Cursor Agentand西风逍遥游 e5a4fb5443 Restyle MapFog clouds as lit cotton metaball puffs
Match the reference FoW look: overlapping circular cotton blobs with
top-left lighting, bubbly unlock rim stamps, and a hole-cast shadow that
follows the puff silhouette instead of flat fBm wallpaper.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-15 01:16:51 +00:00
Cursor Agentand西风逍遥游 1dc9140173 fix(procgen): satisfy api-lifetime lint on PointSet mesh attribute helper
Reword the modifyPointBounds Doxygen note so the architecture POINTER_API
heuristic no longer treats the comment as a raw-pointer declaration, and
document borrow/lifetime for assignWeightedMeshAttribute's mesh/weight tables.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-14 13:27:04 +00:00
Cursor Agentand西风逍遥游 62cb1d3455 feat(procgen): add landscape.sample and texture.sample PointGraph ops
Sample continuous heightfield/texture-mask scalars onto $Density or float
attributes (optional landscape project), closing the UE-style Texture and
Landscape Sampler gap beyond generate/filter/project-only spatial nodes.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-14 09:59:36 +00:00
Cursor Agentand西风逍遥游 be714ea243 feat(procgen): add PointGraph grid.sample and poisson.sample ops
Wire sampleGridPoints and poissonDiskPoints into zero-input graph nodes
with origin offsets, validation, and point-budget checks so scripts no
longer need to leave the PointGraph for basic XZ sampling.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-14 09:30:08 +00:00
Cursor Agentand西风逍遥游 dcf9f5bf60 feat(procgen): close P0/P1 PointGraph gaps for Get*, spawn publish, inspect, and attributes
Add graph-level spatial/points bindings with get.landscape/spline/actor nodes,
inspectNode for Attribute panels, undoable PcgInstancePublisher for spawn.mesh
scene batches, PointSet @Data domain with @Data/@Elements/@Last selectors,
rotation/swizzle float selectors, and partition/noise/int/vector attribute ops.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-14 09:00:58 +00:00
Cursor Agentand西风逍遥游 b75c7806d3 feat(procgen): add PointGraph attribute ops and $ field selectors
Close the deferred attribute gap from PCG node breadth: copy/rename/delete/
transfer, typed set/filter/compare/select, and a closed $Density-style
selector set for float channels—without UE multi-domain selector grammar.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-14 07:24:42 +00:00
Cursor Agentand西风逍遥游 d59f7f37a3 feat(procgen): add UE-style PointGraph breadth nodes
Expose first-class mesh/spline samplers, point-set booleans, normal-to-density,
bounds modify, weighted mesh spawn, and debug disable/inspect so the graph
covers the basic UE PCG node surface without copying UE asset formats.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-14 06:48:05 +00:00
Cursor Agentand西风逍遥游 2a3bb8ab3e fix(interior-mapping): correct room-space rays and atlas projection
The mapping looked flat/skewed because rays were cast on the wrong side of
the facade, world directions were mixed with room-local origins, and
B/(B+d) UV crush / center mullions distorted the pre-projected atlas.

Use per-window object space (window at z=+1 into -Z), Joost far-hit slab
tests, bounded B/(B+d) sampling, outer sash only, and a matching
perspective atlas bake.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-13 14:14:32 +00:00
Cursor Agentand西风逍遥游 5fd7084e7d chore(examples): drop accidental eve_snapshot.json from interior-mapping
Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:43:02 +00:00
Cursor Agentand西风逍遥游 2a8a0f1b8d fix(examples): preload room atlas and raise facade for Interior Mapping
Replace slow runtime ImageData painting with a generated PNG atlas, and
lift the window wall so all rows clear the ground plane.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:42:43 +00:00
Cursor Agentand西风逍遥游 85af5d9cff fix(level-designer): shorter viewport help and wider inspector
Keep shortcut text from clipping; give whitebox param labels more room.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:36:25 +00:00
Cursor Agentand西风逍遥游 22d9f4165a fix(level-designer): unwrap Primitive3D Result for gizmo overlays
Factories return Result; keep owned proxies and depth-ignore so axes render.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:32:38 +00:00
Cursor Agentand西风逍遥游 52decabb53 fix(level-designer): single-row toolbar and full palette list
Top region was clipping multi-row tools; palette nested rows hid most recipes.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:30:08 +00:00
Cursor Agentand西风逍遥游 b8ce0c04c3 fix(level-designer): flatten toolbar rows for reliable layout
Avoid nesting beginRow inside beginToolbar; use badge for EDIT/PLAY.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:17:57 +00:00
Cursor Agentand西风逍遥游 ae6ec9e7c3 refactor(level-designer): classic workspace UI shell
Replace the single left overlay panel with a Unity/Godot-style editor
layout (toolbar, outliner, embedded viewport, inspector, asset palette),
draw the transform gizmo, and route picks/camera through the viewport.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:16:39 +00:00
Cursor Agentand西风逍遥游 4708ea0ef4 feat(examples): add Interior Mapping (pre-projected room atlas)
Implement the Zhihu Interior Mapping technique as a Mesh3D example:
tangent-space ray-AABB, perspective correction, runtime room atlas,
procedural foreground furniture ray-march, window frames and fresnel.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 13:14:10 +00:00
Cursor Agentand西风逍遥游 f844e15c7b Fix MapFog washout and make hole shadow readable
Drop heavy screen-blend that bleached lit cloud maps to flat white, keep
color-map structure via average+multiply, and draw the under-cloud shadow
inside the unlocked hole so the volume cue is actually visible.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 12:01:29 +00:00
Cursor Agentand西风逍遥游 b580de561a Improve MapFog toward tutorial painted-cloud quality
Use domain-warped lit cloud maps (cool valleys / warm peaks), richer dual
blend, wispy unlock rims, stronger under-cloud shadow, and lighter fog tint
so the procedural sheet reads less like flat gray noise.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 11:50:34 +00:00
Cursor Agentand西风逍遥游 2fa181645c fix(devtools): avoid pause-on-caught-throw for raw VM DAP attach
DevTool::attach(HSQUIRRELVM) enabled sq_notifyallexceptions, so with
break-on-error the error hook paused at the throw site before catch /
reportError ran. That left a second pause hanging after one DAP continue
and flaked as SEGFAULT on Linux CI teardown
(devtools.dap.caughtErrorPausesAtReportSite). Keep notify-all only on
Runtime-bound attach (hook already capture-only there) and force-resume
in the test if the script thread is still paused.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-12 04:12:16 +00:00
Cursor Agentand西风逍遥游 7079cddc38 fix(ci): document Camera3D DOF bindings and Hd2dLook ownership
Source quality failed on undocumented setDepthOfField getters and on
api-lifetime for newLook/newMiniatureLook (and a Doxygen false positive).

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 17:13:05 +00:00
Cursor Agentand西风逍遥游 9fcf636a1c Tune MapFog clouds: larger seamless billows, soft unlock stamps
Lower cloud tiling/frequency so the sheet reads as soft dual-scroll
clouds instead of wallpaper noise, and stamp hard-core soft discs into
a hi-res mask so the starting unlock hole is contiguous with organic
edges under UV warp.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 16:23:36 +00:00
Cursor Agentand西风逍遥游 580e23e10d Fix MapFog look: soft dual clouds, organic unlock edges
Rewrite the cloud generator for large seamless billows, retune the
shader toward a translucent dual-scroll sheet (not wallpaper noise or
swiss-cheese density), and stamp a soft hi-res mask in the example so
unlock holes read as cloudy edges instead of hard grid rectangles.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 16:05:42 +00:00
Cursor Agentand西风逍遥游 9568929f87 Document MapFog Texture* ownership and lifetime
Satisfy api-lifetime architecture contracts on getCloudTexture,
getMaskTexture, and makeCloudTexture with @ownership/@lifetime tags.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 15:01:31 +00:00
Cursor Agentand西风逍遥游 60484d8e0d Document remaining MapFog script bindings
Source quality requires every newly bound MapFog getter/setter to appear
in docs/usr/modules/graphics.md; fill the missing API names.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 14:54:53 +00:00
Cursor Agentand西风逍遥游 1464f4f603 Fix map-fog example: drop HUD print without a font
Graphics::print requires setFont; the fog demo only needs the overlay
and console usage hints, so remove the on-screen print calls.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 14:44:08 +00:00
Cursor Agentand西风逍遥游 c38654d504 Add MapFog SLG large-map war-fog overlay
Implement dual-scrolling cloud fog with RGBA mask bridge (R unlock,
G select blink, B dissolve) and a pre-pass shadow, plus example and
unit tests following the common SLG FoW presentation pattern.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 14:16:10 +00:00
Cursor Agentand西风逍遥游 e681ebde45 feat(hd2d): add HD2DURP-style DOF look and DopFix sprite depth
Port the signature HD-2D miniature presentation from HD2DURP: Gaussian
depth-of-field on Camera3D/final HDR resolve, Hd2dLook presets, and
Sprite3D cutout depth-write controls so characters stay sharp in focus.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 14:13:54 +00:00
Cursor Agentand西风逍遥游 66b069d1f9 Polish venom character framing and refresh captures.
Face the Quaternius Superhero Female toward a fixed front 3/4 camera during
the auto capture pass, note the free-pack bald base mesh, and check in the
updated Lavapipe PNG sequence.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 12:06:48 +00:00
Cursor Agentand西风逍遥游 5cc2e98313 Replace venom demo mannequin with Quaternius CC0 character.
Load Superhero Female FullBody via model3d, sample albedo in the coverage
shader, and document the asset license under examples/venom-transform.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 12:00:32 +00:00
Cursor Agentand西风逍遥游 92736e1656 Polish venom-transform demo: clean exit and reference captures.
Exit via eve.bootBench so the Vulkan window is not destroyed mid-frame,
and check in the auto-demo PNG sequence as a visual reference.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 08:48:06 +00:00
Cursor Agentand西风逍遥游 2accc68bef Extend combat carriers with body avoid, volleys, and curves
Add SteerAvoidBody (front-cone shield bypass), CurveSway/CurveHelix
motion modifiers, and deterministic Fan/Ring spawnVolley so tracking,
multi-shot spreads, and curved flight compose on the same recipe.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 08:26:36 +00:00
Cursor Agentand西风逍遥游 f08d9cc224 Add venom-transform example for symbiote coverage demo.
Custom mesh shader drives bottom-to-top glossy goo coverage with an
emissive frontier; tendril ribbons and droplets decorate the front.
Auto-capture writes PNG steps under captures/ for headless smoke runs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 08:24:06 +00:00
Cursor Agentand西风逍遥游 c394aacf32 Add composable combat-carrier projectile framework
Introduce CombatCarrierRuntime in the weapon module so ballistics
(motion ops), triggers, and attack impacts assemble as data recipes
instead of hardcoded projectile modes. Keeps ProjectileRuntime for
existing callers and bridges via carrierRecipeFromProjectile.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 08:08:33 +00:00
Cursor Agentand西风逍遥游 b9f3a5c7de fix(example): hoist enqueue duration out of typed call
Eager binding contracts type-check enqueue duration as float. A
ternary of the form kind==\"tank\"?8.0:4.0 leaked that expected type
into the condition, so the string literal failed EVE2002 at load.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:59:02 +00:00
Cursor Agentand西风逍遥游 b35a64d6d4 fix(example): cap Frontier production and delay assault
The AI enqueued a new unit every second while living count lagged
behind the queue, then assaulted as soon as it tied Crown. Limit
in-flight work to factory slots, cap the army at four, and require
a numbers advantage after 15s before assault.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 ad38d51c29 fix(example): stop Commandery RTS opening deathball
choose() is deterministic, so a 0.60 assault score beat capture every
first tick and walked Frontier across the map. Gate assault on force
parity, garrison the east mine during raid, and picket Crown on the
bridge so the opening is an economic contest.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 8e6d55bea5 fix(example): avoid EveScript reserved keyword match
`match` is a token in the Squirrel lexer, so a local of that name
failed to parse at load. Rename the nearest-point selector.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 1a97146aa3 fix(orders): write move payload through setJson
Owned OrderPayload.setNumber rejects a Squirrel float as the instance.
Use the same setJson path as the existing queue script test.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 c4929beb9d fix(example): make Commandery RTS a playable match
Check production/order Results, drive moves through Orders.replace,
stop Frontier from always assaulting, spawn enemy production, add
win/lose, and list the example in the catalog.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 09618f4d01 fix(orders): bind replace on owned script queues
OwnedOrderQueue documented append/replace/interrupt but only append was
exposed, so examples/commandery-rts threw on right-click move. Bind the
remaining CommandQueue mutations on the owned proxy and cover replace
from script.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 768e5aee4c chore(third-party): pin aggregate checkout to origin/main
Use the newest EVEngine/third-party commit (54725d0) as EVENGINE_THIRD_PARTY_PIN.
The tree matches the previous pin; this moves the documented aggregate onto
current main so configure verifies the latest checkout.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-02 10:40:58 +00:00
Cursor Agentand西风逍遥游 c4f691d8de fix(windows): stop MSVC auto-linking PocoFoundationd.lib
PlacementWorld.cpp includes Poco JSON via JsonDocument.h, but the
building module did not declare THIRDPARTY poco, so those TUs compiled
without POCO_NO_AUTOMATIC_LIBS. MSVC then recorded a link of
PocoFoundationd.lib (the DLL debug name) instead of PocoFoundationmdd.lib.

Declare poco on building and apply the no-auto-link flags to every
native module, the host binary, and unit_test so a future JsonDocument
include cannot regress the Windows link.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:49:00 +00:00
Cursor Agentand西风逍遥游 fe1a5d2a47 fix(test): do not delete the Stylize module singleton
Xray.cpp was the only suite that deleted Stylize after create(). The
pointer stays in ModuleManager, so the next case got a dangling
singleton and crashed on the second delete (xray.occludedSilhouette
after xray.shaderAndFlags). Other stylize tests never delete it.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 817524e76e fix(test): isolate tile collect and build xray pipelines off the render pass
TileRenderSystem::collect walks the global ECS, so leftover TileLayer
entities from earlier cases made tilesContributeDepthY (and dual-grid
depth sort) see extra draw items. Hide other layers first, matching
the rest of the map suite.

drawMeshShader always runs inside an open 3D pass, so lazily calling
vkCreateGraphicsPipelines for the xray variant crashed Lavapipe.
Create that pipeline with the shader (and recreate it on MSAA/RP
change) instead, and skip the draw if it is still missing.

Also refresh module counts after rebasing onto grid / buildingfx.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 8a861597b4 docs: record the delivered state and add a trimming guide
Marks the architecture document as implemented, replaces the roadmap section
with what each step actually landed and the measured result, and regenerates
the module inventory against the post-change dependency graph (scene is L1 now,
gameplay modules no longer pull data, and each row names the first profile that
includes it).

Adds docs/usr/TRIMMING.md for the user-facing side: profiles, per-module
switches, how dependency closure and the configure-time conflict errors behave,
has_module() in scripts, what cannot be trimmed and why, and measured savings.
Linked from the user and developer indexes.

Headline numbers after S1-S6: dependency cycles 26 -> 0, layering back-edges
16 -> 3, JSON implementations 6 -> 1, modules using Poco 15 -> 9, boot scripts
2 -> 1, and any module trimmable on desktop where none were before.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 d80df444aa refactor(scene): register link kinds instead of hard-coding them
A scene link keeps an external object in step with the node it hangs off. The
kinds were a closed enum with a switch in TransformSystem, so scene had to
include graphics, physics and audio to do the casts, and no other module could
ever attach to the tree without editing SceneHost.h -- particles, voxel,
spritestack, avatar and weather all had to stay outside it.

Kinds are registered now (scene/SceneLink.h). The module owning the target type
supplies pushWorld / pullWorld / alive, keeps the casts on its own side where
the type is complete, and scene never learns what a Renderable3D is. Dispatch is
a function-pointer table rather than virtual calls, since link sync runs for
every dirty node every frame.

The six typed helpers (linkRenderable2D and friends) stay as conveniences and
now resolve their kind by name, so they return false rather than crash when the
module that registers it was trimmed out. The script API already named kinds
with strings, which is exactly the registry key, so it is unchanged.

Direction is now the right way round: graphics, physics and audio depend on
scene rather than scene on them, and scene drops from L5 to L1. What remains is
scene -> graphics from pickScreenAt / collectFrustumIdsAt, which take a Camera3D
and read its projection; that is recorded in the back-edge whitelist as the next
thing to move.

Each provider lives in a SceneLinks.cpp, sharing the basename so the three come
out of the build together when scene is disabled.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 a97f7f281f feat(boot): bind whatever modules the build contains, and drop the forked root script
load.nut constructed about thirty modules by name, so any build that trimmed
one crashed at bind time. That is the only reason the browser runtime needed a
second root script, load_web.nut, listing the WASM-surviving subset by hand:
two files to keep in step with the link list, and no way to express any other
subset.

The boot script now walks eve.moduleList, generated at configure time from the
same manifest that produces the link list, and guards optional modules with
has_module(). The two frame drivers share one eve_frame(): desktop runs the
while loop at the bottom of load.nut, the browser leaves it to
emscripten_set_main_loop through the new eve.hostDrivesFrames flag rather than
a separate script. load_web.nut is gone.

EVENGINE_WEBGPU_TRIM is gone as well. What was a special case is now the "web"
profile, and the two remaining uses that really meant "is this Emscripten" say
so directly. Third-party groups the WASM aggregate does not build resolve to
nothing there, matching the list it linked before.

graphics now treats font as an optional dependency rather than a hard one:
graphics/Font.cpp is its only user and was already excluded on WASM. Turning
font off excludes that file everywhere, so the rule no longer depends on the
platform.

Verified: full-profile link line still identical to before the manifest work;
web profile resolves to exactly the module set the old REMOVE_ITEM list left;
a 3d-profile binary boots and runs the basic example, reporting avatar and
dialogue absent and the rest present; example smoke suite unchanged at 19/9.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 6074992d9b build: derive the module and third-party link lists from one manifest
Which modules a build contains was spread over four places that had to be kept
in step by hand: the create_module() calls, the EVELIBS list, the per-platform
ThirdParty lists, and load.nut. Nothing tied them together, so the only trimming
that ever worked was the one hard-coded axis (Emscripten), and dropping a module
never dropped its libraries -- ThirdParty was a flat list unrelated to the
module set.

cmake/module_manifest.cmake now declares each module once with its dependencies,
third-party groups, script binding and profiles, and everything else is derived:

  -DEVENGINE_PROFILE=minimal|2d|3d|full|web   presets (default full)
  -DEVENGINE_MODULE_<NAME>=ON|OFF             per-module override, either casing

Dependencies close automatically, so enabling particles pulls in gpgpu,
animation and ik. Disabling something another enabled module needs is a
configure error naming both sides rather than a link failure. OPTIONAL_DEPS
covers 'integrate when present': each enabled module defines EVENGINE_HAS_<NAME>,
which is how scene picks up audio.

cmake/thirdparty_libs.cmake maps logical groups to per-platform link names and
emits them in EVE_TP_ORDER, since GNU ld needs dependents before providers.

The full profile is unchanged by construction: the generated link line is
identical to the previous one, same libraries in the same order and the same
object files. Trimmed builds work -- the 3d profile links and produces a 198 MB
debug binary against 233 MB for full, and -DEVENGINE_MODULE_DATABASE=OFF drops
PocoData and SQLite from the link.

DevTools becomes a declared module rather than a platform #ifdef, so it can be
switched off on desktop too. Its manifest DEPS record that McpServer and
SceneInspect still include scene / physics / procgen / particles / audio / ui
directly, so the resolver tells you to disable devtools before trimming those.

Step S5 of docs/dev/模块编排与裁剪架构.md. Boot scripts still name modules
directly, so a trimmed build links but needs S6 before it runs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 f7aacbc4a9 refactor(event): let modules translate their own platform events
The SDL pump did the translation itself, so it had to know about keyboard,
joystick, touch, window, graphics, audio and ui: eight upward dependencies from
one of the engine's lowest modules, and the source of every remaining
dependency cycle.

Each module now registers an IPlatformEventSink for the events it owns and the
pump only dispatches. Key and text events move to keyboard/sdl, joystick and
game-controller events (including the hotplug device table) to joystick/sdl,
finger events to touch/sdl, resize and the mobile background/foreground surface
watch to window/sdl, the ImGui observer to ui, and Audio::pump to an
end-of-pump hook in audio. The pump keeps only quit and window-close, which are
about the event loop rather than any one module.

Sinks run in priority order -- observer, then surface, then input -- so ImGui
still sees events first and the window is resized before anything reads its
size. The mobile surface teardown keeps using SDL_AddEventWatch rather than the
poll path, since by the time SDL_PollEvent returns the native surface is gone;
the watch is now installed by the window module on its first pump.

Also removes exceptionIfInRenderPass, whose body has been commented out since
it was written and whose only remaining effect was a graphics include.

The engine dependency graph now has zero cycles, down from 26, and the back-edge
whitelist is down to 2 (window -> graphics, window -> image). Layering is also
right way up: event sits at L0 with the input modules above it at L1/L2.

Verified: unit tests for event/input/ui/audio/thread pass, and the example
smoke suite gives the same 19 pass / 9 fail as the pre-change baseline (those 9
fail on main too, from script API drift in the examples themselves).

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 164e8c1b4c refactor(filesystem): dispatch hot reload instead of hard-coding asset kinds
HotReload knew what lived at every watched path: it included graphics to
refresh textures, particles to reload emitter configs and map to reload tile
layers. That made the engine's lowest-level module depend on three of its
highest, and it was the only reason filesystem sat in a dependency cycle.

Each module now registers an eve::caps::IAssetReloader for the assets it owns
and HotReload only routes paths. Behaviour is unchanged: automatic dispatch
still matches by extension, an explicit bind() still targets one kind and
ignores the extension, and the texture reloader runs at kTexture priority so
the GPU upload happens before emitters and tile layers re-bind to it.

The reloadable set now follows the linked module set, so a build without
particles simply has no particle reloader rather than a dangling reference.
Reload kinds also become extensible: a module or plugin can add one without
touching filesystem.

Back-edge whitelist 14 -> 11; the dependency graph is now acyclic apart from
the event pump.

(map.render.tilesContributeDepthY fails when run after the hotreload cases both
before and after this change -- pre-existing test-order state, not from here.)

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 08679654e0 feat(common): add the capability registry, use it for GPU info and main-thread posts
Introduces eve::cap in common/Capability.h: a name-keyed registry where the
consumer owns the interface, the provider registers an implementation, and
neither includes the other. It generalises what common/RenderTrace.h already
does for the render tracer, and supports both a single provider (provide/query)
and many ordered ones (addListener/forEach), keyed by string so a provider
compiled into a plugin lands in the same slot as the host.

Two upward dependencies go away:

  system -> graphics   IGpuInfo. The Vulkan physical-device fields move into
                       graphics/vulkan/GpuInfoProvider.cpp, with a WebGPU
                       counterpart, so System.cpp loses both the graphics
                       include and its EVENGINE_WEBGPU branches.

  thread -> event      IMainThreadPost. postMain and submitPost now enqueue
                       through the capability. The interface makes explicit
                       what was previously only a comment in submitPost: the
                       submitting thread calls prepare() so the worker never
                       reaches the module registry.

Both now report an error when no provider is linked, rather than lazily
creating a module the build may not contain.

Step S3 of docs/dev/模块编排与裁剪架构.md; back-edge whitelist 16 -> 14.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 17c5f33e98 refactor(i18n): use the shared JSON reader
I18n.cpp carried the original copy of the recursive-descent parser that
common/Json.h now hosts. Drop the 228 local lines and flatten the parsed tree
through eve::json::Value instead.

Locale flattening keeps its behaviour: nested keys join with dots, an object
whose members are all plural categories becomes a plural table, and scalars
stringify. Arrays and nulls were already skipped and still are, now stated
directly rather than implied by the if/else chain.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 51015ff831 refactor: share one JSON reader instead of six copies
rpg, inventory and building each carried a byte-identical JsonHelpers.h (only
the namespace differed), card and voxel inlined a fourth and fifth copy, and
i18n hand-rolled a sixth parser because it needs to build without Poco.

Replace all of them with eve::json in common/Json.h. The backend is i18n's
recursive-descent parser, promoted and extended to track integral literals so
getInt() stays exact; picking that over Poco keeps EVCommon dependency-free and
drops Poco from six gameplay modules outright (15 modules -> 9, 136 include
sites -> 108), which is what lets those modules be trimmed independently later.

Accessors keep the lenient, never-throwing behaviour the per-module helpers
had: a missing key, wrong type or bad index yields the fallback. Two places
that relied on Poco throwing to reject incomplete input (housegen instance and
room records) now check required fields explicitly.

test/json.cpp covers the parser directly -- scalars, lenient conversion,
integer exactness and range, nesting, escapes, surrogate pairs, malformed
input and empty containers.

This is step S2 of docs/dev/模块编排与裁剪架构.md.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 3171209909 ci: gate module dependency layering
Runs scripts/module_depgraph.py --check on every push and PR. It fails when a
module gains an #include pointing up the layering, outside the 16 back-edges
already whitelisted in the script. No build or toolchain needed, so it reports
before the platform jobs finish.

This is step S1 of docs/dev/模块编排与裁剪架构.md.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 ced3366ceb docs: reconcile module counts and verify quantitative claims
Count by module directory (51) throughout, and state the directory-vs-script-
class discrepancy up front: filesystem also exposes HotReload, Cmdline lives in
engine/cmdline, and data/tensor bind under different class names.

Also align the layer diagram with the script's computed depths, add math and
audio to the functional-domain table, and correct the figures that were
estimated during drafting (97 soft lookups, 202 cross-module includes,
136 Poco include sites of which 79 are JSON).

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 c4fd641115 docs: add module orchestration and trimming architecture analysis
Analyse how the 53 modules currently collaborate and why none of them can be
trimmed outside the hardcoded WASM axis, then lay out a target architecture and
a six-step route to per-module build options.

Adds scripts/module_depgraph.py, which produces the dependency graph, the
7-layer topological ordering and the cycle list the document cites. Its --check
mode fails on any back-edge outside the 16 known ones, so it doubles as the CI
guardrail for step S1.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 aa364515b3 Add Cursor Cloud dev environment setup notes (AGENTS.md)
Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 03:33:48 +00:00
Cursor Agentand西风逍遥游 bc128ffdf3 feat(graphics): use authored 2x2 grass and leaf sway atlases
Load the four grass and two leaf masks from test/Texture instead of
painting a procedural strip. Pack them into one 2x2-per-variant atlas,
sample frames by instance id, and tint with the existing two-tone green.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-15 07:36:32 +00:00
Cursor Agentand西风逍遥游 e8e11ef2f9 fix(test): make grass sway-frame advance check wrap-safe
0.48s at 0.12s/frame is exactly 4 frames and can land on the same atlas
index after modulo. Use 0.36s (3 frames) so the CHECK is stable.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-15 06:43:13 +00:00
Cursor Agentand西风逍遥游 23e83a4dcb fix(test): avoid unique_ptr in grass GPU REQUIRE checks
zeroerr Expression copies the compared value, which is illegal for
std::unique_ptr. Compare raw pointers instead.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-15 06:37:04 +00:00
Cursor Agentand西风逍遥游 27f7b176cb test(graphics): GPU-render t3ssel8r grass and save a screenshot
Bake alwaysDark into billboard normals so dense and sparse tufts can share
one mesh shader in the 3D pass, then add a windowed GPU test that draws a
field with a shadow-casting occluder and writes grass_field.png.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-15 06:30:51 +00:00
Cursor Agentand西风逍遥游 981a1cb8ea fix(graphics): avoid nested BakeParams default argument
Clang rejects `BakeParams params = {}` on GrassField while the nested
struct still has in-class initializers. Callers pass BakeParams explicitly.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-15 06:17:43 +00:00