Skip to content

Add Tutorial Island - #1259

Open
HarleyGilpin wants to merge 4 commits into
GregHib:mainfrom
HarleyGilpin:feat/tutorial-island
Open

Add Tutorial Island#1259
HarleyGilpin wants to merge 4 commits into
GregHib:mainfrom
HarleyGilpin:feat/tutorial-island

Conversation

@HarleyGilpin

@HarleyGilpin HarleyGilpin commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

New accounts start on Tutorial Island and walk the full 68 stage sequence through all nine instructors, ending with the Magic Instructor teleporting them to Lumbridge with the usual starter kit.

Gated behind world.start.tutorial, default on. With it off, nothing changes.

How it works

AccountManager.create seeds a persisted tutorial_stage int, so only accounts created while the setting is on ever enter and existing saves are untouched. Everything else derives from that one value, including which tabs are locked, so relogging mid-tutorial restores the stage, tabs, hint arrow, progress bar and instructions without storing any of them separately.

Stage data is in tutorial_island.tables.toml, one row per stage: title, instruction lines, hint target, tab to flash, component to reveal. advanceTutorial(from) only moves when the player is on exactly from, so a handler can be registered without re-checking the stage.

::tutorial <stage> jumps to any stage for testing.

Interface notes

The instruction box (372) has its own interface type rather than reusing dialogue_box.

The progress bar (371) goes in a new above_chat_box slot, 548:17 / 746:74, the 512x69 bottom anchored strip that pairs with private_chat. Its varp is the segment count plus one, because client script 1437 lights segment n only when varp 406 exceeds n. Component 4 stays hidden; it holds a game screen sized arrow model that otherwise spills out of the strip.

Tab flashing uses varbit 3756. Script 117 guards the range to 1..20 and the value list matches the existing tab varc offset by one.

Testing

./gradlew test passes. Content tests cover spawn routing with the setting on and off, the advance rule, tab unlocking, gated doors and ladders in both directions, burnt bread still finishing the cooking stage, the chef replacing lost ingredients, smelting completing, the instruction box yielding to dialogue, the banker keeping its own conversation, the first run orb click, and the welcome message waiting until the player has landed.

Played through end to end in the client.

The client frames opcode 69 as a fixed 12 bytes, but arrowHint only wrote
the body when a sprite was given. clearHint passes the default sprite of
-1, so clearing an arrow sent a 2 byte packet, and the client consumed the
following 10 bytes as part of it. That desynchronised the stream and
dropped the connection on the next opcode.

Every branch now writes the full body, padding the clear case the client
skips over. Covered for npc, player, tile and both clear forms.
New accounts start on Tutorial Island and walk the 68 stage sequence
through all nine instructors, ending with the Magic Instructor teleporting
them to Lumbridge with the usual starter kit. Gated behind
world.start.tutorial, default on; with it off nothing changes.

The stage counter is a persisted int seeded by AccountManager.create, so
only accounts made while the setting is on ever enter, and existing saves
are untouched. Stage data lives in tutorial_island.tables.toml: text,
hint target, tab to flash and component to reveal, one row per stage.
Locked tabs are derived from the stage rather than stored separately, so
relogging restores everything from the one value.

The instruction box (interface 372) gets its own interface type rather
than reusing dialogue_box. Queued actions only run while Player.dialogue
is null, so an always-on interface in a dialogue slot freezes every
delayed action, smelting included. It also stands aside while an NPC is
talking, since both share the chat box slot on the client. The progress
bar (371) sits in a new above_chat_box slot, and its varp is the segment
count plus one because the client script lights segment n only when the
varp exceeds n.

Fixes found along the way:

- Introduction read world.setup.gear, but the property is
  world.start.gear, so the toggle never did anything. It also granted
  "shrimp", which is not an item id.
- fishing_spot_tutorial_island had an empty net list and caught nothing.
- Two Tutorial Island ladders (3029, 3030) were filed under wizards tower
  with wrong region comments. Object teleports are keyed by tile and
  option alone, so they collided with the correctly named entries.
- The dungeon doorways are named Gate in the cache but swing as doors,
  so they take the existing gate = false override.
- The run orb showed a stale mode when revealed mid-session, since varp
  173 is never sent while it holds its default.
The exit followed world.home, which is the respawn point rather than
where the tutorial drops you. Split it into its own
world.start.tutorial.exit setting so the two can differ.
Upstream fixed the hint arrow packet length independently in GregHib#1236, so
that implementation is taken over mine. The length test is kept, since
upstream has none and it pins every branch to twelve bytes.

Ports the tutorial to the renamed hint API: hint is now markHint, and
clearHint() with no arguments is now clearHints().
@V0lcanic

V0lcanic commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Out of curiosity, are there any plans for Unstable Foundations to be added as well? That tutorial was used up until 647, so it would be more authentic to use.

@Ebp90

Ebp90 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Out of curiosity, are there any plans for Unstable Foundations to be added as well? That tutorial was used up until 647, so it would be more authentic to use.

Greg said to could be a toggle. Personally I have no desire to add it, Tutorial Island does it's job way better.

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.

3 participants