Compare commits

...

2 Commits

Author SHA1 Message Date
Brian Fertig 91be23088c Raise claim-reward plate depth above HUD overlays
- Bump CLAIM REWARD plate from depth 31 to 65 so it renders above compass arrows, toasts, deck blocks, and the sub-bar while still staying below modals (70) and full-screen consoles (80).
- Update ship.mp4 asset.
2026-09-19 10:25:58 -06:00
Brian Fertig 36e36fb2d1 Fix MineralHud capacity restore snapping the fill back to stale fraction
- Void in-flight count-up tween when max changes so a late landing can't redraw against the old cap (250/250 → full after cap grew to 500)
- Add regression test for mid-count-up capacity restore voiding the stale tween
- Archive completed ship-screen goal and add ship.mp4 asset
2026-09-19 09:53:46 -06:00
8 changed files with 48 additions and 8 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,9 +9,9 @@
"activeSeconds": 19608
},
"sisyphus": false,
"revision": 383,
"revision": 385,
"createdAt": "2026-09-18T22:07:23.053Z",
"updatedAt": "2026-09-19T14:55:35.006Z",
"updatedAt": "2026-09-19T15:40:04.710Z",
"scheduler": {
"version": 1,
"owner": "01a0b67f-b950-7128-bde1-b1647328e168",
@ -72,8 +72,8 @@
"blockCompletion": true,
"proposedAt": "2026-09-18T21:58:39.258Z"
},
"activePath": ".pi/goals/active_goal_2026091816072305_mu7ieab2-f24hte.md",
"stopReason": "user"
"stopReason": "user",
"archivedPath": ".pi/goals/archived/goal_2026091909324453_mu7ieab2-f24hte.md"
}
# Goal Prompt

View File

@ -46,3 +46,5 @@
{"type":"task_started","goalId":"mu7ieab2-f24hte","taskId":"task-5","at":"2026-09-19T05:22:27.127Z"}
{"type":"task_complete","goalId":"mu7ieab2-f24hte","taskId":"task-5","evidence":"Selecting a filled bay opens BAY MANIFEST (js/ui/ShipWindow.js _paintManifest): goods icon frame, name, CLASS/TIER/BASE VALUE chips (labels from data), flavor, MADE IN origin|hub pool + producer class","at":"2026-09-19T06:10:11.478Z"}
{"type":"goal_paused","goalId":"mu7ieab2-f24hte","reason":"user","status":"paused","at":"2026-09-19T14:55:34.986Z"}
{"type":"goal_focused","goalId":"mu7ieab2-f24hte","reason":"selected","at":"2026-09-19T15:32:31.167Z"}
{"type":"goal_focused","goalId":"mu7ieab2-f24hte","reason":"selected","at":"2026-09-19T15:38:35.941Z"}

BIN
assets/videos/ship.mp4 Normal file

Binary file not shown.

View File

@ -14,6 +14,9 @@
* - quick-succession landings: a superseded tween landing LATE can't
* snap the readout back to a stale value (the fragment staggers are
* ~70 ms vs a 420 ms count-up — they overlap in real play);
* - the main-game entry sequence: the capacity restored from build
* records (250 → 500) landing MID count-up must void the stale
* tween — the bar may not snap back to 'full' against the OLD cap;
* - the fill turns amber (theme 'amber') at capacity;
* - clamping (overfull records, negatives), no-op on unchanged value,
* and clean teardown.
@ -194,6 +197,30 @@ function makeScene() {
assert.ok(Math.abs(hud.fillG.fills.at(-1).w - (hud.innerW * 2) / 250) < 1e-9, '… nor the bar');
}
// ---------------------------------------------------------------------------
// The main-game entry sequence: the HUD is seeded with the BASE hold
// (250) before the build records restore the expanded storage (500) —
// the capacity lands MID count-up. The in-flight tween's target fraction
// was computed against 250 (= full); when it lands late it must not snap
// the fill back to 'full' (the reported bug: 250 / 500 rendered full).
// ---------------------------------------------------------------------------
{
const scene = makeScene();
scene.tweens.defer = true;
const hud = new MineralHud(scene);
hud.set(250, 250); // GameScene.create() — base storage, count-up in flight
const t1 = scene._tweens[0]; // superseded count-up (target frac 250/250 = 1)
assert.equal(hud.set(250, 500), false, 'the restore only changes the capacity → no new tween');
assert.equal(hud.label.text, 'MINERALS 250 / 500', '… the readout shows the new cap');
assert.ok(Math.abs(hud.fillG.fills.at(-1).w - hud.innerW * (250 / 500)) < 1e-9,
'… and the fill re-draws at the NEW fraction (half)');
// The base-hold count-up lands LATE — it must be a no-op now.
t1.run();
assert.equal(hud.label.text, 'MINERALS 250 / 500', 'the late tween can\'t touch the readout');
assert.ok(Math.abs(hud.fillG.fills.at(-1).w - hud.innerW * (250 / 500)) < 1e-9,
'… and can\'t snap the bar back to "full"');
}
// ---------------------------------------------------------------------------
// Capacity: amber fill (theme 'amber'); drops don't flash; clamping
// ---------------------------------------------------------------------------
@ -240,6 +267,7 @@ function makeScene() {
console.log('layout: upper-right corner, screen-fixed (old tether spot): OK');
console.log('set(): count-up + bar fill (one tween, exact fraction): OK');
console.log('overlap: superseded tween is void (no stale snap-back): OK');
console.log('restore: capacity change mid count-up voids the stale tween: OK');
console.log('capacity: amber fill + clamping both ends: OK');
console.log('teardown: all layers destroyed: OK');
console.log('\nmineral-hud: all checks passed');

View File

@ -140,7 +140,12 @@ export class MineralHud extends Phaser.GameObjects.Container {
const newMax = Math.max(1, Math.round(Number(max) || 1));
if (newMax !== this.max) {
// Capacity changed: re-render even if the value didn't, so the
// 'n / N' readout and the fraction stay true.
// 'n / N' readout and the fraction stay true. Void any in-flight
// count-up FIRST — its target fraction was computed against the
// OLD max (e.g. 250/250 = 1 before the cap grew to 500), and
// without this its late onUpdate/onComplete would snap the fill
// back to the stale fraction after we've already re-drawn it.
this._gen++;
this.max = newMax;
this.label.setText(this.format(this.value));
this.drawFill(this._frac(this.value));

View File

@ -806,7 +806,12 @@ export class QuestTrackerHud {
const cont = new Phaser.GameObjects.Container(s, px, py);
s.add.existing(cont);
cont.setScrollFactor(0);
cont.setDepth(31); // just above the tracker's own plate (30)
// Topmost element of the live game: the CLAIM REWARD plate is never
// covered where it overlaps the compass arrows (40), the toasts
// (45), the deck blocks (50) or the sub-bar (60). Stays UNDER the
// modal save panel (70) and the full-screen consoles (80) — they
// own the screen while up.
cont.setDepth(65);
cont.add(g);
cont.add(header);
for (const b of btns) cont.add(b);