Commit 4ffe25d5 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat: Phase 7.4/7.5 — extract magic numbers to config, remove dead code

- Created core/config.js with SUPABASE_URL, STOCKFISH_URL, DEFAULT_RATING
- login.js, register.js, realtime.js now import from shared config
- chess/game.js and bot-select.js use STOCKFISH_URL constant
- multiplayer.js uses DEFAULT_RATING from config
- ludo/game.js: named TURBO_SPEED constant
- table.js: removed dead `disabled = false` code path
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent c13254bc
export const SUPABASE_URL = 'https://safe-supabase-kong.caprover.al-arcade.com';
export const STOCKFISH_URL = 'https://stockfishapi.caprover.al-arcade.com';
export const DEFAULT_RATING = 1200;
......@@ -8,6 +8,7 @@ import * as juice from './juice.js';
import * as scene from './scene.js';
import * as modal from './modal.js';
import { emoji } from './theme.js';
import { DEFAULT_RATING } from './config.js';
import { t } from './i18n.js';
let currentMatchId = null;
......@@ -34,7 +35,7 @@ export function renderOpponentBar(container, opponent, options = {}) {
</div>
<div style="flex:1;">
<div style="font-size:13px;font-weight:600;color:var(--text-primary);">${opponent.display_name || opponent.username || t('common.opponent')}</div>
${showRating ? `<div style="font-size:11px;color:var(--text-muted);">${emoji('star', '⭐', 11)} ${opponent.rating || opponent.elo_rapid || '1200'}</div>` : ''}
${showRating ? `<div style="font-size:11px;color:var(--text-muted);">${emoji('star', '⭐', 11)} ${opponent.rating || opponent.elo_rapid || DEFAULT_RATING}</div>` : ''}
</div>
<div id="mp-opponent-status" style="font-size:10px;color:var(--text-muted);"></div>
`;
......
// Supabase Realtime — subscribe to table row changes
// Used for live multiplayer in Chess and Ludo
const REALTIME_URL = 'wss://safe-supabase-kong.caprover.al-arcade.com/realtime/v1/websocket';
const ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzM1Njg5NjAwLCJleHAiOjE4OTM0NTYwMDB9.31PF6PvP-pSrvRuQwLFptQoejR0W1A7o53lZhEbnz84';
import * as store from './store.js';
import { SUPABASE_URL } from './config.js';
const REALTIME_URL = SUPABASE_URL.replace('https://', 'wss://') + '/realtime/v1/websocket';
const ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzM1Njg5NjAwLCJleHAiOjE4OTM0NTYwMDB9.31PF6PvP-pSrvRuQwLFptQoejR0W1A7o53lZhEbnz84';
let ws = null;
let heartbeatInterval = null;
......
......@@ -5,8 +5,7 @@ import * as net from '../../../core/net.js';
import * as audio from '../../../core/audio.js';
import { t } from '../../../core/i18n.js';
import { assetImg } from '../../../core/theme.js';
const SUPABASE_URL = 'https://safe-supabase-kong.caprover.al-arcade.com';
import { SUPABASE_URL } from '../../../core/config.js';
export function mountLogin(el) {
el.innerHTML = `
......
......@@ -4,8 +4,7 @@ import * as scene from '../../../core/scene.js';
import * as net from '../../../core/net.js';
import * as audio from '../../../core/audio.js';
import { t } from '../../../core/i18n.js';
const SUPABASE_URL = 'https://safe-supabase-kong.caprover.al-arcade.com';
import { SUPABASE_URL } from '../../../core/config.js';
export function mountRegister(el) {
el.innerHTML = `
......
......@@ -14,6 +14,7 @@ import * as emoteSystem from '../components/emotes.js';
import * as mp from '../../../core/multiplayer.js';
import * as modal from '../../../core/modal.js';
import { emoji } from '../../../core/theme.js';
import { STOCKFISH_URL } from '../../../core/config.js';
import * as matchLive from '../../../core/match-live.js';
let board, clock, gameState;
......@@ -106,7 +107,7 @@ export function mountGame(el, params) {
<div class="chess-bar" style="display:flex;align-items:center;justify-content:space-between;padding:8px 14px;background:var(--bg-surface);">
<div style="display:flex;align-items:center;gap:10px;">
<div id="opponent-avatar" style="width:36px;height:36px;border-radius:50%;background:var(--bg-elevated);display:flex;align-items:center;justify-content:center;overflow:hidden;border:2px solid ${mode === 'bot' ? 'var(--text-muted)' : 'var(--blue)'};">
${mode === 'bot' ? `<img src="https://stockfishapi.caprover.al-arcade.com/portraits/${botId || 'amina'}.png" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';this.parentNode.innerHTML='${emoji('robot', '🤖', 16)}'">` : `<span style="font-size:16px;">${emoji('person', '👤', 16)}</span>`}
${mode === 'bot' ? `<img src="${STOCKFISH_URL}/portraits/${botId || 'amina'}.png" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';this.parentNode.innerHTML='${emoji('robot', '🤖', 16)}'">` : `<span style="font-size:16px;">${emoji('person', '👤', 16)}</span>`}
</div>
<div>
<div style="font-size:13px;font-weight:600;color:var(--text-primary);" id="opponent-name">${mode === 'bot' ? (botId || t('game.bot')) : t('game.loading_opponent')}</div>
......
......@@ -46,6 +46,7 @@ let turnTimer = null;
let turnTimerStart = 0;
let livePlayerIds = [];
const TURN_TIMEOUT = 15000;
const TURBO_SPEED = 0.4;
function renderPanel(p) {
return `
......@@ -379,7 +380,7 @@ async function botLoop(el) {
const personality = personalities[game.currentPlayer] || personalities[1];
// === BOT HUMANIZATION: delays that mimic real player ===
const turboMul = game.turboMode ? 0.4 : 1;
const turboMul = game.turboMode ? TURBO_SPEED : 1;
const thinkDelay = (personality.thinkMin + Math.random() * (personality.thinkMax - personality.thinkMin)) * turboMul;
const botPanel = el.querySelector(`#pp-${game.currentPlayer}`);
......
......@@ -2,6 +2,7 @@ import * as scene from '../../../core/scene.js';
import * as audio from '../../../core/audio.js';
import * as net from '../../../core/net.js';
import { t } from '../../../core/i18n.js';
import { STOCKFISH_URL } from '../../../core/config.js';
const DIFFICULTY_COLORS = ['var(--success)', 'var(--success)', 'var(--amber)', 'var(--amber)', 'var(--orange)', 'var(--orange)', 'var(--error)'];
......@@ -44,7 +45,7 @@ function renderBots(el, bots, params) {
<div class="card bot-card" data-id="${bot.id}" style="cursor:pointer;padding:var(--s-3);position:relative;overflow:hidden;">
<div style="position:absolute;top:0;left:0;right:0;height:var(--bot-card-accent-height);background:${diffColor};"></div>
<div style="width:var(--bot-card-avatar-size);height:var(--bot-card-avatar-size);border-radius:var(--r-full);background:var(--bg-elevated);margin:var(--s-2) auto var(--s-2);display:flex;align-items:center;justify-content:center;font-size:20px;overflow:hidden;border:var(--bot-card-avatar-border) solid ${diffColor};">
${bot.portrait_url ? `<img src="https://stockfishapi.caprover.al-arcade.com${bot.portrait_url}" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';this.parentNode.querySelector('.bot-fallback').style.display='flex'"><span class="bot-fallback" style="display:none;font-size:22px;font-weight:800;color:${diffColor};">${initial}</span>` : `<span style="font-size:22px;font-weight:800;color:${diffColor};">${initial}</span>`}
${bot.portrait_url ? `<img src="${STOCKFISH_URL}${bot.portrait_url}" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';this.parentNode.querySelector('.bot-fallback').style.display='flex'"><span class="bot-fallback" style="display:none;font-size:22px;font-weight:800;color:${diffColor};">${initial}</span>` : `<span style="font-size:22px;font-weight:800;color:${diffColor};">${initial}</span>`}
</div>
<div style="text-align:center;">
<div style="font-size:var(--bot-card-name-font);font-weight:700;">${bot.name_ar || bot.name}</div>
......
......@@ -56,14 +56,12 @@ export function mountTable(el) {
<!-- Games -->
<div class="games-grid">
${games.map(g => {
const disabled = false;
return `
<div class="game-tile ${disabled ? 'game-tile-disabled' : ''}" data-game="${g.key}" style="--game-color:${g.color};--game-gradient:${g.gradient};">
<div class="game-tile" data-game="${g.key}" style="--game-color:${g.color};--game-gradient:${g.gradient};">
<div class="game-tile-bg" style="background:${g.gradient};"></div>
<div class="game-tile-content">
<div class="game-tile-icon">${assetImg(g.key + '_icon', g.icon, 48, 48)}</div>
<div class="game-tile-name">${g.name}</div>
${disabled ? `<div class="game-tile-soon">${t('play.coming_soon')}</div>` : ''}
</div>
</div>`;
}).join('')}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment