Skip to content

Send creatures another way when the bridge they were using is sold - #28

Open
Upabjojr wants to merge 2 commits into
tomluchowski:shaders-improvementfrom
Upabjojr:split/bridge-sold
Open

Send creatures another way when the bridge they were using is sold#28
Upabjojr wants to merge 2 commits into
tomluchowski:shaders-improvementfrom
Upabjojr:split/bridge-sold

Conversation

@Upabjojr

@Upabjojr Upabjojr commented Aug 1, 2026

Copy link
Copy Markdown

A creature walking towards (or standing on) a bridge when it is sold kept its computed path, stepped onto the uncovered lava/water tile, and stopped there permanently, because its move speed there is zero. Now a creature walking towards the missing bridge is stopped and re-routed, and a creature left standing in lava or water it cannot live in dies — as discussed in the review, it does not get teleported ashore. Two commits.


Split out of #16 so each topic can be reviewed on its own.

🤖 Generated with Claude Code

A creature walking towards a bridge when it is sold walks to the last tile
before the water or the lava and stops there for the rest of the game. One
standing on the bridge when it goes stops just as permanently, in the middle of
the lava.

Nothing tells a creature that the ground it planned to walk on has gone. It
keeps the path it computed, steps onto the tile the bridge used to cover, and
Creature::getMoveSpeed() returns the creature's lava speed there, which is zero
for everything that does not live in it. The distance it may move in a frame is
that speed times the frame time, so it stops where it is, its walk queue never
empties, CreatureActionWalkToTile never completes, and the action that sent it
walking never gets to choose again. It is a statue that can still be attacked.

So look, once a turn, at whether the ground still holds:

checkWalkPathIsStillValid() walks the remaining path and, if any tile of it has
stopped being walkable, stops the creature and looks for another way to the same
destination. If there is none, it stops there and the action that started the
walk decides what to do instead, exactly as it would have done had the creature
arrived. A tile that refuses passage because of the building on it, a closed
door or a prison, does not count: those are meant to stop the creature, and it
was already walking towards one knowing what it would find.

checkStandsOnWalkableTile() puts a creature that is standing where it cannot
stand back on the closest tile where it can. That is the only way out for it,
since the null speed applies to its own movement as well. It only fires for
water and lava with nothing built on them, which is exactly what a bridge
leaves behind, rather than for anything that happens to give a null speed.

Also stop the client dereferencing the entity named by an entityTeleported
message without checking it knows it, since teleports are no longer limited to
the arena gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit ac9f193)
Comment thread source/entities/Creature.cpp Outdated
}

return nullptr;
}

@tomluchowski tomluchowski Aug 2, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code path ALWAYS enters the maxRadious loop, that is it's always tested against : ```

if(tileClosest != nullptr)
            return tileClosest;

and it always would encounter
return nullptr;when exiting from the loop and not triggering the prev IF.

IN other words : isn't it simpler to just write :
return tileClosest;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, but I don't see any actual difference. I guess this would only occur if there are no tiles in the map?

But... is it the desired behaviour? Should the create actually be teleported if the bridge disappears?

@tomluchowski tomluchowski Aug 3, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No the outcome would be the same, I vote only for simpler code. As whether it is desired behaviour : maybe.
For sure we have to do something with that, no one wants to stall creature in the middle of the lava. On the other hand : I can imagine doing some kind of landing operation on a coast to which normally player wouldn't have access....

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe the creature should simply disappear... or start losing hit points?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah .... throwing and creatures into lava, which aren't immune to it should kill them ........

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b49bca3: the creature now dies where it stands — it takes its remaining hit points as damage and the normal death sequence handles the rest. A creature that can live in the liquid is never touched by this check, since it can still go through the tile. This also deletes findClosestWalkableTile() (ring search and all — which settles the simplification question above by removal) and teleportToTile(), which no longer had a caller. No more free landings on unreachable coasts.

The first version of this branch teleported a creature left standing in
lava or water to the closest tile it could stand on. Review found that
wrong: it lands the creature on a coast its keeper may have no legitimate
access to, and a creature dropped into lava it is not immune to should
simply die. So it dies, by taking its own hit points in damage, and the
usual death sequence takes it from there; one that can live in the liquid
was never picked up by this check in the first place, since it can still
go through the tile.

That removes findClosestWalkableTile(), and with it the ring search whose
final return the review also asked about, and teleportToTile(), which no
longer has a caller. The client-side check on entityTeleported stays: the
message is still sent for arena teleports, and a client should never
dereference an entity it does not know either way.

Requested in
tomluchowski#28 (comment)

Co-Authored-By: Claude Fable 5 <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.

2 participants