1. 03 Jul, 2026 14 commits
  2. 25 Jun, 2026 3 commits
  3. 23 Jun, 2026 5 commits
    • Mahmoud Aglan's avatar
      fix: draw offer race condition + add multiplayer logging · 9b2a459c
      Mahmoud Aglan authored
      Root cause: draw offers stored in game_state were lost when a
      concurrent move write did read→merge→write (non-atomic). Now uses
      PostgreSQL jsonb || operator via merge_game_state() RPC for atomic
      merges.
      
      Also adds:
      - mp_log table for server-side multiplayer event logging
      - Frontend sessionStorage logging (sessionStorage.mp_log) for
        debugging draw offers, moves, and poll events
      - Logging on match_created, move, resign, draw_accepted, game_state_merge
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      9b2a459c
    • Mahmoud Aglan's avatar
      test: add chess sync verification test with move+resign proof · 2f9d7d84
      Mahmoud Aglan authored
      Screenshots confirm: moves sync to opponent board, resign shows
      victory screen. Both directions verified via Puppeteer + API.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      2f9d7d84
    • Mahmoud Aglan's avatar
      fix: chess moves/resign silently failing — non-existent columns · b3109e7a
      Mahmoud Aglan authored
      The `matches` table has no `last_activity` or `ended_at` columns.
      PostgREST rejects the entire PATCH when ANY column doesn't exist,
      causing every move update and resignation to silently fail.
      
      - Remove `last_activity` from handleGameMove (column doesn't exist)
      - Change `ended_at` to `completed_at` in handleResign, handleDraw,
        handleComplete (correct column name per DB schema)
      
      This was the root cause of zero sync in multiplayer chess.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      b3109e7a
    • Mahmoud Aglan's avatar
      fix: bulletproof matchmaking queue across all games · 1c145579
      Mahmoud Aglan authored
      - Add dequeue handler to backgammon-match.php (was missing)
      - Add 90-second stale entry cleanup to ludo/domino/backgammon queues
      - Add atomic opponent claiming (conditional update) to prevent race conditions
      - Fix client queue.js to route dequeue to correct game endpoint
      - Register unmountQueue for proper cleanup when exiting search screen
      - Remove json_encode on jsonb fields in backgammon (prevent double-encoding)
      
      Fixes: self-matching, ghost queue entries, and race condition where two
      players simultaneously claim the same opponent.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      1c145579
    • Mahmoud Aglan's avatar
      fix: eliminate jsonb double-encoding that broke multiplayer sync · 6517bd2d
      Mahmoud Aglan authored
      The root cause: PHP's json_encode() was used on jsonb fields before
      passing to SupabaseClient->insert/update, which json_encodes the entire
      payload. This double-encoded game_state into a JSON string scalar.
      
      When the match_heartbeat RPC did `jsonb_string || jsonb_object`,
      PostgreSQL created an array instead of merging, corrupting game_state.
      The polling logic then couldn't find move_count or last_move in the
      array, so moves never synced between players.
      
      Fix: pass PHP arrays directly for all jsonb columns (game_state, moves,
      positions, scores, winners, hands, boneyard). The Supabase client
      handles encoding once at the HTTP layer.
      
      Also: when reading game_state back from the DB, handle the case where
      PostgREST returns it as a decoded array/object (not a string) since
      jsonb columns are deserialized automatically.
      
      Affected: chess, ludo, domino — all multiplayer match creation and
      move/state updates.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      6517bd2d
  4. 22 Jun, 2026 1 commit
  5. 21 Jun, 2026 4 commits
  6. 20 Jun, 2026 8 commits
  7. 19 Jun, 2026 5 commits
    • Mahmoud Aglan's avatar
      24810eaf
    • Mahmoud Aglan's avatar
      fix: getPipCount used non-existent VARIANTS.standard key · 1050fd15
      Mahmoud Aglan authored
      The VARIANTS object has keys 'sheshbesh', 'mahbousa', 'thirtyone' but
      getPipCount referenced 'standard' which is undefined, causing
      'Cannot read properties of undefined (reading normPos)' and preventing
      the entire board from rendering.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      1050fd15
    • Mahmoud Aglan's avatar
      fix: redesign backgammon game UI with real player data + polished visuals · c5374e12
      Mahmoud Aglan authored
      - Player cards now use store player data (avatar_url, display_name, level)
      - Opponent shows bot icon or opponent data for multiplayer
      - Active turn highlight on player cards with green glow border
      - Cube value display in match info area
      - Professional dark gradient background with proper hierarchy
      - Controls bar with proper spacing and button styling
      - Doubling offer dialog with backdrop blur and better layout
      - Turn badge repositioned to top-center with pill shape
      - Emote panel centered with backdrop blur
      - All interactive elements have proper touch targets (40px+)
      - Safe area inset for bottom bar
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      c5374e12
    • Mahmoud Aglan's avatar
      fix: backgammon gameplay — working buttons, correct canvas rendering, no DPR bugs · 873b7000
      Mahmoud Aglan authored
      - Remove DPR ctx.scale() that compounded every frame and broke all rendering
      - Use logical pixel dimensions directly (canvas.width = logical size)
      - Fix isSel/isValid closures that caused undefined reference errors in checker glow
      - Simplify game scene: roll button is now a normal element in .bgg-controls (not overlay)
      - Event handlers correctly scale click coords via rect ratio
      - Remove unused getCheckerScreenPos import from move-animator
      - All buttons (roll, double, emote, quit) bind via addEventListener properly
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      873b7000
    • Mahmoud Aglan's avatar
      feat: full backgammon overhaul — 60fps game loop, premium canvas, particles, admin branding · 4cf9baa5
      Mahmoud Aglan authored
      - 60fps requestAnimationFrame game loop with dt-based particle physics
      - 3D checkers with radial gradients, specular highlights, drop shadows
      - Wood-grain board texture with gradient triangles and bevel frame
      - Physics-based dice with bounce damping, spin, and staggered animation
      - Arc-based move animations with easeOutBack overshoot
      - Particle burst on hit (red/orange sparks) and bear-off (green stars)
      - Confetti celebration on match win with canvas animation
      - Full multiplayer sync via match-session + server polling
      - Bot AI with animated moves (arc + SFX per piece)
      - Admin branding: 14 board colors + 7 game settings (durations, particles)
      - CSS tokens for all backgammon board colors (--bg-*)
      - Theme.js maps branding values to CSS vars + window.__EL3AB_THEME
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      4cf9baa5