An highly extensible online multiplayer card game platform built on PocketBase.
"Everything is an Object" - In this platform, all game concepts (rules, tables, players, games, every action) are database records.
- Rules as Configuration: Game rules are stored as data - add new games by creating records
- Event Sourcing: Every game action is recorded for anti-cheat, reconnection, and replay
- State Machine Driven: Table status (waiting, playing, finished) drives game flow
- Pluggable Game Engine: Different game rules via JavaScript logic files
- Backend: PocketBase (Go)
- JavaScript Engine: goja (for game logic execution)
- Database: SQLite (PocketBase built-in)
- Real-time: PocketBase Realtime API
# Build
go build -o cardgames
# Run
./cardgames serve
# Access
# - API: http://localhost:8090
# - Admin UI: http://localhost:8090/_/# Using Docker Compose
docker-compose up -d
# Or build image manually
docker build -t cardgames:latest .
docker run -d -p 8090:8090 -v cardgames-data:/app/pb_data cardgames:latestSee DOCKER_GUIDE.md for detailed Docker deployment instructions.
For Users:
For Developers:
- GAME_RULE_GUIDE.md - How to create new games ⭐
- FRONTEND_GUIDE.md - How to integrate frontend ⭐
- DEVELOPMENT.md - Development guide
- DOCKER_GUIDE.md - Docker deployment guide
- ROADMAP.md - Future improvements
The platform supports different game categories:
-
Mahjong-like Games (麻将类)
- Turn-based with multiple response options
- Example: Four Color Card
- See:
game_logics/four_color_card.js
-
Poker-like Games (扑克类)
- Betting rounds and card rankings
- Coming soon
-
Trick-taking Games (打牌类)
- Trick-based play
- Coming soon
-
Read the guide: GAME_RULE_GUIDE.md
-
Create game logic file in
game_logics/mygame.js:
function initializeGame(config, playerIds) {
// Initialize game state
return { player_hands: {}, deck: [], ... };
}
function validatePlay_cards(config, gameState, playerId, actionData) {
// Validate action
return { valid: true, message: "Valid" };
}
function applyPlay_cards(config, gameState, playerId, actionData) {
// Apply action to state
return newGameState;
}-
Create game rule in admin UI with:
- Name, description
- logic_file: "mygame.js"
- config_json: game configuration
-
Test your game by creating a table and playing!
See FRONTEND_GUIDE.md for complete frontend integration guide.
Quick example:
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://localhost:8090');
// Login
await pb.collection('users').authWithPassword(email, password);
// Create table
const table = await pb.collection('tables').create({
name: 'My Game',
rule: ruleId,
owner: pb.authStore.model.id,
status: 'waiting'
});
// Subscribe to updates
pb.collection('game_actions').subscribe('*', (data) => {
console.log('New action:', data.record);
});- Extensibility: Add games without modifying core code
- Event Sourcing: Complete audit trail and replay capability
- Security: Proper authentication and authorization
- Real-time: Instant updates via WebSocket subscriptions
See LICENSE file.
一个基于 PocketBase 构建的高度可扩展的在线多人卡牌游戏平台。
"万物皆对象" - 在这个平台中,所有游戏概念(规则、牌桌、玩家、牌局、每一次出牌)都是数据库中的一个记录。
- 规则即配置: 游戏规则作为数据存储,添加新游戏只需创建新记录
- 事件溯源: 每个游戏动作都被记录,支持防作弊、断线重连、游戏复盘
- 状态机驱动: 牌桌状态(等待中、游戏中、已结束)驱动游戏流程
- 可插拔游戏引擎: 通过 JavaScript 逻辑文件实现不同游戏规则
- 后端: PocketBase (Go)
- JavaScript引擎: goja (用于游戏逻辑执行)
- 数据库: SQLite (PocketBase 内置)
- 实时通信: PocketBase Realtime API
# 构建
go build -o cardgames
# 运行
./cardgames serve
# 访问
# - API: http://localhost:8090
# - 管理界面: http://localhost:8090/_/# 使用 Docker Compose
docker-compose up -d
# 或手动构建镜像
docker build -t cardgames:latest .
docker run -d -p 8090:8090 -v cardgames-data:/app/pb_data cardgames:latest详细的 Docker 部署说明请参见 DOCKER_GUIDE.md。
用户文档:
开发者文档:
- GAME_RULE_GUIDE.md - 如何创建新游戏 ⭐
- FRONTEND_GUIDE.md - 如何集成前端 ⭐
- DEVELOPMENT.md - 开发指南
- DOCKER_GUIDE.md - Docker 部署指南
- ROADMAP.md - 未来改进计划
平台支持不同的游戏分类:
-
麻将类游戏
- 回合制,多种响应选项
- 示例:四色牌
- 参见:
game_logics/four_color_card.js
-
扑克类游戏
- 下注轮次和牌型排名
- 即将推出
-
打牌类游戏
- 基于墩的玩法
- 即将推出
-
阅读指南:GAME_RULE_GUIDE.md
-
在
game_logics/mygame.js中创建游戏逻辑文件:
function initializeGame(config, playerIds) {
// 初始化游戏状态
return { player_hands: {}, deck: [], ... };
}
function validatePlay_cards(config, gameState, playerId, actionData) {
// 验证动作
return { valid: true, message: "有效" };
}
function applyPlay_cards(config, gameState, playerId, actionData) {
// 将动作应用到状态
return newGameState;
}-
在管理界面创建游戏规则,包括:
- 名称、描述
- logic_file: "mygame.js"
- config_json: 游戏配置
-
通过创建牌桌来测试你的游戏!
完整的前端集成指南请参见 FRONTEND_GUIDE.md。
快速示例:
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://localhost:8090');
// 登录
await pb.collection('users').authWithPassword(email, password);
// 创建牌桌
const table = await pb.collection('tables').create({
name: '我的游戏',
rule: ruleId,
owner: pb.authStore.model.id,
status: 'waiting'
});
// 订阅更新
pb.collection('game_actions').subscribe('*', (data) => {
console.log('新动作:', data.record);
});- 可扩展性: 添加游戏无需修改核心代码
- 事件溯源: 完整的审计跟踪和重播能力
- 安全性: 适当的身份验证和授权
- 实时性: 通过 WebSocket 订阅实现即时更新
请参见 LICENSE 文件。
定义游戏的玩法和配置。
| 字段 | 类型 | 说明 |
|---|---|---|
| name | Text | 游戏名称 |
| description | Text | 游戏描述 |
| config_json | JSON | 游戏配置(牌堆、初始手牌、计分规则等) |
| logic_file | Text | JavaScript 逻辑文件名 |
游戏控制器,管理玩家和游戏生命周期。
| 字段 | 类型 | 说明 |
|---|---|---|
| name | Text | 牌桌名称 |
| rule | Relation | 关联的游戏规则 |
| owner | Relation | 牌桌创建者 |
| status | Select | waiting/playing/finished |
| players | Relation (multiple) | 玩家列表 |
| player_states | JSON | 玩家状态(准备、分数等) |
| current_game | Relation | 当前游戏状态 |
| is_private | Bool | 是否私密房间 |
| password | Text | 房间密码 |
存储某一局游戏的实时快照。
| 字段 | 类型 | 说明 |
|---|---|---|
| table | Relation | 所属牌桌 |
| round_number | Number | 第几局 |
| current_player_turn | Relation | 当前玩家 |
| player_hands | JSON | 所有玩家的手牌 |
| deck | JSON | 牌堆中剩余的牌 |
| discard_pile | JSON | 弃牌堆 |
| last_play | JSON | 上一次出牌信息 |
| player_melds | JSON | 玩家已公示的牌组 |
| game_specific_data | JSON | 游戏特有状态 |
事件溯源的核心,记录每一步操作。
| 字段 | 类型 | 说明 |
|---|---|---|
| table | Relation | 动作发生的牌桌 |
| game_state | Relation | 游戏状态 |
| player | Relation | 执行动作的玩家 |
| sequence_number | Number | 动作序号 |
| action_type | Select | 动作类型 |
| action_data | JSON | 动作数据 |
- Go 1.21 或更高版本
- 克隆仓库:
git clone https://github.com/frog-software/CardGames.git
cd CardGames- 安装依赖:
go mod download- 构建项目:
go build -o cardgames./cardgames serve服务器将在 http://127.0.0.1:8090 启动。
- 打开浏览器访问
http://127.0.0.1:8090/_/ - 首次访问时,创建管理员账户
- 登录后可以查看和管理所有集合
POST /api/collections/users/auth-with-password- 用户登录POST /api/collections/users/records- 用户注册
GET /api/collections/game_rules/records- 获取所有可用游戏规则GET /api/collections/tables/records- 获取所有公开的牌桌POST /api/collections/tables/records- 创建新牌桌
示例创建牌桌:
{
"name": "Test Game",
"rule": "RULE_ID",
"owner": "USER_ID",
"status": "waiting",
"is_private": false
}使用 PocketBase SDK 订阅集合更新:
// 订阅特定牌桌的游戏动作
pb.collection('game_actions').subscribe('*', function (e) {
console.log('New action:', e.record);
}, { filter: 'table = "TABLE_ID"' });-
在
game_logics/目录下创建新的 JavaScript 文件 -
实现必需的函数:
initializeGame(config, playerIds)- 初始化游戏状态validatePlay_cards(config, gameState, playerId, actionData)- 验证出牌applyPlay_cards(config, gameState, playerId, actionData)- 应用出牌动作- 其他游戏特定的验证和应用函数
-
在
game_rules集合中创建新记录,指定逻辑文件名
项目已包含完整的四色牌游戏实现:
- 逻辑文件:
game_logics/four_color_card.js - 自动初始化的游戏规则记录
支持的动作:
play_cards- 出牌chi- 吃牌peng- 碰牌kai- 开牌(第四张)hu- 胡牌draw- 抓牌pass- 跳过
只需要:
- 编写游戏逻辑 JavaScript 文件
- 创建
game_rules记录 - 无需修改核心代码
大部分修改只需编辑 config_json 字段,无需修改代码。
前端可以使用任何框架(Vue、React、Svelte 等):
- 使用 PocketBase SDK 连接后端
- 订阅实时更新
- 发送 API 请求执行操作
- PocketBase 集合设计
- 基础数据结构
- 牌桌管理基础功能
- JavaScript 逻辑执行框架
- 完整的游戏逻辑实现
- 所有动作验证函数
- 游戏状态管理
- 完善的 API 端点实现
- 完整的游戏流程测试
- 计分和结算逻辑优化
- Web 前端界面
- 多游戏支持
欢迎提交 Pull Request 或创建 Issue!
详见 LICENSE 文件。