Post-codex-review-5: align event-log с telemetry spec + UX polish

- MatchTracker (codex #1 Low): event-log поля переименованы под
  telemetry-spec.md v3.10 — ballOwner→ballOwnerBeforeHit,
  matchTimeSec→matchTimeSeconds (для bumper_hit и goal events).
  Future-proof для batched emit через .getEvents(). Тест assertion
  обновлён под новые поля.
- Touch zone labels (codex #2 Low): BOOST 14→18px, alpha все
  лейблы 0.5→0.7 для mobile readability.
- Test comment (codex #3 editorial): «player получает hits через
  ai_setup» → корректная формулировка про defensive trap
  (атакующий игрок кормит AI как защитника).

50/50 tests, typecheck/lint/build .

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
aevgarik
2026-05-24 08:13:32 +03:00
parent bfdb24294a
commit 32b894ec08
3 changed files with 13 additions and 9 deletions

View File

@@ -579,7 +579,7 @@ export class MatchScene extends Phaser.Scene {
.text(sideW / 2, zoneY, '◀ L', {
fontFamily: 'monospace', fontSize: '20px', color: '#ff006e', fontStyle: 'bold',
})
.setOrigin(0.5).setAlpha(0.5);
.setOrigin(0.5).setAlpha(0.7);
// Right zone
const rightX = GAME_WIDTH - sideW / 2;
@@ -594,7 +594,7 @@ export class MatchScene extends Phaser.Scene {
.text(rightX, zoneY, 'R ▶', {
fontFamily: 'monospace', fontSize: '20px', color: '#ff006e', fontStyle: 'bold',
})
.setOrigin(0.5).setAlpha(0.5);
.setOrigin(0.5).setAlpha(0.7);
// Booster zone (центр, узкая) — Phase 2 placeholder
const boosterZone = this.add.rectangle(GAME_WIDTH / 2, zoneY, boosterW, zoneH * 0.5, PALETTE.accent, 0.05);
@@ -606,9 +606,9 @@ export class MatchScene extends Phaser.Scene {
});
this.add
.text(GAME_WIDTH / 2, zoneY, 'BOOST', {
fontFamily: 'monospace', fontSize: '14px', color: '#ffbe0b', fontStyle: 'bold',
fontFamily: 'monospace', fontSize: '18px', color: '#ffbe0b', fontStyle: 'bold',
})
.setOrigin(0.5).setAlpha(0.5);
.setOrigin(0.5).setAlpha(0.7);
}
private buildHUD(): void {

View File

@@ -99,7 +99,8 @@ describe('MatchTracker.recordBumperHit — credit и point-counters', () => {
describe('MatchTracker.recordBumperHit — стэк очков и событий', () => {
it('многократные hits корректно накапливают BP per сторона', () => {
const t = new MatchTracker(0);
// Player атакует — player получает 3 hits через ai_setup (по 3 pts slingshot)
// Player атакует (ballOwner=player) — мяч застревает в AI-setup,
// AI фармит как защитник (defensive trap). Player BP не растёт.
t.recordBumperHit(3, 'ai_setup', 'player', 'slingshot', 0, 0);
t.recordBumperHit(3, 'ai_setup', 'player', 'slingshot', 100, 0.1);
t.recordBumperHit(10, 'ai_setup', 'player', 'turbo', 200, 0.2);
@@ -137,7 +138,7 @@ describe('MatchTracker.recordBumperHit — стэк очков и событий
expect(events[0]?.data).toMatchObject({
source: 'fixed_last_touch',
bumperType: 'standard',
ballOwner: 'player',
ballOwnerBeforeHit: 'player',
creditedTo: 'player',
pointsEarned: 5,
});

View File

@@ -115,16 +115,18 @@ export class MatchTracker {
this.uncreditedBumperHits += 1;
}
// Event-log использует имена полей из telemetry-spec.md v3.10 bumper_hit event,
// чтобы при future batched-emit можно было пробрасывать .getEvents() напрямую.
this.events.push({
type: 'bumper_hit',
timestamp: now,
data: {
source,
bumperType,
ballOwner,
ballOwnerBeforeHit: ballOwner,
creditedTo,
pointsEarned,
matchTimeSec,
matchTimeSeconds: matchTimeSec,
},
});
@@ -139,6 +141,7 @@ export class MatchTracker {
} else {
this.aiGoals += 1;
}
// Event-log поля совпадают с telemetry-spec.md goal_scored event.
this.events.push({
type: 'goal',
timestamp: now,
@@ -146,7 +149,7 @@ export class MatchTracker {
scorer: scoredBy,
isAutogoal,
ballOwnershipBeforeGoal: this.ballOwner,
matchTimeSec,
matchTimeSeconds: matchTimeSec,
},
});
}