chore(prototype): log lane connections at prototype segment nodes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
haylanandClaude Bot committed 2026-10-06 00:14:12 +02:00
1 parent 6ed16fb1ab
commit 1afd1f2e61
2 files changed
+24

No files matched your search

+1
View File
@@ -107,3 +107,4 @@ The human confirmed in game what the log showed: rebuilding the segment under a
- Third run setup: passing lanes at 20 m/s (normal lanes 22.22 m/s), everything else unchanged. Question: does a lower limit keep vehicles in the normal lane and send them to the passing lane only when the normal lane is blocked?
- Third run (20 m/s passing lanes): **no change.** Slow buses still sat in the left passing lane (29849 and 29851: 29/29 samples in lane 3); fast 29251 split 8/11. The engine doesn't pick lanes by speed limit (the slow buses top out at 16.67 < 20 anyway). Observed pattern: a vehicle gets a lane when it enters the stretch and keeps it; it doesn't move over when blocked; passes happen only when fast and slow happen to be in different lanes.
- Lane connections are editable: `BaseNodeConfig.laneConnections` (`LaneConnection{segment0, lane0, segment1, lane1, withRoad, withTram}`, lanes zero-based left-to-right seen from the node) plus `userModifiedLaneConnections`, scriptable via `SimpleStreetProposal.nodeConfigsToAdd`. The game also has a native **crossing tool** ("allows to change the road and tram lanes at crossings", `UI::LaneModifier` in the executable). Next test (option a, by hand): at the stretch's entry junction, connect the normal road only to the right lane, to see whether entry control works and whether a blocked fast bus moves left inside the stretch.
- Fourth run (after the human's crossing-tool edits): **entry control not effective.** Slow buses 29849, 29851 and 29852 still entered prototype stretches (segments 21304, 29012) in the left lane 3 and stayed there (12–14/12–14 samples). 29850, 29848 and the fast 29251 entered in lane 4. No vehicle switched lanes inside a stretch. It's unknown whether or where the edits were saved, so the probe now logs the lane connections (`NODE … userModified= conns=`) at both nodes of every occupied prototype segment.
+23
View File
@@ -33,10 +33,31 @@ local function roadOf(seg : integer) : string
return (tostring(be.roadTemplate):match("([^/]+)%.street_template$")) or tostring(be.roadTemplate)
end
-- lane connections at both nodes of a segment, to check whether crossing-tool edits exist where vehicles enter
local function nodeLog(seg : integer)
local be = api.engine.getComponent(seg, api.type.ComponentType.BASE_EDGE) as Engine.Component.BaseEdge
if be == nil then return end
for _, node in ipairs({ be.node0, be.node1 }) do
local cfg = api.engine.getComponent(node, api.type.ComponentType.BASE_NODE_CONFIG) as Engine.Component.BaseNodeConfig
if cfg == nil then
p(string.format("NODE seg=%d node=%d no BaseNodeConfig (default connections)", seg, node))
else
local conns : {string} = {}
for _, lc in ipairs(cfg.laneConnections) do
if lc.segment0 == seg or lc.segment1 == seg then
table.insert(conns, string.format("%d:%d->%d:%d", lc.segment0, lc.lane0, lc.segment1, lc.lane1))
end
end
p(string.format("NODE seg=%d node=%d userModified=%s conns=%s", seg, node, tostring(cfg.userModifiedLaneConnections), table.concat(conns, " ")))
end
end
end
local function dump(dt : number)
local player = api.engine.util.getPlayer()
local vehicles = api.engine.getEntitiesWithComponent(api.type.ComponentType.TRANSPORT_VEHICLE, { requireOwnedByPlayer = player })
p(string.format("tick=%d dt=%s playerVehicles=%d", ticks, tostring(dt), #vehicles))
local protoSegs : {integer : boolean} = {}
for _, v in ipairs(vehicles) do
local lv = api.engine.getComponent(v, api.type.ComponentType.LAND_VEHICLE) as Engine.Component.LandVehicle
local mp = api.engine.getComponent(v, api.type.ComponentType.MOVE_PATH) as Engine.Component.MovePath
@@ -48,8 +69,10 @@ local function dump(dt : number)
v, edge and roadOf(edge.entity) or "-", edge and edge.entity or -1, tostring(edge and edge.index), tostring(dir), tostring(edge and turnaround(edge)),
mp.dyn.pathPos.edgeIndex, #(mp.path.edges as {any}), mp.dyn.pathPos.pos, mp.dyn.speed, tostring(mp.state),
tostring(tv and tv.state), tostring(tv and tv.line), mp.dyn.timeStanding))
if edge ~= nil and roadOf(edge.entity) == "overtake_proto_b" then protoSegs[edge.entity] = true end
end
end
for seg, _ in pairs(protoSegs) do nodeLog(seg) end
end
local ret : GameScript<table> = {