- 05 Jun, 2026 30 commits
-
-
Mahmoud Aglan authored
Player reconnection: - On app boot, checks localStorage for active match - Verifies match is still 'in_progress' on server before rejoining - If match ended/aborted → clears recovery, goes to homepage - If server unreachable → tries to rejoin anyway (optimistic) Match auto-close: - handleGet() checks updated_at timestamp on every poll - If match hasn't been updated in 30+ seconds → both players inactive - Server marks match as 'completed' with result 'aborted' - Next player who polls sees status='completed' → game ends cleanly - Prevents zombie matches lingering forever Flow: 1. Both players disconnect → no pings → updated_at goes stale 2. After 30s, if either player comes back and polls → server closes match 3. Match shows as 'aborted' → player sees 'game ended' UI 4. If only one player comes back within 30s → they keep playing (match alive) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Replace cluttered logo/level/coins/gems/bell HUD with clean layout: avatar+level badge (left), coins+gems (center), bell (right). Avatar taps navigate to profile. Add profile photo upload with camera badge overlay, client+server validation, Supabase Storage upload endpoint. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New core module handles ALL connection edge cases: TAB REFRESH RECOVERY: - Active match stored in localStorage with timestamp - On app boot, checks for recoverable match (< 5 min old) - Automatically re-enters the game scene with recovered state - Fetches latest state from server immediately TAB VISIBILITY (switch/minimize): - Pauses polling when tab is hidden (saves bandwidth) - Resumes and immediately fetches latest state on return - Resets disconnect timers on tab return OPPONENT DISCONNECT DETECTION: - Tracks lastOpponentActivity timestamp - After 30s: fires onOpponentDisconnect (show warning UI) - After 60s: fires onOpponentAbandon (auto-claim win) - If opponent comes back: fires onOpponentReconnect NETWORK LOSS HANDLING: - If server unreachable for 10s: fires onConnectionLost - On recovery: fires onConnectionRestored - Polling continues with error tolerance SERVER PING (keep-alive): - Every 10s, pings server with player ID + timestamp - Stored in game_state.ping field - Opponent's polling reads this to know sender is alive API: - create(matchId, gameType, callbacks) — start session - destroy() — clean up timers + localStorage - getRecoverableMatch() — check for resume on boot - markOpponentActive() — call when opponent data received - isConnected() / isOpponentConnected() — status checks Engine updated: - Imports match-session on boot - Checks for recoverable match after auth - Auto-resumes game if found Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Uses contain-fit logic: scales image to fit within the square while preserving natural proportions, centered within the cell. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Game tiles (chess, domino, ludo, backgammon) now get their gradient colors from the theme — editing chess_primary/chess_secondary etc in admin branding immediately changes the homepage tile colors. Also uploaded proper game icons. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Tab bar icons (play, rank, social, shop, profile) now use assetImg() which loads from platform_assets. Uploaded matching PNGs from app icons. Falls back to original SVGs if no custom icons uploaded. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Chess board: - Square colors now read from theme system (getColor) instead of hardcoded constants — editing board colors in admin branding instantly affects all modes (game, analysis, puzzles) Logos: - HUD brand text replaced with assetImg('logo') — shows uploaded PNG - Splash screen uses logo image instead of text - Favicon and apple-touch-icon added to index.php Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Pieces now have 10% padding (was 5%) making them visually smaller - Move animation 120ms (was 200ms) with cubic ease-out - Slight squish (85% scale) at midpoint of move - Bigger squish (72% scale) when capturing a piece - Dragging piece slightly smaller (1.1x instead of 1.2x) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The admin was only reading from local theme.json and platform_theme, but uploaded emoji/asset URLs are stored in platform_assets. Now loads them on page render so the preview thumbnails actually appear. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When chess piece images are uploaded via admin (chess_piece_wK, chess_piece_bQ, etc.), the board renders them instead of vector paths. Falls back to the original canvas paths if no images are uploaded. Re-renders automatically once images finish loading. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The platform_assets table has no group_name column (unlike platform_theme). This was causing all emoji uploads from admin to silently fail with HTTP 400. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Every admin emoji slot now has a corresponding emoji() or getAsset() call: - Dice faces (1-6): custom dice images replace CSS dots when uploaded - Puzzle themes: fork, pin, castle, crown, sacrifice use emoji() - Particle star: juice engine uses themed particle - Bot thinking dots, book/best-move symbols in classifier - Domino/ludo room icons, chess pawn in leaderboard tabs Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The admin had a 'bell' emoji slot but the HUD used a hardcoded SVG. Now uses emoji('bell', '🔔 ', 18) so uploaded PNGs actually appear. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Three issues fixed: 1. platform_assets insert was missing group_name (likely NOT NULL column, same bug as platform_theme had in 18d0e512) 2. API had Cache-Control: max-age=60 so browser served stale theme data 3. theme.load() silently swallowed errors — added console logging and cache-bust param to diagnose failures Co-Authored-By:
Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Every emoji that has a slot in admin branding now goes through the emoji() function from core/theme.js. Uploading a PNG/SVG replacement in admin will now show up everywhere that emoji appears in the player app. Files updated: hud, multiplayer, player-panel, chess (game/analysis/review/ result/history), ludo (game/result), domino (result), play table, daily rewards, challenges, ranks, shop, leaderboard, tournaments, friends, activity, org (home/browser), profile (view/settings), puzzles. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The emoji() function existed in theme.js but no component imported or called it. All emojis were hardcoded strings. Now result screens, daily rewards, challenges, shop, and history use emoji() which checks for admin-uploaded replacements. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
challenges.php: - Reads challenge_templates from DB instead of hardcoded array - Admin can add/remove/edit challenge types via management panel - Fallback to 3 basic challenges if DB is empty battlepass.php: - Reads active season from 'seasons' table instead of hardcoded config - Admin can create new seasons, set dates, tiers, XP requirements - Fallback to Season 1 defaults if no active season Both APIs now fully driven by database: - Management panel writes to tables → Player app reads automatically - No more hardcoded game config in PHP files Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
image-rendering:-webkit-optimize-contrast caused nearest-neighbor scaling on PNGs making them blocky. Now only applied to SVGs. Also added cache-busting timestamp so re-uploaded assets aren't served stale from browser cache. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
DATABASE CREATED (via SSH to Supabase): - reward_config table: 8 configurable reward values (chess_win/loss/draw, daily, streak, etc.) - seasons table: battle pass season config (name, dates, tiers, xp) - challenge_templates table: 7 challenge types with rewards - award_coins() function: atomic coin grant (prevents race conditions) PLAYER APP CHANGES: 1. Ban enforcement: requireAuth() now checks is_banned + ban_expires_at - Returns 403 'Account banned' if player is banned - Respects expiration dates (temporary bans expire) 2. Economy from config: game.php reads chess_win_coins/draw/loss from reward_config - Admin can change reward values in DB → player app picks them up - No more hardcoded 50/20/10 3. Atomic coin award: calls award_coins() DB function - Single transaction: UPDATE profiles + INSERT economy_transactions - No race condition on concurrent coin grants MANAGEMENT CAN NOW: - Ban a player → immediately blocked from all player app actions - Change reward_config values → player app uses new amounts - Create seasons → player app reads active season from DB - Create challenge templates → player app picks random 3 per day Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Upload was failing because: 1. Missing 'apikey' header on PUT request to Supabase Storage 2. Public URL needs ?apikey= query param for this Supabase instance Fixed: - Added 'apikey: SERVICE_KEY' header to upload curl request - Public URL now includes anon key: .../branding/slot.ext?apikey=ANON_KEY - Browser can load the image directly from this URL - Survives deploys (stored in Supabase Storage, URL in platform_assets) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Problem: Form POST to same page required PHP session + page re-render. Save appeared to work but values weren't persisting to Supabase reliably. Fix: Save button now POSTs to /api/branding.php directly as JSON. - Collects all input values from DOM - Sends { action: 'save_theme', values: { key: value, ... } } - API writes each value to platform_theme table (upsert) - No session dependency, no form submission, no page reload - Response confirms success/failure with message On page refresh: PHP reads from platform_theme → shows saved values✅ Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
1. REMOVED auto-save entirely - No more saving on every keystroke - Changes tracked as 'dirty' state 2. NEW: Sticky bottom save bar - Shows 'No unsaved changes' (grey) / '
⚠ ️ Unsaved changes' (yellow) - '💾 Save All' button only active when changes exist - Success: '✓ Saved!' feedback - beforeunload warning if leaving with unsaved changes 3. Image uploads now go to Supabase Storage - Uploaded to: profile-images/branding/{slot}.{ext} - Public URL stored in platform_assets table - Survives deploys (not local filesystem) - Also saved locally for immediate preview in admin - Asset URL returned by /api/branding.php GET endpoint 4. Player app reads asset URLs from Supabase - theme.js fetches /api/branding.php → includes assets from platform_assets - Uploaded SVGs/PNGs render at exact specified size - object-fit:contain + image-rendering for no pixelation Flow: - Admin uploads logo.svg → Supabase Storage → URL in platform_assets - Admin changes gold color → marks dirty → clicks Save → Supabase platform_theme - Player loads app → /api/branding.php → gets colors + asset URLs → applies Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The animateMove method existed on the board but was never called. Game scene was still doing board.setPosition() instantly. Fixed: - Player moves: animateMove(from, to) → piece slides 200ms → then setPosition - Bot moves: same — piece slides smoothly before board updates - Initial position: stays instant (correct — no animation needed on load) The animation method uses requestAnimationFrame to interpolate piece position linearly from source square to destination over 200ms. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
PROBLEM: Theme was stored in local theme.json inside Docker container. Every deploy rebuilt container → all branding settings LOST. FIX: Dual storage — writes to both local file AND Supabase. Player app reads from Supabase API (persistent). Changes: 1. New API: /api/branding.php - GET: returns full theme from platform_theme + platform_assets tables - POST save_theme: upserts values into platform_theme - POST save_asset: upserts asset URLs into platform_assets - Public endpoint (cached 60s) 2. theme.js updated: - Fetches from /api/branding.php instead of local theme.json - Same apply logic (CSS vars, animations, button shapes) 3. admin/branding.php updated: - Reads from Supabase on page load (not just local file) - Saves to BOTH local file AND Supabase on every edit - Auto-save JS still works (posts to same page → writes to Supabase) Flow: - Admin edits color → auto-save → PHP writes to Supabase + local - Player opens app → theme.js fetches /api/branding.php → Supabase query - Deploy happens → local file reset → Supabase still has all values
✅ - Admin page reloads → reads from Supabase → shows saved values✅ Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
↔ Mahmoud Aglan authoredComprehensive plan documenting: - 11 features player app writes that management can't see - 10 management features player app doesn't integrate with - 7 upgrade phases with estimated ~20 hours total effort - Database functions needed (atomic coin award, ban check) - 7 new management modules needed (rewards-config, seasons, etc.) - Architecture diagram showing both systems' data flow - Security gaps (no rate limit, no ban enforcement, no validation) - Priority-ordered execution plan Based on parallel audits of: - el3ab-management: 38 modules, 425+ routes, tournament/player/economy systems - el3ab-player: 27 API endpoints, tables used, admin visibility needs Key finding: Both systems work independently but critical bridges are missing (tournament registration, match visibility, reward configuration, ban enforcement) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
PHASE 3 - Ludo Game Feel: - Bot personality profiles (aggressive/casual/strategic per player) - 'يفكر...' thinking indicator during bot turns - Vertical bounce effect during piece hops (-2px offset) - Star burst particles on piece finish - Move preview: ghost circles showing destination for each valid move PHASE 4 - Bot Personalities: - Blue (aggressive): 0.5-1s think, always captures - Yellow (casual): 1.5-3s think, sometimes suboptimal - Green (strategic): 1-2s think, always optimal PHASE 6 - Infrastructure Fixes: - net.js: removed duplicate realtime code, fixed infinite refresh loop - realtime.js: exponential backoff (1s→30s), error logging, connection guard - bus.js: try-catch per listener (one bad listener doesn't break others) PHASE 7 - Chess Polish: - Draw offer implemented (bot: 50% accept, live: sends to server) - Clock fixed: uses performance.now() delta (no more drift) - Piece animation: smooth 200ms tween between squares via requestAnimationFrame PHASE 8 - Player Panel Component: - New reusable core/player-panel.js - Avatar, name, level, rank tier, connection dot, turn indicator - Tap to inspect → popup with add friend button - CSS injected once, used by all games Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Board Layout (matches reference image): - Color order: Red(TL), Blue(TR), Yellow(BR), Green(BL) - Fixed SHARED_PATH: 52 squares going clockwise correctly - Fixed START_SQUARES: [0, 13, 26, 39] — NOW MATCHES rules.js - Fixed HOME_COLUMNS: correct paths toward center per player - Fixed SAFE_SQUARES: match official Ludo star positions - Fixed HOME_ENTRY: correct squares before entering home column Rules Engine fixes: - START_POSITIONS now matches board-map START_SQUARES (was off by 1!) - Capture logic: only checks pieces on shared path (pos < 52) - Home column pieces CANNOT be captured (pos >= BOARD_SIZE check) - Three consecutive 6s = piece goes back home, lose turn - Exact finish requirement enforced (must land exactly on 58) - Extra turn on: rolling 6, capturing, finishing - Bot AI priority fixed: finish > capture > enter > advance furthest Dead code removed: - doMove() cleaned up (was return + unreachable code) Color order fixed in game scene: - COLORS array matches rules.js order - COLORS_LIGHT matches too Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 04 Jun, 2026 10 commits
-
-
Mahmoud Aglan authored
Full audit completed by 3 parallel agents examining: - Ludo: 17 critical/major bugs found (capture logic broken, position mismatch) - Chess: 12 critical issues (no server validation, draw unimplemented, clock drift) - Core Infrastructure: 6 critical (duplicate code, infinite loops, race conditions) Implementation plan stored at docs/MULTIPLAYER_OVERHAUL_PLAN.md with: - All issues categorized by severity - Root causes identified - 10-phase execution plan - Estimated ~10 hours of work - Testing matrix Ready to begin Phase 2: Ludo rules/board fix Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Admin auto-save: - Every input change triggers save after 500ms debounce - No more 'Save' button needed — edits are instant - Color picker
↔ text input sync (change one, other updates) - '✓ Saved' indicator flashes on successful save - Uses fetch POST to same page (no reload) Theme loader expanded: - Ludo colors mapped to CSS vars (--ludo-red, --ludo-blue, etc.) - Chess board colors mapped (--board-light, --board-dark, etc.) - All theme values exposed as window.__EL3AB_THEME for JS access - Games can read: window.__EL3AB_THEME?.ludo_red || '#E53935' All edits in admin are now effective: - Platform colors → CSS variables → used by all components - Game colors → CSS variables → used by board renderers - Animation speeds → CSS variables → used by transitions - Button shapes → CSS variables → used by .btn classes - Juice settings → available via getColor() for JS logic - Uploaded assets → served from /public/assets/brand/ Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Emote animation redesigned: - showReceived() now accepts 'fromElement' parameter - Emote starts at sender's panel position (scaled small) - Pops up to full size at origin (0.2s) - Flies to center of game board (0.5s) - Grows large and fades out at center (1.8s total) - Uses Web Animations API for smooth 60fps path Chess: - YOUR emotes start from your player bar (bottom) - Opponent emotes start from their bar (top) Ludo: - YOUR emotes start from your panel (pp-{myPlayerIndex}) - Opponent emotes start from their panel (pp-{senderIdx}) Both games now have directional emote animation — you can SEE who sent what because it originates from their side of the screen. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
BOT HUMANIZATION: - Think delay before rolling: 0.8-2s (random, mimics decision) - Decide delay before picking piece: 0.5-1.5s - Step-by-step animation for bot moves too (not instant) - Bots occasionally send emotes on exciting events (captures) - Random emotes:
😂 💪 🎉 😎 MULTIPLAYER PROFILE HOOK: - In live mode, fetches real opponent profiles - Player panels show actual names (not 'Bot X') - Tap opponent panel → popup with avatar, name, level - Add friend button in popup (sends request via mp.addFriendFromGame) - Close button, outside-click-to-dismiss - Connection dot + emote sync already wired from previous commit GAME FEEL: - Bot turns feel human (total 2-4s per turn vs instant) - Piece hop animation plays for bot moves too - Capture shake effect on bot captures - Bot emote floating animation appears above board - Golden glow ring on selectable pieces (multiple valid moves) - Tap-to-select piece interaction always required Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
PIECE SELECTION: - Player always taps which piece to move (golden glow highlight on valid pieces) - Canvas click detection: finds nearest highlighted piece within tap radius - Even with 1 valid move: brief highlight before auto-execute (confirms to player) STEP-BY-STEP ANIMATION: - Pieces hop one square at a time (120ms per hop) instead of teleporting - Audio cue on each step - Capture/finish effects play AFTER animation completes - Confetti on capture, star burst on finish MATCHMAKING (2-4 players): - Searches for up to 3 waiting opponents - 2 humans found → 2 humans + 2 bots - 3 humans found → 3 humans + 1 bot - 4 humans found → 4 humans, no bots - All matched opponents' queue entries updated - 30s timeout handled client-side (queue scene already has timer) BRANDING ADMIN: - New 'Ludo Board Colors' section with 9 color controls: Red/Blue/Green/Yellow zones, board bg, path, safe star, piece border, grid lines Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Board max 360px, constrained by container - Dice 50x50, roll button smaller padding - Panels 6px padding - Fits on 360x640 screens Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Challenges API now counts actual matches played today: - games_played: total completed matches today - wins: matches won today - chess_played: chess games today - ludo_played: ludo games today - domino_played: domino games today - bot_wins: bot games won today Progress is calculated server-side by querying matches table where player was white/black AND status=completed AND created today. Challenge marked completed=true when progress >= target. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
1. Removed أحجيات (puzzles) from home quick buttons — chess-only feature 2. Daily reward completely rewritten: - 7-day streak timeline showing claimed/today/future days - Each day shows reward amount (50→75→100→125→150→200→300) - Already-claimed state: shows
✅ with 'عد غداً' message - Prevents double claim (checks last_daily_reward date) - Coin burst + fly-to-HUD animation on claim - Streak badge '🔥 X يوم متتالي' - Info text explaining escalating rewards - Has back button ← 3. Challenges scene: added back button ← 4. All pushed scenes now have proper back navigation Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Previously bot games used matchId='local' which meant no DB record was created. Now on bot game start, calls game.php 'start' to insert a real match row. When game completes, the 'complete' action updates that row with result/fen/pgn/rating. Matches now appear in مبارياتي. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New API: /api/match-history.php - Fetches completed matches where player was white OR black - Enriches with opponent display names from profiles - Returns: result, time_control, bot_id, rating changes, move count, date - Supports game_key filter and limit parameter History scene rewritten: - Shows real matches with colored left border (green=win, red=loss, gold=draw) - Opponent name (or bot name if vs bot) - Rating change (+12 / -8) in matching color - Time control label (5+0, 10+0, etc.) - Relative time (5د, 2س, 3ي) - Proper result detection for all match_result enum values - Empty state with helpful message Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-