Skip to content

Feature/zulrah slayer - #525

Open
dylanreniers wants to merge 18 commits into
chsami:developmentfrom
dylanreniers:feature/zulrah-slayer
Open

Feature/zulrah slayer#525
dylanreniers wants to merge 18 commits into
chsami:developmentfrom
dylanreniers:feature/zulrah-slayer

Conversation

@dylanreniers

@dylanreniers dylanreniers commented Aug 11, 2026

Copy link
Copy Markdown

Zulrah Slayer — Test Evidence

This document separates the reusable framework guarantees (covered by fast JUnit tests that run in
./gradlew test) from the Zulrah-specific behavior (unit-tested where pure; otherwise verified by a
live run and recorded in the matrix below).

1. Reusable framework guarantees (automated)

Tests live under src/test/java/net/runelite/client/plugins/microbot/actions/.

Guarantee Test
Actions run in ascending order() regardless of input order ActionRunnerTest.runsActionsInAscendingOrderRegardlessOfInputOrder
A later action can read an earlier action's result from the same ScriptState ActionRunnerTest.laterActionsCanReadEarlierResultsFromTheSameState
needsExecution == false records a skipped action without calling execute ActionRunnerTest.needsExecutionFalseRecordsASkipWithoutCallingExecute
An exception in needsExecution or execute does not prevent later actions running ActionRunnerTest.oneThrowingActionDoesNotAbortTheRestOfTheTick
Duplicate action keys are rejected deterministically (fail fast) ActionRunnerTest.duplicateActionKeysAreRejectedDeterministically
Discovery finds only concrete top-level implementations, built through Guice ActionRegistryTest (discoversEveryConcreteActionInThePackage, skipsTheInterfaceAndAbstractBases, buildsInstancesThroughGuice)
Discovery returns an empty list (no throw) when a package has no implementations ActionRegistryTest.returnsEmptyListWhenThePackageHasNoImplementations
gameTick() dispatches to the executor (off the client thread), never inline ActionScriptTickTest.tickBodyIsDispatchedToTheExecutorAndNotRunInline
Repeated gameTick() cannot overlap while a slow action is running ActionScriptTickTest.dropsAnOverlappingTickAndResumesAfterTheInFlightOneCompletes
Logged-out / uninitialised ticks skip cleanly and release the guard ActionScriptTickTest.loggedOutTickSkipsCleanlyAndReleasesTheGuard, uninitialisedTickDoesNotThrowAndReleasesTheGuard
A rejected submission (shut-down executor) does not leave the guard stuck ActionScriptTickTest.rejectedSubmissionDoesNotLeaveTheGuardPermanentlyStuck
The built plugin JAR bundles the shared action classes exactly once, excludes the marker file PluginJarPackagingTest.pluginJarBundlesTheSharedActionsFrameworkAndNotTheMarkerFile
Every Zulrah action class in the JAR loads and implements the shared interface (and is instantiable) PluginJarPackagingTest.everyZulrahActionClassInTheJarLoadsAndImplementsTheSharedActionInterface

The packaging tests self-skip on a bare ./gradlew test; build the artifact first to exercise them:
./gradlew build -PpluginList=ZulrahSlayerPlugin then ./gradlew test.

Known gap: the "a class cannot load during discovery" path is guarded in ActionRegistry
(info.load() is wrapped in try/catch(Throwable) → log & skip) but is not unit-tested, because a
deliberately-unloadable class cannot be produced from normally compiled sources. Verified by inspection.

Bugs found and fixed while writing these tests

  • ScriptState.result() threw NullPointerException for any action that returned null (or whose
    execute threw) — findFirst() cannot wrap a null. Reordered to findFirst().map(...).
  • ActionScript.gameTick() left the re-entrancy guard permanently stuck if submit() was rejected
    (the resetting finally lived inside the never-run task). The guard is now released on submit failure.
  • ActionRunner did not enforce the documented uniqueness of Action.key(); duplicates now fail fast.

2. Zulrah-specific pure logic (automated)

Tests under src/test/java/net/runelite/client/plugins/microbot/zulrahslayer/.

Behavior Test
Rotation identification narrows to the correct rotation from its form sequence (all of A–D) rotationutils/RotationTypeTest
matching returns empty for an invalid stage or unrecognised NPC (no wrong guess) RotationTypeTest.matchingReturnsEmptyForInvalidStageOrUnknownNpc
Attack style: only the tanzanite MAGIC form is ranged; Jad is always magic actions/ZulrahDecisionLogicTest.onlyTheTanzaniteMagicFormIsAttackedWithRanged
Venom damage progression + anti-venom drink threshold (damage > 10) ZulrahDecisionLogicTest (venomDamage…, antiVenomThresholdBoundary…)
Eating threshold (≤ 50% health) actions/EatActionTest

3. Zulrah-specific live behavior (manual run)

Pure logic above is automated; the following require a live client at Zulrah with both inventory setups
configured. Fill the Observed column from a run (client version, date).

# Scenario Starting state / loadout Expected result Observed
1 Start point: Banking At GE/house, mage+range setups configured, bank stocked Full trip: house → altar → GE restock → travel → board boat → fight begins
2 Start point: Travel to Zulrah In POH, supplies already in inventory Skips banking; fairy-ring → stone → dock → boat → fight begins
3 Start point: Beginning of fight Already on boat, continued No prep; opening attack fires exactly once, then repositions
4 Setups not configured One/both inventory-setup configs null startUp shows a message and stops the plugin (no crash)
5 Bank missing supplies Bank lacks a setup item Restock logs "could not top up…", prep aborts, bot idles visibly
6 Multi-kill loop Restock-between-kills ON ≥3 consecutive kills: fight → loot → restock → travel → re-enter, no drift
7 Rotation A–D identification Each rotation Locks to the correct rotation before the Jad stage; stand tiles match
8 Jad phase Reach the Jad phase Prayer flips each Jad attack; correct final phases
9 Melee reposition Melee phase Alternates NE dodge tiles on tail swings; no melee damage taken
10 Prayer/gear switch Phase transitions across styles Correct overhead + mage/range gear each phase
11 Eating threshold Take damage to ≤ 50% Eats at/below 50%; survives a magic-phase ranged streak
12 Anti-venom threshold Venom ramps up Drinks anti-venom once the projected hit exceeds 10
13 Full-inventory loot Inventory full on kill Loot handled gracefully (no soft-lock)
14 Teleport/boat/instance-entry failure Force a missing object/step Step times out, prep aborts, bot idles (recoverable)
15 Death / recovery Die to Zulrah Prayers off on death; state reset; no runaway actions
16 Logout mid-run Log out during a fight gameTick skips cleanly; resumes on login
17 Stop plugin mid-action Disable the plugin mid-walk/attack shutDown resets context and stops the script cleanly

chsami and others added 15 commits July 2, 2026 13:35
Bug In table potion
Add an "Auto Pay Tree Removal" toggle (Dialogue section, default on) that
selects 'Yes.' on the "Pay X Coins to have your tree chopped down?" prompt,
so farm runs don't wait on a manual click. Matched on the question title
(widget 219,1 index 0, verified live via the agent server) rather than the
option text, so it can never fire on unrelated Yes/No dialogues; the coin
amount is intentionally not matched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…emoval

QoL: auto-confirm the farming tree-removal payment dialogue
…-navigation

Fix mahogany upstairs navigation
… of random. (chsami#520)

* Update StrugglingSaplingEvent.java

Updated Ingredient Collection to use closest first instead of Random Ingredient. Behavior is more player-like.

* Update AutoWoodcuttingPlugin.java

Updated Plugin version to 1.8.4

chsami commented Aug 13, 2026

Copy link
Copy Markdown
Owner

The new plugin JAR compiles against Microbot 2.6.19, but I’m holding the merge because the PR still needs substantial contributor work:

  1. New Hub features should target development, not main; please rebase onto current development and retarget the PR.
  2. The PR has no description, automated tests, or runtime validation. Please document supported cycle start points, required inventory setups/gear, known limitations, and the exact fight/travel/bank/loot scenarios tested in game.
  3. This PR combines the Zulrah plugin with repository-wide infrastructure: gradle/plugin-utils.gradle, eight shared actions framework classes, and a new shared-source packaging mechanism. Please separate that framework/build-system work into its own PR, or add focused tests for action discovery, ordering, exception isolation, overlapping-tick prevention, and final JAR packaging.
  4. Please remove the unrelated CLAUDE.md change from the feature PR and add normal plugin documentation under the Zulrah resource docs path.

After those changes, the plugin itself can be reviewed without accepting untested shared build/runtime infrastructure at the same time.

@dylanreniers
dylanreniers changed the base branch from main to development August 13, 2026 17:02
@dylanreniers

Copy link
Copy Markdown
Author

I understand your points and I wanted to address these with you on Discord before I created this PR, but that ultimately didn't happen (I sent you a friend request).

I'll make the modification for the first 2 points, though I'm not sure what is fully expected in terms of tests. I'm happy to add tests as I see fit, but perhaps it might be best for you to give some guidance on this.

chsami commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Concrete test guidance:

For the shared actions framework (ideally in its own PR), add small JUnit fakes covering:

  • ActionRunner executes in ascending order, and later actions can read earlier results from the same ScriptState.
  • needsExecution == false records a skipped action without calling execute; exceptions from either method do not prevent later actions from running.
  • duplicate action keys are rejected or otherwise handled deterministically (the interface currently calls them unique but does not enforce that).
  • ActionRegistry discovers only concrete top-level implementations, constructs them through Guice, and behaves predictably when a class cannot load or no implementations exist.
  • repeated ActionScript.gameTick() calls cannot overlap while a slow action is running; logout/uninitialised state skips cleanly; execution happens off the client thread; shutdown/rejected submission cannot leave the guard permanently stuck.
  • the built plugin JAR actually contains the shared action classes exactly once and can instantiate the Zulrah action set.

For the Zulrah plugin, unit-test the pure rotation/phase and action-decision logic where possible, then report live evidence for:

  • every supported CycleStartPoint, including missing/invalid gear or supplies;
  • a complete bank/travel/enter/fight/loot/re-enter loop across multiple kills, not only one fight;
  • rotation changes (including Jad), melee repositioning, prayer/gear switches, eating/prayer/anti-venom thresholds, and a full-inventory loot case;
  • teleport/boat/instance-entry failure recovery, death/recovery, logout, and stopping the plugin mid-action.

A short table in the PR description with scenario, starting state/loadout, expected result, and observed result is enough for the live portion. The key is separating reusable framework guarantees from the Zulrah-specific behavior.

@chsami chsami left a comment

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 added JUnit and packaging coverage materially improves the shared action framework, and the base now targets development. The PR is still not ready to merge: every Observed cell in the 17-scenario live matrix is blank, and the branch still has multiple merge bases plus unrelated changes to CLAUDE.md, Mahogany Homes, Mixology, QoL, and Forestry. Please rebuild the branch cleanly on current development so the diff contains only the action framework and Zulrah feature, then fill the live matrix for the supported cycle, multi-kill, rotation/Jad, death/logout, and stop-mid-action paths.

@chsami

chsami commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Requested changes summary: please rebuild this branch cleanly on current development so the diff contains only the shared action framework and Zulrah feature. It still has multiple merge bases and unrelated CLAUDE.md, Mahogany Homes, Mixology, QoL, and Forestry changes. The automated coverage is much improved, but the 17-scenario live matrix still needs observed results for the supported cycle, multi-kill, rotation/Jad, recovery, logout, and stop-mid-action paths.

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.

6 participants