The Game Center is a modular gaming platform built with React, TypeScript, and Supabase. It consists of two main components:
games table: Stores game metadata
id: Unique identifiername: Display nameslug: URL-friendly identifieractive: Game availability statuslast_accessed: Timestamp of last settings updategame_settings table: Stores configurable game parameters
game_id: Reference to games tablekey: Setting identifiervalue: JSON object containing:
type: “number” |
“color” |
value: Current valuemin: Minimum value (for numbers)max: Maximum value (for numbers)step: Increment size (for numbers)description: Setting descriptionversion: Setting version for change trackinghigh_scores table: Stores player achievements
user_id: Player identifierscore: Numeric scoreusername: Player display nameCreate a new migration file in supabase/migrations/ with:
-- Add game entry
INSERT INTO games (name, slug)
VALUES ('Game Name', 'game-slug');
-- Add game settings
INSERT INTO game_settings (game_id, key, value, description)
SELECT
games.id,
settings.key,
settings.value::jsonb,
settings.description
FROM games
CROSS JOIN (
VALUES
(
'settingKey',
'{"type": "number", "value": 1, "min": 0, "max": 10, "step": 1}',
'Setting description'
)
) AS settings(key, value, description)
WHERE games.slug = 'game-slug';
Create a new directory in src/games/your-game/ with:
your-game/
├── Game.tsx # Main game component
├── components/ # Game-specific components
│ ├── Player.tsx
│ └── ...
└── types.ts # Game-specific types
Your main Game component must:
Example structure:
export function YourGame() {
// Settings state
const [settings, setSettings] = useState(DEFAULT_SETTINGS);
// Game state
const [gameStarted, setGameStarted] = useState(false);
const [gameOver, setGameOver] = useState(false);
const [score, setScore] = useState(0);
// Load settings
useEffect(() => {
loadSettings();
}, []);
// Game loop
useEffect(() => {
if (gameStarted && !gameOver) {
const gameLoop = () => {
// Update game state
requestAnimationFrame(gameLoop);
};
requestAnimationFrame(gameLoop);
}
}, [gameStarted, gameOver]);
return (
<div className="game-container">
{/* Game UI */}
</div>
);
}
Add your game to the game selection screen in src/App.tsx:
<button
onClick={() => setCurrentGame('your-game')}
className="game-button"
>
<h2>Your Game</h2>
<p>Game description</p>
</button>
Each setting must include:
Before deployment:
const DEFAULT_SETTINGS = {
playerSpeed: {
type: 'number',
value: 5,
min: 1,
max: 10,
step: 0.5
},
backgroundColor: {
type: 'color',
value: '#4ade80'
}
};
The system automatically deploys through Netlify:
//admin