Skip to content

Wyson mole part exchange, giant mole burrow crash and light source fixes - #1182

Merged
GregHib merged 4 commits into
GregHib:mainfrom
HarleyGilpin:feat/giant-mole-enhancements
Aug 18, 2026
Merged

Wyson mole part exchange, giant mole burrow crash and light source fixes#1182
GregHib merged 4 commits into
GregHib:mainfrom
HarleyGilpin:feat/giant-mole-enhancements

Conversation

@HarleyGilpin

@HarleyGilpin HarleyGilpin commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

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:

  • The unusual flower bed branch, including the "Why are you even collecting mole claws?" detour
  • Giant Mole combat advice
  • "Tell me your price." , bulk woad leaves at 25gp each
  • The mole part exchange

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:

  • Nests are given unnoted. No noted bird nest exists in the cache (noteId = -1 on every nest), so there is nothing to hand out.
  • The 5 and 10 coin refusals end the conversation instead of looping back to the price menu. That matches the transcript, and the menu is already at the five option cap so "changed my mind" has nowhere to go.

Giant Mole burrow crash

gianMoleSpawns.random(mole) was dereferenced with !!. Area.random gives 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_mudskips and these_arent_the_coins_youre_looking_for had 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.toml to falador_tasks.varbits.toml, since it holds all four difficulty sets and every other area already uses the _tasks name.

Extinguishing light sources

Light.extinguish built its column path as row.item(".unlit"). RowDefinition.item already prepends the row id, so the path became extinguish.<item>..unlit; Tables.get splits on . and destructures the first three parts, leaving the column empty and failing with Column 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 GameLoop catches outside its while loop, so a throw while closing would have ended the game loop rather than just one overlay.

Testing

./gradlew test passes. New coverage:

  • FiremakingTest - candles and torches swap to their unlit form, lanterns stay lit
  • GiantMoleTest -nearby players are blinded, their lit light sources are snuffed, and the overlay clears itself

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.
Comment thread game/src/main/kotlin/content/area/asgarnia/falador/WysonTheGardener.kt Outdated
@GregHib
GregHib merged commit 07f678c into GregHib:main Aug 18, 2026
2 checks passed
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