Skip to content

Fix skill level task handling, add XP task handling, and improve data synchronization#65

Open
Darkforge317 wants to merge 6 commits into
Toofifty:masterfrom
Darkforge317:fix-skill-update-listeners
Open

Fix skill level task handling, add XP task handling, and improve data synchronization#65
Darkforge317 wants to merge 6 commits into
Toofifty:masterfrom
Darkforge317:fix-skill-update-listeners

Conversation

@Darkforge317

@Darkforge317 Darkforge317 commented Jun 23, 2026

Copy link
Copy Markdown

Added real-time tracking for Skill XP tasks and fixed several issues related to task synchronization, validation, serialization, and startup initialization.

Key improvements include:

  • Skill XP tasks now update from live XP gains and re-evaluate correctly after login.
  • Skill Level task updates now consistently trigger notifications, UI updates, and persistence.
  • Fixed an NPE that could occur when loading large prerequisite chains such as Heroes' Quest.
  • Added safeguards against malformed imports and missing serialized data.
  • Fixed task creation ordering that could result in incorrect progress values being saved.

Technical Changes

1. Skill Task Synchronization and XP Event Tracking

Skill level changes were being calculated correctly but did not consistently trigger notifications, UI updates, or persistence. In addition, SkillXpTask instances were not responding to live XP gain events and were not re-evaluated during login.

  • Refactored onStatChanged into a structure that supports multiple skill-based task types.
  • Added event-driven updates for both SkillLevelTask and SkillXpTask.
  • Trigger UI refreshes, notifications, and persistence when task progress changes.
  • Added a save optimization flag to reduce unnecessary disk writes.
  • Renamed xp to targetSkillXp for consistency with other skill milestone models.

2. Login Synchronization

Task state was not reliably synchronized when a player logged into the game, which could leave goals displaying outdated progress until another qualifying event occurred.

Implemented a login initialization pass within onGameStateChanged.
The startup routine waits until skill data has been populated (client.getRealSkillLevel(Skill.ATTACK) > 0) before performing validation. Once player data is available, it executes:

  • refreshQuestTasks()
  • refreshSkillLevelTasks()
  • refreshSkillXpTasks()

The UI is then refreshed to reflect the updated task state.

3. Thread-Safe Prerequisite Validation (refreshAllTasks)

Complex prerequisite validation could occur on the Swing event thread, leading to synchronization issues and inconsistent task state updates.

Introduced refreshAllTasks(Runnable onCompleteUIHandler).

  • Validation now executes entirely on RuneLite's clientThread.
  • UI updates are deferred until validation completes.
  • Heavy prerequisite traversal is kept off the Swing thread.

4. Defensive Handling for Missing Data

Malformed imports or partially initialized task objects could trigger NPEs and leave the UI unable to render.

  • Added a fallback in Task.getStatus() that returns Status.NOT_STARTED when status data is missing.
  • Added lazy initialization in Goal.getTasks() to ensure missing task collections are replaced with an empty ReorderableList<>.

5. Task Creation and Serialization Ordering

The task insertion handler fired a blocking, synchronous goalManager.save() straight on the main UI thread before player statistics were evaluated in memory resulting in incorrect values such as current_skill_xp = 0 being written to disk. This caused fresh tasks to write uninitialized primitive states directly to the disk file cache.

Restructured the loop to invoke taskUpdateService.update(task) on the game thread prior to serialization. This forces the task to immediately query current live client milestones, caching the real statistics in RAM before goalManager.save() writes the payload to disk. Moved both the file save handle and notifyTask off the UI thread entirely to insulate the Swing engine from blocking disk I/O.


Verification

  • Malformed JSON Import — Importing data with a missing items field no longer causes UI failures. Empty goals load correctly.
  • Quest Prerequisites — Large prerequisite chains such as Heroes' Quest validate correctly and update task states immediately when applicable.
  • Live XP Tracking — XP milestones update immediately from gameplay events, refresh the sidebar, trigger notifications, and persist the correct XP values.

…ization on login/creation

Refactored `level` to `targetSkillLevel` across all task definitions and quest requirement mappings for code clarity, preventing confusion now that a distinct `currentSkillLevel` tracking field has been introduced.

Implemented `currentSkillLevel` progression cache inside `SkillLevelTask` and `TaskUpdateService` to ensure active player stats are stored locally before cross-thread evaluations occur.

Added a non-blocking frame loop to `onGameStateChanged` to resolve uninitialized player profile data on login, preventing accidental level-0 task completions caused by server packet lag.

Wrapped the UI thread's `onTaskAdded` handler in a `clientThread` loop to bypass service thread guards safely, ensuring freshly created goals check active player stats immediately instead of remaining stuck as unverified.
Prerequisites were never added to the Goal Manager and therefore would never get their statuses checked when running update(). This fixes that.

Also, importing a JSON file that was malformed would cause a null reference pointer exception. Also fixed.

# CHANGES:
- Implemented `refreshAllTasks` gatekeeper to safely process batch updates (like pre-reqs) on the game thread.
- Added an override for `Task.getStatus()` to intercept uninitialized constructor states and safely default to `NOT_STARTED`.
- Added an override for `Goal.getTasks()` with a lazy-initialization pattern to prevent null pointer array crashes during malformed JSON imports.
Skill level tasks updated behind the scenes but never reflected their new status on the UI or saved to the disk. This fixes that, making sure player actions instantly repaint the sidebar and notify the chat.

Also, added the necessary layout infrastructure so we can easily add experience tracking next without making a big mess of the method.

# CHANGES:
- Tied level updates inside `onStatChanged` directly to real-time `uiStatusManager` refreshes and player chat notifications.
- Replaced individual, spammy disk writes with a single batch-save check at the very end of the method to protect processing power.
- Implemented an extensible if/else loop structure to act as clean scaffolding for upcoming XP task processing.
Skill XP tasks were completely ignored by the live skill training event hook (onStatChanged) and failed to catch up or initialize upon logging into the game. This fixes that, ensuring player experience gains are tracked smoothly in real-time.

Also, added a dedicated experience verification sweep to the startup routine so milestones achieved on other devices synchronize instantly on login.

# CHANGES:
- Integrated a new `SkillXpTask` collection processing loop directly inside the `onStatChanged` event listener.
- Appended `refreshSkillXpTasks()` to the `onGameStateChanged` login airlock loop to force a silent experience verification pass on startup.
- Refactored `xp` to `targetSkillXp` within `SkillXpTask.java` to align perfectly with the skill level property layout naming conventions.
…ve bugs

Skill XP tasks were completely ignored by the live training event hook and failed to initialize on creation or login. This fixes that, ensuring progress metrics are tracked smoothly in real-time.

Also, refactored the task addition layout to resolve a critical data-health serialization bug that was forcing incomplete integer data onto the disk.

# CHANGES:
- Restructured onTaskAdded to execute 	askUpdateService.update prior to disk serialization, ensuring newly created tasks capture true player statistics instead of zero placeholders.
- Offloaded goalManager.save() and
otifyTask to the background game thread to insulate the main Swing UI thread from blocking I/O stutters.
- Integrated the 
efreshAllTasks background gatekeeper to process prerequisite batch additions safely on the game thread.
- Fortified Task and Goal models with self-healing null guards to prevent user interface crashes during malformed JSON data imports.
A few files were converted back to CRLF... so I bumped them back to LF again.
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.

1 participant