Wyson mole part exchange, giant mole burrow crash and light source fixes - #1182
Merged
Merged
Conversation
Complete Wyson's conversation tree from the wiki transcript: the unusual flower bed branch, Giant Mole combat advice, the 25gp bulk woad leaf haggle, and the mole part exchange that replaces the old TODO. Mole claws and skins trade for cheap seed nests, noses for seed nests, matching the item split in game. Completing the Falador hard tasks adds a white lily seed per skin. Parts are swapped one at a time in their own transaction so a full inventory stops the trade rather than rolling all of it back, since a skin plus seed needs two slots for the one it frees. Nests are given unnoted because no noted bird nest exists in the cache. The old five and ten coin refusals looped back to the price menu; the transcript ends the conversation there, and the menu is already at the five option cap. Also fix two bugs found while verifying this: Giant mole burrows threw a NullPointerException on Area.random returning null, which it does after 100 failed attempts to fit a size 3 npc. The throw landed between the burrow down and burrow up animations, so a failed relocation left the mole rendered underground permanently. It now resurfaces in place and logs a warning. Falador varbit ids for i_heard_you_like_mudskips and these_arent_the_coins_youre_looking_for were swapped. Task structs carry a task index whose 115..151 range maps contiguously onto varbits 5691..5727 ordered by index; every other entry matches, those two were an exact swap. The hard task check for the seed bonus read the wrong bit as a result. Rename falador_easy.varbits.toml to falador_tasks.varbits.toml since it holds all four difficulty sets, matching the other areas.
Light.extinguish looked up the replacement item with row.item(".unlit").
RowDefinition.item already prepends the row id, so the path built was
extinguish.<item>..unlit. Tables.get splits on "." and destructures the
first three parts, leaving column empty, which failed as
"Column not found". Line 29 already used the bare form for "type", and
light_source.tables.toml declares the column as unlit.
This threw whenever a player carrying a lit candle or torch had their
light snuffed out, so no light source could ever be extinguished.
Add a regression test covering candles and torches swapping to their
unlit form, and lanterns deliberately staying lit.
handleDirtOnScreen opened the overlay for every nearby player before queueing the timer that closes it again, so a throw part way through the open loop skipped the queue entirely and left everyone in range staring at dirt until they logged out. Register the timer first, and guard each player individually so one failure costs that player their dirt effect rather than everyone else's. Guard the close loop too. World queue blocks are run unguarded inside a game loop stage, and GameLoop catches outside its while loop, so a throw while closing would have ended the game loop instead of just the overlay. Add a test covering nearby players being blinded, their lit light sources being snuffed out, and the overlay clearing itself afterwards.
GregHib
reviewed
Aug 18, 2026
GregHib
approved these changes
Aug 18, 2026
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.
Three related changes that came out of working on the Giant Mole and Wyson.
Wyson the gardener
Completes his conversation tree from the wiki transcript, replacing the
// TODO add selling mole parts:Mole claws and skins trade for cheap seed nests, noses for seed nests, matching the item split in game. Completing the Falador hard tasks adds a white lily seed per skin.
Parts are swapped one at a time in their own transaction, so a full backpack stops the trade rather than rolling all of it back, a skin plus its seed needs two slots for the one it frees.
Two deliberate deviations from the wiki:
noteId = -1on every nest), so there is nothing to hand out.Giant Mole burrow crash
gianMoleSpawns.random(mole)was dereferenced with!!.Area.randomgives up after 100 attempts to fit a size 3 npc and returns null, so this threw, and it threw between the burrow down and burrow up animations, leaving the mole rendered underground permanently. It now surfaces in place and logs a warning.Falador task varbits
i_heard_you_like_mudskipsandthese_arent_the_coins_youre_looking_forhad their varbit ids swapped, so the hard task check read the wrong bit.Task structs carry a task index whose 115..151 range maps contiguously onto varbits 5691..5727 ordered by index. Every other entry in the file matches that mapping; those two were an exact swap of each other.
Also renames
falador_easy.varbits.tomltofalador_tasks.varbits.toml, since it holds all four difficulty sets and every other area already uses the_tasksname.Extinguishing light sources
Light.extinguishbuilt its column path asrow.item(".unlit").RowDefinition.itemalready prepends the row id, so the path becameextinguish.<item>..unlit;Tables.getsplits on.and destructures the first three parts, leaving the column empty and failing withColumn not found.This threw for any lit candle or torch being snuffed out, so no light source could be extinguished anywhere in the game. Caught in production via the Giant Mole's dirt attack.
Dirt-on-screen resilience
That crash surfaced a second problem in
handleDirtOnScreen. The overlay was opened for every nearby player before the timer that closes it was queued, so a throw part way through the open loop skipped the queue entirely and left everyone in range stuck behind a dirt screen until they logged out. The timer is now registered first, and each player is guarded individually.The close loop is guarded too. World queue blocks run unguarded inside a game loop stage, and
GameLoopcatches outside itswhileloop, so a throw while closing would have ended the game loop rather than just one overlay.Testing
./gradlew testpasses. New coverage:FiremakingTest- candles and torches swap to their unlit form, lanterns stay litGiantMoleTest-nearby players are blinded, their lit light sources are snuffed, and the overlay clears itself