Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Removed
- Retired the v2 section-difficulty surface (#159, tier rail 4/4, parent #131):
the `difficulty:sections-updated` event and its `difficulty_ladder.sections.v2`
payload (`fillPercentage` / `glassSize`), the legacy canvas overlay that drew
it (`drawHud` and its sizing/measurement helpers), and the retired pre-rename
setting key's one-time forward-migration. The render-neutral
`difficulty:sections-updated-v3` event (`difficulty_ladder.sections.v3`,
#156/#157) is now the only section-difficulty contract. This is a **breaking
change** for any third-party consumer still reading
`difficulty_ladder.sections.v2`: migrate to the v3 fields
(`sections[].top_tier` / `.current_tier` / `.has_chart_content`). Section Map
migrates to these fields in
[sectionmap#14](https://github.com/get-flashbacks/feedback-plugin-sectionmap/issues/14);
this removal ships only once that migration is in place.
The renamed-predecessor setting is gone: only `showDifficultyGuide` is read,
still defaulting to on. `screen.js`, `settings.html`, `tests/screen.test.js`,
`README.md`, `INTEGRATION.md`, `COMPLIANCE.md`, `PLAYER_CONTEXT.md`,
`MIGRATION.md` and `plugin.json` updated. Version 0.40.3 -> 0.41.0.

### Fixed
- Profile-aware Hosts that expose only `window.v3Profile` (no
`playerContexts` capability) now resolve the main player's identity when the
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ Also worth knowing before poking around:
- **`PLAYER_CONTEXT.md`** — the multi-player `(session_id, player_id)`
contract shared with Split Screen, `note_detect`, karaoke, and Section
Map; read this before touching anything that keys state by player.
- **`INTEGRATION.md`** — Section Map's phrase/glass-fill contract
(`difficulty:sections-updated`, schema `difficulty_ladder.sections.v2`).
- **`INTEGRATION.md`** — Section Map's section-difficulty contract
(`difficulty:sections-updated-v3`, schema `difficulty_ladder.sections.v3`).
Note: as of this writing its title line still reads "Integration —
feedBack-plugin-sectionmap", left over from an earlier doc it was
adapted from — the content is this repo's real, current contract
Expand Down Expand Up @@ -132,7 +132,7 @@ snapshot, this one included.
## Testing

```bash
node --test # JS: all tests/*.test.js (429 tests)
node --test # JS: all tests/*.test.js (419 tests)
python3 -m pip install -r requirements-test.txt # Python test environment
python3 -m pytest tests/test_dd_generation.py -q # Python generator tests — CI's own invocation
node tools/settle_points.js # auto-adjust settle-point simulation, see README
Expand Down
24 changes: 12 additions & 12 deletions COMPLIANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ spec is intentionally non-normative about exact mechanics.
- [x] `standards: ["plugin-runtime-idempotent.v1"]` — verified true: `screen.js`'s singleton guard
(`window.__feedBackDynamicDifficulty.installed`) returns unconditionally on any re-run, so a
second execution installs zero additional listeners/timers/wrappers (§6.1).
- [x] rAF loops (`tickScoring`, `drawHud`) stop themselves when the player isn't active and restart
- [x] rAF loops (`tickScoring`) stop themselves when the player isn't active and restart
on `highway:visibility` / `visibilitychange` (§6.4, rule 13).
- [x] No `querySelector`/`querySelectorAll`/layout reads inside a per-frame path; DOM refs
(`_hudCanvas`, `_playerEl`) are cached and only re-resolved via a cheap `.isConnected` check
(`_playerEl`) are cached and only re-resolved via a cheap `.isConnected` check
(rule 9).
- [x] No `MutationObserver` anywhere in the plugin (rule 10).
- [x] `localStorage` writes are debounced/change-gated (`_onMasteryApplied` skips the write when
the value is unchanged) and never happen inside `tickScoring`'s or `drawHud`'s per-frame body
the value is unchanged) and never happen inside `tickScoring`'s per-frame body
— only from the `setMastery` wrapper, which fires on user/auto-adjust action, not per frame
(rule 11). Confirmed this is the established, org-wide pattern: `localStorage` is used
extensively by first-party bundled plugins (`achievements`, `career`, `highway_3d`,
Expand Down Expand Up @@ -96,7 +96,7 @@ spec is intentionally non-normative about exact mechanics.
declare a capability domain for this surface, which is *correct*, not a gap: best-practices rule
52 is explicit that declaring a capability you don't service is worse than declaring none. The
actual cross-plugin surface for section-level difficulty is the plugin's own
`difficulty:sections-updated` event — see "Section-map integration assumptions" below for the
`difficulty:sections-updated-v3` event — see "Section-map integration assumptions" below for the
current (post-#63) contract; this bullet's original text described a since-superseded
getters-only architecture. (Separately, unrelated to section difficulty: the plugin *does* now
participate in the Host's capability dispatch pipeline for player-scoped difficulty commands —
Expand Down Expand Up @@ -131,24 +131,24 @@ spec is intentionally non-normative about exact mechanics.
longer how this integration works.** This section originally documented issue #9's acceptance
criteria against the state of the plugins at the time (both reading `window.highway` getters
independently, no dedicated event). That's since changed: `difficulty_ladder` now emits a bespoke
`difficulty:sections-updated` event on `window.feedBack` (fired from
`difficulty:sections-updated-v3` event on `window.feedBack` (fired from
`calculateAndEmitSectionDifficulties()`, throttled at approximately 150 ms — a trailing-edge
throttle via `scheduleSectionDifficultiesEmit()`, not a debounce: it fires periodically during a
continuous drag rather than only once at the end), and `section_map` no longer calls
`highway.getPhrases()` / `hasPhraseData()` / `getMastery()` for section-difficulty data at all — it
renders whatever `fillPercentage`/`glassSize` the event payload carries per section, and nothing
renders whatever tiers, spans and content flags the event payload carries per section, and nothing
else. See [`INTEGRATION.md`](INTEGRATION.md) for the authoritative, current contract (event shape,
fallback/timing behavior, and why the fill formula was unified with `drawHud()`'s own discrete
tiers in the same pass). Kept below for historical context only; do not treat the bullets as
fallback/timing behavior, and the shared discrete tier mapping used by the guide, the attempt log
and the v3 payload). Kept below for historical context only; do not treat the bullets as
current:

- ~~This plugin does **not** expose a bespoke API or event for section difficulty.~~ It does now
(`difficulty:sections-updated`).
(`difficulty:sections-updated-v3`).
- ~~`feedBack-plugin-sectionmap` should therefore read `window.highway.getPhrases()` /
`hasPhraseData()` / `getMastery()` directly...~~ It doesn't anymore; it's a pure event consumer.
- No "difficulty maker" screen exists anywhere in the current feedBack codebase (checked
`feedBack/plugins/` and `feedBack/static/` for any "maker" screen) — still true, and unaffected
by the event-contract change above.
- Missing/delayed phrase data must degrade to "no glass HUD," never an error — still the case on
both sides: this plugin's own `drawHud()` fail-soft path is unchanged, and `section_map` simply
has nothing to render when no `difficulty:sections-updated` event has fired yet.
- Missing/delayed phrase data must degrade to "no section difficulty," never an error — still the
case on both sides: this plugin's own guide fail-soft path is unchanged, and `section_map` simply
has nothing to render when no `difficulty:sections-updated-v3` event has fired yet.
Loading
Loading