feat: add four Blackwood story expansions as vanilla ES modules#40
feat: add four Blackwood story expansions as vanilla ES modules#40Copilot wants to merge 5 commits into
Conversation
…s, Third-Star Altar, Library of Still Waters) Agent-Logs-Url: https://github.com/NicholaiMadias/gamifiedlearning.github.io/sessions/ba999351-e96a-4055-ad1c-e4f58a2aa3e1 Co-authored-by: NicholaiMadias <73684379+NicholaiMadias@users.noreply.github.com>
Agent-Logs-Url: https://github.com/NicholaiMadias/gamifiedlearning.github.io/sessions/ba999351-e96a-4055-ad1c-e4f58a2aa3e1 Co-authored-by: NicholaiMadias <73684379+NicholaiMadias@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds four new “Blackwood” quest-arc interactive modules as vanilla ES modules (no build step), integrating them into the existing static index.html experience via a new tabbed navigation.
Changes:
- Added four new location/puzzle UIs (Whispering Pines, Third-Star Altar, Raven’s Message, Library of Still Waters) that dispatch completion
CustomEvents onwindow. - Added a Raven’s Message match-3 board engine (
ravensMessageBoard.js) mirroring the existingmatchMakerState.jsAPI shape. - Updated
index.html+main.jsto include tab navigation, new screens, styles, and init/restart wiring.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| whispering-pines-ui.js | New toggle-stone puzzle UI and completion event dispatch. |
| third-star-altar-ui.js | New drag-to-reorder ritual UI and completion event dispatch with ordering detail. |
| ravensMessageBoard.js | New 8×8 match-3 state engine (create/swap/match/clear/gravity). |
| ravens-message-ui.js | New Raven-themed match-3 UI with moves/score and completion event dispatch. |
| library-of-still-waters-ui.js | New scenario-based decision puzzle with scoring, retry, and completion event dispatch. |
| main.js | Imports/inits new modules; adds tab switching and button handlers. |
| index.html | Adds tab bar + new screens and scoped CSS for the new modules. |
| STONES.forEach(({ id, label, name }) => { | ||
| const btn = document.createElement('button'); | ||
| btn.className = 'wp-stone'; | ||
| btn.id = `wp-stone-${id}`; | ||
| btn.title = name; | ||
| btn.textContent = label; | ||
| btn.onclick = () => toggleStone(id); | ||
| ring.appendChild(btn); |
There was a problem hiding this comment.
The stone buttons render as single-character glyphs (△/○/◇) and only set title; many assistive technologies won’t announce title reliably. Consider adding an accessible name/state (e.g., aria-label with the stone name and aria-pressed reflecting selection) so the toggle UI is usable with screen readers.
| <nav class="tab-nav" id="tab-nav"> | ||
| <button class="tab-btn tab-btn--active" data-tab="match-maker">Match Maker</button> | ||
| <button class="tab-btn" data-tab="ravens-message">Raven's Message</button> | ||
| <button class="tab-btn" data-tab="whispering-pines">Whispering Pines</button> | ||
| <button class="tab-btn" data-tab="third-star-altar">Third-Star Altar</button> | ||
| <button class="tab-btn" data-tab="library-still-waters">Library of Still Waters</button> | ||
| </nav> |
There was a problem hiding this comment.
The tab UI is visually a tabset, but there are no ARIA semantics tying the buttons to their panels (e.g., role="tablist"/"tab", aria-controls, aria-selected, and updating these on selection). Adding these attributes (and keeping focus behavior consistent) would make the new navigation much more accessible to screen readers.
| const slot = document.createElement('div'); | ||
| slot.className = 'altar-slot'; | ||
| slot.id = `altar-slot-${artifact.id}`; | ||
| slot.draggable = true; | ||
| slot.textContent = artifact.label; | ||
| slot.dataset.index = index; |
There was a problem hiding this comment.
This interaction is drag-and-drop only (draggable = true + drag events), which is not keyboard accessible. Consider providing a keyboard alternative (e.g., move left/right buttons per slot or a select + move controls) or at least an accessible fallback so users who can’t drag still can complete the puzzle.
| currentScenario++; | ||
|
|
||
| // Brief pause so the player can read the feedback before next scenario | ||
| setTimeout(renderScenario, 900); | ||
| } |
There was a problem hiding this comment.
handleWisdomChoice schedules renderScenario via setTimeout but leaves the choice buttons active during the 900ms pause. A quick double-click will advance currentScenario multiple times and can inflate wisdomScore, skipping scenarios. Consider locking input until the next scenario renders (e.g., disable the buttons / hide the choice row immediately, or keep a pending-timeout flag and ignore additional clicks).
|
|
||
| /** | ||
| * Finds all horizontal and vertical matches of 3 or more. | ||
| * Returns an array of match groups, each being an array of {r, c} objects. |
There was a problem hiding this comment.
The findMatches JSDoc says it returns “an array of match groups”, but the implementation collapses everything into a single group (return [[...matched].map(...)]) like matchMakerState.findMatches. Please either update the comment to document the single-group behavior or change the function to actually return separate groups so callers aren’t misled.
| * Returns an array of match groups, each being an array of {r, c} objects. | |
| * Returns an empty array when there are no matches, otherwise a single | |
| * match group containing every matched cell as an array of {r, c} objects. |
| board = clearMatches(board, matches); | ||
| board = applyGravity(board); | ||
| renderBoard(); | ||
|
|
||
| setTimeout(resolveRavenMatches, CHAIN_DELAY_MS); |
There was a problem hiding this comment.
resolveRavenMatches schedules itself via setTimeout but initRavensMessage/restart doesn’t cancel any pending timeout. If the user clicks “↺ New Board” during a chain reaction, an older timeout will continue mutating the newly-initialized board/score/moves. Track the timeout id (or a runId/generation token) and cancel/ignore stale callbacks when re-initializing or restarting.
| const cell = document.createElement('div'); | ||
| cell.className = 'rm-cell'; | ||
| cell.dataset.row = r; | ||
| cell.dataset.col = c; | ||
| cell.textContent = RAVEN_ICONS[board[r][c]] ?? '⬛'; |
There was a problem hiding this comment.
The grid cells are clickable
| const cell = document.createElement('div'); | |
| cell.className = 'rm-cell'; | |
| cell.dataset.row = r; | |
| cell.dataset.col = c; | |
| cell.textContent = RAVEN_ICONS[board[r][c]] ?? '⬛'; | |
| const tile = board[r][c]; | |
| const cell = document.createElement('button'); | |
| cell.type = 'button'; | |
| cell.className = 'rm-cell'; | |
| cell.dataset.row = r; | |
| cell.dataset.col = c; | |
| cell.textContent = RAVEN_ICONS[tile] ?? '⬛'; | |
| cell.setAttribute('aria-label', `Row ${r + 1}, column ${c + 1}, ${tile} raven tile`); |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/NicholaiMadias/gamifiedlearning.github.io/sessions/2f59a362-a892-415c-b90b-55d1c1b6b46b Co-authored-by: NicholaiMadias <73684379+NicholaiMadias@users.noreply.github.com>
Implements four new interactive modules for the Blackwood quest arc — Whispering Pines, Raven's Message, Third-Star Altar, and Library of Still Waters — as vanilla ES modules matching the existing static-site architecture (no React, no build step).
New modules
ravensMessageBoard.js— 8×8 board state engine (createBoard,canSwap,applySwap,findMatches,clearMatches,applyGravity); mirrors thematchMakerState.jsAPI shaperavens-message-ui.js— Raven-themed match-3 on 8×8 grid; 25-move limit, chain reactions, firesravens_message_completeCustomEvent at 150 ptswhispering-pines-ui.js— Three toggle-able symbol stones (△ ○ ◇); requires all selected before "Align"; fireswhispering_pines_completethird-star-altar-ui.js— Drag-to-reorder three artifact slots; "Perform Ritual" firesthird_star_completewith current order indetaillibrary-of-still-waters-ui.js— 3-scenario decision engine (Fourth Star: Wisdom); fireswisdom_star_completeon perfect run, offers retry on failureAll completion events are
CustomEvents dispatched onwindow, keeping modules decoupled from any future quest engine integration.index.html/main.jschangesclicklistener on#tab-nav./assets/main.jsimports and inits all modules; wires button handlersAsset placeholders
Background images are referenced as relative paths (
./assets/*.png). Drop generated art here when ready:assets/whispering-pines.pngassets/third-star-altar.pngassets/library-of-still-waters.png