Skip to content

FIX: prevent shorter bridge construction in tutorial chapter 3 - #46

Open
Dkijas wants to merge 1 commit into
simutrans:mainfrom
Dkijas:fix/tutorial-chapter3-bridge-deck-permission
Open

FIX: prevent shorter bridge construction in tutorial chapter 3#46
Dkijas wants to merge 1 commit into
simutrans:mainfrom
Dkijas:fix/tutorial-chapter3-bridge-deck-permission

Conversation

@Dkijas

@Dkijas Dkijas commented Sep 3, 2026

Copy link
Copy Markdown

Fixes the long-standing problem in chapter 3 discussed in
https://forum.simutrans.com/index.php/topic,23838.0.html — the player can
build a rail bridge shorter than the one the chapter asks for.

Why it happens

The chapter sets up two rules for the bridge:

rules.forbid_way_tool_rect(player_all, tool_build_bridge, wt_rail, 0, cube[2], cube[3], get_message(5) )
rules.allow_way_tool_cube (player_all, tool_build_bridge, wt_rail, 0, cube[0], cube[1])

cube[0] is at the bridge deck height (b.z + 1) but cube[1] is at the
ground height (a.z), so the permission covers every level from the ground
up to the deck, across the whole box between the two bridge heads.

scenario_t::is_work_allowed_here consults the allow list before the
forbid list, so as soon as that cube matches, the forbid rect is never
examined. The consequence is that the intermediate tiles are permitted at
ground level too, and the player can simply end a shorter bridge there.

The change

Collapse that existing permission to the deck plane:

-rules.allow_way_tool_cube(player_all, tool_build_bridge, wt_rail, 0, cube[0], cube[1])
+rules.allow_way_tool_cube(player_all, tool_build_bridge, wt_rail, 0, cube[0], coord3d(cube[1].x, cube[1].y, cube[0].z))

The bridge deck stays buildable, while the intermediate tiles at ground level
remain covered by the chapter's own forbid rect, so only the intended bridge is
possible. The two bridge heads need no extra permission: the forbid rect covers
only the interior strip, so they were never forbidden.

clear_way_tool_cube gets the identical geometry — if the two do not match, the
rule is not removed once the bridge is finished.

select_cube() is unchanged, no rule is added, and no other chapter is touched.

Measured

Simutrans trunk r12244, pak64, tutorial64.sve from this repository, using the
scenario rule API directly at the chapter's own coordinates
(a = 106,158,-1 b = 103,158,-1, deck z = 0):

bridge no rules before after
intended a→b SUCCESS SUCCESS SUCCESS
intended b→a SUCCESS
intended, heads already carrying rail SUCCESS
shorter bridge a→(104,158) SUCCESS SUCCESS REFUSED

The "no rules" column matters: on this terrain a→(104,158) is the only
shorter bridge that is geometrically possible at all, so it is the only case
that can discriminate. The other short directions are refused by the terrain
even with no scenario rules at all.

On refusal: the world is unchanged and the money delta is 0. The scenario still
loads with no script errors.

Not addressed here

pak128 has a separate, pre-existing problem that this PR does not cause and
does not fix: class_basic_coords_p128.nut declares the bridge end as
b = coord3d(100,158,-1), but the real ground there is z = 0 and the real
deck is z = 1. The permission band therefore ends one level below the deck,
and on pak128 the intended bridge is already refused by the current rules,
before and after this change. That needs a coordinate fix rather than a rule
change, so I left it out of this PR deliberately.

pak64.german was not tested — the pakset is not installed on the machine used
for these measurements. The scenario code is single-source, and its coordinates
are identical to pak64's, but its savegame is a different map, so I am not
claiming it as verified.

🤖 Generated with Claude Code

The permission for the bridge span covered every height from the ground
level up to the bridge deck. Scenario allow rules are consulted before the
forbid rules, so that single permission also covered the tiles between the
two bridge heads at ground level, and the player could end a shorter bridge
there instead of building the one the chapter asks for.

Restrict the permission to the deck plane. The deck stays buildable while
the intermediate ground tiles remain forbidden, so only the intended bridge
is possible. clear_way_tool_cube gets the identical geometry, otherwise the
rule would not be removed once the bridge is finished.

Measured on pak64 with tutorial64.sve: the intended bridge still builds in
both directions, and also when the bridge heads already carry rail; the
shorter bridge is refused, with no change to the world and no cost.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant