Stop tile recolouring from stacking material clones until tiles vanish - #36
Merged
tomluchowski merged 1 commit intoAug 21, 2026
Conversation
colourizeMaterial() names its colourized copy by appending the colour
suffix to the material it was given, and colourizeEntity() recovers the
original material by cutting the name at a "##" separator. The separator
went away when the Z pre-pass work commented it out of the append (the
outliner and brighter suffixes use "##" too, and a generic find("##")
strip would eat theirs), so every recolour has been cloning the already
colourized material and growing the name by one more suffix:
WoodBridge, WoodBridgeColor_1_, WoodBridgeColor_1_Color_2_, and so on,
one fresh Ogre material per refresh.
A tile that rarely changes colour hides this well enough. Claiming
enemy squares walks right into it: every handover refreshes the tile
and its neighbours, the chain of clones grows by one link each time,
and a few claims in, the cloned material no longer renders - the
square's bridge planks disappear from the map while the server keeps
saying, correctly, that the bridge is there. The claim-a-bridge level
from the review of the square-by-square claiming change shows exactly
that: bridge tiles wink out one by one as the enemy workers dance.
Bring the separator back as "@@", which nothing else uses, so the
recolour replaces the suffix instead of stacking it and never touches
the "##_Outliner"/"##_Brighter" names: colourizeEntity() only ever
serves tile and bridge meshes, and the set of materials stays bounded
at one per (material, seat colour, dig mark, vision) combination.
Verified on ForgottenTreasures2 with enemy workers claiming a bridge:
unfixed, five claimed squares lost their planks within a minute;
fixed, all 27 squares stay drawn through 14 handovers, recoloured to
the claimer's colour, and the material name stays WoodBridge@@Color_2_
instead of growing without bound.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014hrk8PiEUMgjYJnTxLF2PU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the actual cause of the disappearing bridge meshes on the
ForgottenTreasures2level from #34.colourizeMaterial()names its colourized copy by appending the colour suffix to the material it was given, andcolourizeEntity()recovers the original material by cutting the name at a##separator. The separator was commented out of the append in the Z pre-pass work (understandably — the outliner/brighter suffixes use##too, and a genericfind("##")strip would eat theirs), so every recolour since then has been cloning the already colourized material and growing the name by one more suffix:WoodBridge→WoodBridgeColor_1_→WoodBridgeColor_1_Color_2_→ … one fresh Ogre material per refresh.Tiles that rarely change colour hide this well. Bridge claiming walks right into it: every handover refreshes the square and its neighbours, the clone chain grows by a link each time, and a few claims in, the cloned material stops rendering — the planks vanish from the map while the server keeps correctly reporting the bridge (I verified the packets:
hasBridge=1,WoodBridge.mesh,waterGroundall the way through). That's why #34 makes it visible: square-by-square claiming multiplies the recolour events. The bug itself is independent of #34 and was quietly leaking a material clone on every tile recolour.The fix brings the separator back as
@@, which nothing else uses: recolouring now replaces the suffix instead of stacking it, thefind("##_Outliner")/find("##_Brighter")checks can never match a colourized name, and the set of materials stays bounded at one per (material, seat colour, dig mark, vision) combination.colourizeEntity()is only ever called for tile meshes and bridge meshes, so nothing else changes behaviour.Verified on your level with seat 2's workers claiming WoodenBridge_9 in skirmish:
WoodBridge@@Color_2_instead of growing without bound.Loading the level in the editor and in skirmish before any claims looks identical before/after.
🤖 Generated with Claude Code
https://claude.ai/code/session_014hrk8PiEUMgjYJnTxLF2PU