feat: guided tutorial for first-time players#215
Merged
Conversation
Implements a step-by-step tutorial that activates on a player's first practice game. The tutorial guides through 6 scripted orb pulls (points, bomb, multiplier, triple bomb, health, points-to-milestone), explains game mechanics at each step with spotlight overlays, walks through the milestone choice and shop, then lets the player free-play until game end. - Tutorial state persisted in localStorage (survives reload) - Scripted pulls via forcedOrbId param threaded through engine/store/actions - Spotlight overlay with SVG mask cutout, positioned tooltips, and arrows - data-tutorial-id attributes on key UI elements for targeting - Reward overlay suppressed during tutorial for direct game entry - Level-up overlay suppressed during scripted phase - Post-game messages explain reward mode on return to home Co-Authored-By: Lattice
The overlay was capturing all pointer events, preventing clicks from reaching the underlying buttons (practice, puller, bag, continue). Split the backdrop into 4 dark panels around the spotlight gap for interactive steps so clicks in the spotlight pass through to the real DOM elements. Non-interactive steps still use a full-screen backdrop with SVG mask. Also updated hint text to say "TAP THE HIGHLIGHTED AREA" for target-only steps. Co-Authored-By: Lattice
The outer overlay container uses pointer-events: none so the spotlight gap is clickable, but child backdrop elements were inheriting that and couldn't receive tap events. Added explicit pointerEvents: "auto" to all backdrop panels (4-panel split, SVG mask, and full-screen div). Co-Authored-By: Lattice
Replaced the 4-panel rectangular gap with SVG clip-path donut approach.
clip-path affects both rendering and hit-testing, so clicks inside the
circle pass through to the puller button. Added spotlightShape config
option ("rect" | "circle") to step definitions. The PULL_PROMPT step
now uses a circular cutout with extra padding for a clean look.
Co-Authored-By: Lattice
The data-tutorial-id was on the wrapper div that includes the multiplier badge, making the bounding rect taller than the actual puller. Moved the attribute to the Puller component itself so the circular spotlight is centered precisely on the pull button. Co-Authored-By: Lattice
The spotlight targeting of the practice button was fragile — the data-tutorial-id ended up on the inner <button> inside GradientBorder, and when not found the backdrop blocked all interaction with no hole. Changed HOME_WELCOME to a centered tap-anywhere overlay with no target. Tapping dismisses it, then the player clicks practice naturally. The tutorial activates when they click practice via startTutorial(). Co-Authored-By: Lattice
The data-tutorial-id on Button components ended up on the inner <button> inside GradientBorder, making the spotlight misaligned and clicks unable to reach the real element. Wrapped practice button (desktop + mobile), ORBS button, and CASH OUT button in plain <div data-tutorial-id="..."> wrappers so the spotlight covers the full visual element and the clip-path hole lines up with the actual clickable area. Restored HOME_WELCOME as an interactive spotlight step pointing at the practice button. Co-Authored-By: Lattice
The inner path in the clip-path donut wound the same direction as the outer rect. With the default nonzero fill rule, both regions counted as "inside" so no hole appeared. Adding evenodd makes the inner region alternate to "outside", creating the visible cutout for both circle and rounded-rect spotlights. Co-Authored-By: Lattice
Only allow pulls at PULL_PROMPT and WAIT_PULL steps. All other steps in the scripted phase (overlays, AFTER_PULL animations, explanations) now block pulling. After FREE_PLAY the restriction is lifted. Co-Authored-By: Lattice
- Trigger onOrbBought from onBalanceChange when balance drops (user tapped + on an orb) instead of waiting for shop confirm. This shows the "price increases" tooltip immediately while still in the shop. - Suppress "Entering Level X" overlay during tutorial scripted phase so it doesn't cover the tutorial tooltips. - handleBuyAndExit now only calls onShopExited (not onOrbBought). Co-Authored-By: Lattice
The tutorial useEffects had `tutorial` in their dependency arrays. Since the tutorial context value object is recreated on every state change, calling onGameEnd (which updates tutorial state) triggered the effect again, causing an infinite setState loop. Removed `tutorial` from deps of game-over and pull-animation-complete effects — they only need to fire on game state changes, not tutorial state changes. Co-Authored-By: Lattice
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Shortened pull outcome animation from 2000ms to 1200ms during the tutorial scripted phase so explanation tooltips appear faster after each pull. Also reduced tooltip entrance animation delay from 150ms to 80ms and duration from 300ms to 200ms for snappier feel. Co-Authored-By: Lattice
- game.tsx: use tutorialRef to read tutorial state inside useLayoutEffect instead of accessing tutorial.state directly (avoids adding tutorial to deps which would cause re-render loops) - TutorialOverlay.tsx: add currentConfig.spotlightShape to useEffect deps Co-Authored-By: Lattice
Co-Authored-By: Lattice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a step-by-step interactive tutorial that activates on a player's first practice game. The tutorial walks new players through the core game mechanics with scripted orb pulls and contextual tooltips.
Tutorial Flow
Implementation
client/src/tutorial/): 35-step state machine with localStorage persistence, React context, and hooksforcedOrbIdparameter threaded through offline engine → store → actions hook to force specific orbs during tutorialevenoddfill rule creates circular (puller) or rounded-rect (buttons) cutouts that pass both visual rendering and pointer events through to the underlying UIKey design decisions
data-tutorial-idattributes on wrapper<div>s (not on Button components directly) so the spotlight targets the full visual element including GradientBorderclip-path: path(evenodd, ...)approach for interactive spotlight steps — creates a pointer-event hole so clicks pass through to the real button underneathfont-secondary(VCR OSD Mono), raw hex colors from CSS variables, GradientBorder-style card with#0A1A0AbackgroundTest plan
🪟 Made with Lattice