Skip to content

feat: add four Blackwood story expansions as vanilla ES modules#40

Draft
Copilot wants to merge 5 commits into
claude/push-polish-match-maker-uifrom
copilot/add-whispering-pines-react-page
Draft

feat: add four Blackwood story expansions as vanilla ES modules#40
Copilot wants to merge 5 commits into
claude/push-polish-match-maker-uifrom
copilot/add-whispering-pines-react-page

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

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 the matchMakerState.js API shape
  • ravens-message-ui.js — Raven-themed match-3 on 8×8 grid; 25-move limit, chain reactions, fires ravens_message_complete CustomEvent at 150 pts
  • whispering-pines-ui.js — Three toggle-able symbol stones (△ ○ ◇); requires all selected before "Align"; fires whispering_pines_complete
  • third-star-altar-ui.js — Drag-to-reorder three artifact slots; "Perform Ritual" fires third_star_complete with current order in detail
  • library-of-still-waters-ui.js — 3-scenario decision engine (Fourth Star: Wisdom); fires wisdom_star_complete on perfect run, offers retry on failure

All completion events are CustomEvents dispatched on window, keeping modules decoupled from any future quest engine integration.

index.html / main.js changes

  • Added 5-tab nav bar (Match Maker + 4 new); tab switching via single delegated click listener on #tab-nav
  • Scoped CSS for each new module; background panels degrade to solid dark colours until art assets are dropped into ./assets/
  • main.js imports and inits all modules; wires button handlers

Asset placeholders

Background images are referenced as relative paths (./assets/*.png). Drop generated art here when ready:

  • assets/whispering-pines.png
  • assets/third-star-altar.png
  • assets/library-of-still-waters.png

Copilot AI and others added 2 commits April 16, 2026 08:54
…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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 on window.
  • Added a Raven’s Message match-3 board engine (ravensMessageBoard.js) mirroring the existing matchMakerState.js API shape.
  • Updated index.html + main.js to 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.

Comment thread whispering-pines-ui.js
Comment on lines +29 to +36
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);
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread index.html
Comment on lines +458 to +464
<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>
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread third-star-altar-ui.js
Comment on lines +33 to +38
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;
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +75
currentScenario++;

// Brief pause so the player can read the feedback before next scenario
setTimeout(renderScenario, 900);
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment thread ravensMessageBoard.js

/**
* Finds all horizontal and vertical matches of 3 or more.
* Returns an array of match groups, each being an array of {r, c} objects.
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
* 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.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment thread ravens-message-ui.js
Comment on lines +124 to +128
board = clearMatches(board, matches);
board = applyGravity(board);
renderBoard();

setTimeout(resolveRavenMatches, CHAIN_DELAY_MS);
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread ravens-message-ui.js
Comment on lines +55 to +59
const cell = document.createElement('div');
cell.className = 'rm-cell';
cell.dataset.row = r;
cell.dataset.col = c;
cell.textContent = RAVEN_ICONS[board[r][c]] ?? '⬛';
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The grid cells are clickable

elements with only an onclick handler, so the match-3 UI isn’t keyboard accessible (no focus, no Enter/Space activation, no role). Consider rendering each cell as a (or add role="button", tabindex="0", and keydown handlers) so keyboard and assistive tech users can play.

Suggested change
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`);

Copilot uses AI. Check for mistakes.
Comment thread library-of-still-waters-ui.js
Comment thread third-star-altar-ui.js
NicholaiMadias and others added 3 commits April 16, 2026 16:17
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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