DEV Community

Hiroshi TK
Hiroshi TK

Posted on

A quest-completion marker needs a persistent state after the animation

This is a proposed integration recipe, not a claim of a completed runtime test.

A quest marker should still communicate completion after its particles disappear. Treat the effect as a short acknowledgment of a state change, while the completed icon and text remain the authoritative UI.

The sequence in this example is deliberately small: update the quest state, show the completed marker immediately, optionally play one decorative burst, and clean up the effect when it finishes. The animation must not delay reward eligibility or hide the completed state from keyboard and assistive-technology users.

Deduplicate the completion event

A reconnect or repeated server message can announce the same quest completion twice. Use an identifier for the completion event rather than assuming each callback represents a new achievement.

export function makeCompletionHandler(onComplete) {
  const handled = new Set();
  return event => {
    if (!event.id || handled.has(event.id)) return false;
    handled.add(event.id);
    onComplete(event);
    return true;
  };
}
Enter fullscreen mode Exit fullscreen mode

Keep that set within the appropriate session or quest-screen lifetime. A long-running application needs a bounded retention policy or an authoritative completion version, not an unbounded global set. The example isolates the deduplication rule without prescribing the server's event model.

Put timing in the asset contract

Use a one-shot marker asset with a proposed 0.45-second maximum particle lifetime and no looping emitter. The persistent check icon should appear at event receipt, not at the end of that lifetime. The exact visual envelope needs review in the game; the value here is an art target rather than a measured result.

A web game particle editor is useful for adjusting the appearance independently of the quest logic. NixieFX's PixiJS guide describes the export and runtime integration path. Create a distinct quest-complete effect, validate it for Pixi, and keep the source alongside the exported bundle.

On a new completion event:
1. Update the persistent completed icon and label.
2. Announce completion once through the host's accessible UI.
3. If reduced motion is enabled, skip the particles.
4. Otherwise create the verified one-shot at the marker position.
5. Remove the finished instance through the renderer's cleanup API.
Enter fullscreen mode Exit fullscreen mode

These steps are host instructions. The particle runtime does not supply the quest state, semantic label, or screen-reader announcement for a canvas UI. Provide those through the application's accessible interface.

Keep the cue out of the reading path

Place the effect behind or beside the marker, with enough separation from the quest title to preserve readability. Test long titles and the smallest supported viewport. If the marker lives inside a transformed Pixi container, compute its position in the effect layer's coordinate space; a global position copied into a local layer can drift.

For a reproducible visual check, freeze the UI layout, use a fixed seed, and capture the marker at the same elapsed time. Do not describe a screenshot from the editor as proof of the host integration. The runtime screenshot needs to come from the actual Pixi screen.

Check the cases that expose the boundary

Send the same event twice and verify that only one cue occurs. Send a different completion and verify that it can produce its own cue. Enable reduced motion and confirm that the completed state and announcement still appear. Leave the screen during the burst and confirm that teardown removes the effect without changing quest data.

The code in this post covers event deduplication, not a complete game or a verified exported effect. Inspect the actual Pixi support report for unsupported or approximated authoring settings. Do not claim that lighting, depth, or other Three-specific presentation transfers unchanged. The recipe is complete only when the source asset, host integration, and visual check agree.

Top comments (1)

Collapse
 
saqrelfirgany profile image
Ahmed ElFirgany •

The handled Set stops repeats while one handler lives. After a page reload or reconnect, that Set starts empty. A server that replays recent events would then fire the burst again. Seeding the Set from the quest snapshot on load closes that gap. Should quests already complete at load skip the particles entirely?