From 9500c4c80a718073530fdbc05ef96609f93c9292 Mon Sep 17 00:00:00 2001 From: xyou Date: Fri, 7 Aug 2026 23:39:47 +0800 Subject: [PATCH] FIRST --- .github/workflows/ci.yml | 33 + .gitignore | 73 + .trae/documents/initialize-mrcc-project.md | 206 ++ Makefile | 41 + .../Scripts/RedCircuit.Audio/AudioManager.cs | 9 + .../Scripts/RedCircuit.Audio/NotePlayer.cs | 9 + .../RedCircuit.Audio/RedCircuit.Audio.asmdef | 10 + .../Scripts/RedCircuit.Auth/AuthManager.cs | 9 + .../Scripts/RedCircuit.Auth/OAuthClient.cs | 9 + .../RedCircuit.Auth/RedCircuit.Auth.asmdef | 10 + .../Scripts/RedCircuit.Auth/TokenStore.cs | 9 + .../RedCircuit.Components/ComponentData.cs | 18 + .../ComponentRegistry.cs | 9 + .../PlacementController.cs | 9 + .../RedCircuit.Components.asmdef | 10 + .../Scripts/RedCircuit.Grid/ChunkManager.cs | 9 + .../Scripts/RedCircuit.Grid/GridCanvas.cs | 9 + .../RedCircuit.Grid/RedCircuit.Grid.asmdef | 10 + .../Scripts/RedCircuit.Grid/TileRenderer.cs | 9 + .../Scripts/RedCircuit.Net/ApiClient.cs | 9 + .../RedCircuit.Net/RedCircuit.Net.asmdef | 10 + .../Scripts/RedCircuit.Net/SyncManager.cs | 9 + .../Assets/Scripts/RedCircuit.Net/WsClient.cs | 9 + .../Scripts/RedCircuit.Save/CloudSync.cs | 9 + .../Scripts/RedCircuit.Save/LocalDatabase.cs | 9 + .../RedCircuit.Save/RedCircuit.Save.asmdef | 10 + .../Scripts/RedCircuit.Save/SaveManager.cs | 9 + .../ComponentBehavior.cs | 9 + .../RedCircuit.Simulation.asmdef | 10 + .../RedCircuit.Simulation/SignalPropagator.cs | 9 + .../RedCircuit.Simulation/SimulationLoop.cs | 9 + .../Scripts/RedCircuit.UI/EditorWindow.cs | 9 + .../Scripts/RedCircuit.UI/InspectorPanel.cs | 9 + .../Scripts/RedCircuit.UI/PalettePanel.cs | 9 + .../RedCircuit.UI/RedCircuit.UI.asmdef | 10 + .../RedCircuit.UI/ToolbarController.cs | 9 + client/Packages/manifest.json | 33 + client/ProjectSettings/ProjectVersion.txt | 2 + docker-compose.dev.yml | 80 + server/Makefile | 31 + server/cmd/auth-service/main.go | 26 + server/cmd/blueprint-service/main.go | 27 + server/cmd/economy-service/main.go | 27 + server/cmd/match-service/main.go | 27 + server/cmd/relay-server/main.go | 167 ++ server/cmd/social-service/main.go | 28 + server/go.mod | 37 + server/internal/config/config.go | 58 + server/internal/httpserver/server.go | 60 + server/internal/logger/logger.go | 26 + server/pkg/response/response.go | 27 + 完整开发文档.html | 2487 +++++++++++++++++ 52 files changed, 3801 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .trae/documents/initialize-mrcc-project.md create mode 100644 Makefile create mode 100644 client/Assets/Scripts/RedCircuit.Audio/AudioManager.cs create mode 100644 client/Assets/Scripts/RedCircuit.Audio/NotePlayer.cs create mode 100644 client/Assets/Scripts/RedCircuit.Audio/RedCircuit.Audio.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Auth/AuthManager.cs create mode 100644 client/Assets/Scripts/RedCircuit.Auth/OAuthClient.cs create mode 100644 client/Assets/Scripts/RedCircuit.Auth/RedCircuit.Auth.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Auth/TokenStore.cs create mode 100644 client/Assets/Scripts/RedCircuit.Components/ComponentData.cs create mode 100644 client/Assets/Scripts/RedCircuit.Components/ComponentRegistry.cs create mode 100644 client/Assets/Scripts/RedCircuit.Components/PlacementController.cs create mode 100644 client/Assets/Scripts/RedCircuit.Components/RedCircuit.Components.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Grid/ChunkManager.cs create mode 100644 client/Assets/Scripts/RedCircuit.Grid/GridCanvas.cs create mode 100644 client/Assets/Scripts/RedCircuit.Grid/RedCircuit.Grid.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Grid/TileRenderer.cs create mode 100644 client/Assets/Scripts/RedCircuit.Net/ApiClient.cs create mode 100644 client/Assets/Scripts/RedCircuit.Net/RedCircuit.Net.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Net/SyncManager.cs create mode 100644 client/Assets/Scripts/RedCircuit.Net/WsClient.cs create mode 100644 client/Assets/Scripts/RedCircuit.Save/CloudSync.cs create mode 100644 client/Assets/Scripts/RedCircuit.Save/LocalDatabase.cs create mode 100644 client/Assets/Scripts/RedCircuit.Save/RedCircuit.Save.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Save/SaveManager.cs create mode 100644 client/Assets/Scripts/RedCircuit.Simulation/ComponentBehavior.cs create mode 100644 client/Assets/Scripts/RedCircuit.Simulation/RedCircuit.Simulation.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.Simulation/SignalPropagator.cs create mode 100644 client/Assets/Scripts/RedCircuit.Simulation/SimulationLoop.cs create mode 100644 client/Assets/Scripts/RedCircuit.UI/EditorWindow.cs create mode 100644 client/Assets/Scripts/RedCircuit.UI/InspectorPanel.cs create mode 100644 client/Assets/Scripts/RedCircuit.UI/PalettePanel.cs create mode 100644 client/Assets/Scripts/RedCircuit.UI/RedCircuit.UI.asmdef create mode 100644 client/Assets/Scripts/RedCircuit.UI/ToolbarController.cs create mode 100644 client/Packages/manifest.json create mode 100644 client/ProjectSettings/ProjectVersion.txt create mode 100644 docker-compose.dev.yml create mode 100644 server/Makefile create mode 100644 server/cmd/auth-service/main.go create mode 100644 server/cmd/blueprint-service/main.go create mode 100644 server/cmd/economy-service/main.go create mode 100644 server/cmd/match-service/main.go create mode 100644 server/cmd/relay-server/main.go create mode 100644 server/cmd/social-service/main.go create mode 100644 server/go.mod create mode 100644 server/internal/config/config.go create mode 100644 server/internal/httpserver/server.go create mode 100644 server/internal/logger/logger.go create mode 100644 server/pkg/response/response.go create mode 100644 完整开发文档.html diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a838b1f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + backend: + name: Go Backend + runs-on: ubuntu-latest + defaults: + run: + working-directory: server + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + + - name: Download dependencies + run: go mod download + + - name: Build + run: go build ./cmd/... + + - name: Vet + run: go vet ./... + + - name: Test + run: go test ./... -race -cover diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fdcc3b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +# ===================== Go ===================== +# Binaries +*.exe +*.exe~ +*.dll +*.so +*.dylib +server/bin/ + +# Test binary & coverage +*.test +*.out +*.prof + +# Go workspace +go.work +go.work.sum + +# Environment +.env +*.env.local + +# ===================== Unity ===================== +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ +client/Assets/AssetStoreTools* +client/Assets/Plugins/Editor/JetBrains* + +# Visual Studio / Rider cache +.vs/ +.idea/ + +# Autogenerated solution & project files +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity meta for generated +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity crash report +sysinfo.txt + +# Builds +*.apk +*.aab +*.unitypackage + +# ===================== OS ===================== +.DS_Store +Thumbs.db +desktop.ini + +# ===================== Docker ===================== +docker-compose.override.yml diff --git a/.trae/documents/initialize-mrcc-project.md b/.trae/documents/initialize-mrcc-project.md new file mode 100644 index 0000000..2e1d0dc --- /dev/null +++ b/.trae/documents/initialize-mrcc-project.md @@ -0,0 +1,206 @@ +# 初始化 MRCC 项目 + +## Summary + +将 MRCC (MineRedCircuitcraft) 从空目录初始化为完整的 monorepo 骨架,包含 Unity 客户端和 Go 后端(6 个服务),每个服务具备 `/health` 健康检查端点并可独立启动。对应开发文档 Sprint 1 的交付目标。 + +## Current State Analysis + +| 项目 | 状态 | +|------|------| +| Git 仓库 | 已初始化,main 分支,remote: `dcp.itnet.buzz/Deaicup/MRCC` | +| 现有文件 | `README.md`、`完整开发文档.html` | +| Go | **未安装** | +| Docker | **未安装** | +| Unity CLI | 不在 PATH 中(可能已安装 Editor) | + +开发文档定义的技术栈: +- 客户端: Unity 2024 LTS (C#),8 个模块 +- 后端: Go 1.22 + Gin,5 个业务微服务 + 1 个联机中转站 +- 基础设施: PostgreSQL 16、Redis 7.2、MinIO、RabbitMQ 3.13 + +## Prerequisites + +执行前需安装(可通过 dev-env-expert 辅助): +1. **Go 1.22+** — 后端编译运行 +2. **Docker Desktop** — 开发环境基础设施(PostgreSQL/Redis/MinIO/RabbitMQ) +3. **Unity 2024 LTS** — 客户端打开编辑 + +> 骨架代码可先创建,Go 安装后即可 `go run` 启动后端。 + +## Proposed Changes + +### 1. 根目录文件 (4 files) + +| 文件 | 内容 | +|------|------| +| `.gitignore` | Go + Unity + IDE 忽略规则合并 | +| `docker-compose.dev.yml` | PostgreSQL 16、Redis 7.2、MinIO、RabbitMQ 3.13 开发环境 | +| `Makefile` | 根目录快捷命令:`make dev`(启动基础设施)、`make build-all`、`make run-*` | +| `.github/workflows/ci.yml` | Go build + vet + test;PR 触发 | + +### 2. Go 后端 (`server/`) + +**Module path**: `mrcc` + +``` +server/ +├── go.mod # module mrcc, go 1.22, deps: gin, gorilla/websocket +├── Makefile # build / run-* / tidy / lint / test +├── cmd/ +│ ├── auth-service/main.go # :8081, /health +│ ├── economy-service/main.go # :8082, /health +│ ├── blueprint-service/main.go # :8083, /health +│ ├── match-service/main.go # :8084, /health +│ ├── social-service/main.go # :8085, /health +│ └── relay-server/main.go # :8086, /health + /ws WebSocket 骨架 +├── internal/ +│ ├── config/config.go # 环境变量加载,ServiceConfig 结构体 +│ ├── logger/logger.go # slog 封装,统一日志格式 +│ └── httpserver/server.go # Gin 实例工厂:CORS、Recovery、日志中间件、/health 注册 +└── pkg/ + └── response/response.go # 标准 JSON 响应 {code, message, data} +``` + +**每个业务微服务 main.go 模式**(以 auth-service 为例): +```go +package main + +import ( + "log" + "mrcc/internal/config" + "mrcc/internal/httpserver" +) + +func main() { + cfg := config.Load("auth-service", "8081") + srv := httpserver.New(cfg) + log.Printf("auth-service listening on :%s", cfg.Port) + if err := srv.Run(":" + cfg.Port); err != nil { + log.Fatal(err) + } +} +``` + +**relay-server 额外内容**: +- `/ws` WebSocket 升级端点(gorilla/websocket) +- `Room`、`Player` 结构体定义(对照文档 18.5 节) +- 连接注册/注销 channel 骨架(不实现完整逻辑) + +**go.mod 依赖**(最小化): +- `github.com/gin-gonic/gin v1.10.0` +- `github.com/gorilla/websocket v1.5.3` + +### 3. Unity 客户端 (`client/`) + +``` +client/ +├── Assets/ +│ └── Scripts/ +│ ├── RedCircuit.Grid/ # RedCircuit.Grid.asmdef +│ │ ├── GridCanvas.cs # 网格画布渲染 +│ │ ├── ChunkManager.cs # 分块管理 +│ │ └── TileRenderer.cs # 瓦片渲染 +│ ├── RedCircuit.Simulation/ # RedCircuit.Simulation.asmdef +│ │ ├── SimulationLoop.cs # 仿真主循环 +│ │ ├── SignalPropagator.cs # 信号传播 +│ │ └── ComponentBehavior.cs # 元件行为基类 +│ ├── RedCircuit.Components/ # RedCircuit.Components.asmdef +│ │ ├── ComponentRegistry.cs # 元件注册表 +│ │ ├── PlacementController.cs # 放置控制器 +│ │ └── ComponentData.cs # 元件数据定义 +│ ├── RedCircuit.UI/ # RedCircuit.UI.asmdef +│ │ ├── EditorWindow.cs # 编辑器窗口 +│ │ ├── ToolbarController.cs # 工具栏 +│ │ ├── PalettePanel.cs # 元件面板 +│ │ └── InspectorPanel.cs # 属性面板 +│ ├── RedCircuit.Net/ # RedCircuit.Net.asmdef +│ │ ├── ApiClient.cs # REST 客户端 +│ │ ├── WsClient.cs # WebSocket 客户端 +│ │ └── SyncManager.cs # 同步管理 +│ ├── RedCircuit.Save/ # RedCircuit.Save.asmdef +│ │ ├── SaveManager.cs # 存档管理 +│ │ ├── LocalDatabase.cs # 本地 SQLite +│ │ └── CloudSync.cs # 云端同步 +│ ├── RedCircuit.Audio/ # RedCircuit.Audio.asmdef +│ │ ├── AudioManager.cs # 音频管理 +│ │ └── NotePlayer.cs # 音符播放 +│ └── RedCircuit.Auth/ # RedCircuit.Auth.asmdef +│ ├── AuthManager.cs # 认证管理 +│ ├── TokenStore.cs # Token 存储 +│ └── OAuthClient.cs # OAuth 客户端 +├── Packages/ +│ └── manifest.json # Unity 2024 LTS 基础包 +└── ProjectSettings/ + └── ProjectVersion.txt # 2024.2.0f1 +``` + +**每个 C# 脚本模式**(空骨架): +```csharp +using UnityEngine; + +namespace RedCircuit.Grid +{ + /// 网格画布渲染器,负责 PCB 风格网格绘制与视口裁剪。 + public class GridCanvas : MonoBehaviour + { + } +} +``` + +**Assembly Definition (asmdef) 模式**: +```json +{ + "name": "RedCircuit.Grid", + "rootNamespace": "RedCircuit.Grid", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} +``` + +### 4. 文件清单汇总 + +| 区域 | 文件数 | +|------|--------| +| 根目录 | 4 | +| server/ (Go) | 16 (go.mod, Makefile, 6×main.go, 4×internal, 1×pkg) | +| client/ (Unity) | 29 (8×asmdef, 24×cs, manifest.json, ProjectVersion.txt) | +| **合计** | **~49 files** | + +## Assumptions & Decisions + +1. **端口分配**: relay-server 使用 8086(文档中 8084 与 match-service 冲突,调整为 8086) +2. **Go module path**: 使用 `mrcc`(简单私有项目名,可后续改为 VCS URL) +3. **日志**: 使用标准库 `log/slog`,不引入 zap(最小化依赖) +4. **数据库连接**: 骨架阶段不连接实际数据库,docker-compose 仅供后续 Sprint 使用 +5. **Unity 场景**: 不手动创建 .unity 场景文件(格式复杂且版本相关),用户在 Unity Editor 中新建 +6. **.meta 文件**: 不创建 Unity .meta 文件,Unity Editor 首次打开自动生成 +7. **CI**: 仅 Go 后端 CI(Unity CI 需要 Unity License,后续 Sprint 再加) + +## Verification Steps + +1. **Go 后端编译**: + ```powershell + cd server; go mod tidy; go build ./cmd/... + ``` +2. **各服务启动 + 健康检查**: + ```powershell + go run ./cmd/auth-service & + curl http://localhost:8081/health # 期望 {"code":0,"message":"ok"} + # 对 8082-8086 重复 + ``` +3. **relay-server WebSocket**: + ```powershell + # 连接 ws://localhost:8086/ws 应成功升级 + ``` +4. **Unity 客户端**: + - 用 Unity Hub 打开 `client/` 文件夹 + - 无编译错误,8 个 asmdef 程序集均编译通过 +5. **Git 提交**: + ```powershell + git add -A; git status # 确认无敏感文件 + ``` diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..14e70b2 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +.PHONY: dev build-all run-auth run-economy run-blueprint run-match run-social run-relay tidy lint test + +# 启动开发环境基础设施 +dev: + docker compose -f docker-compose.dev.yml up -d + +dev-down: + docker compose -f docker-compose.dev.yml down + +# 后端:构建所有服务 +build-all: + cd server && go build ./cmd/... + +# 后端:运行单个服务 +run-auth: + cd server && go run ./cmd/auth-service + +run-economy: + cd server && go run ./cmd/economy-service + +run-blueprint: + cd server && go run ./cmd/blueprint-service + +run-match: + cd server && go run ./cmd/match-service + +run-social: + cd server && go run ./cmd/social-service + +run-relay: + cd server && go run ./cmd/relay-server + +# 后端:工具 +tidy: + cd server && go mod tidy + +lint: + cd server && go vet ./... + +test: + cd server && go test ./... diff --git a/client/Assets/Scripts/RedCircuit.Audio/AudioManager.cs b/client/Assets/Scripts/RedCircuit.Audio/AudioManager.cs new file mode 100644 index 0000000..42ecaf4 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Audio/AudioManager.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Audio +{ + /// 音频管理器,统一管理 BGM、UI 音效与游戏内音效播放。 + public class AudioManager : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Audio/NotePlayer.cs b/client/Assets/Scripts/RedCircuit.Audio/NotePlayer.cs new file mode 100644 index 0000000..a9c096e --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Audio/NotePlayer.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Audio +{ + /// 音符播放器,驱动音符盒与蜂鸣器,支持频率随信号强度变化。 + public class NotePlayer : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Audio/RedCircuit.Audio.asmdef b/client/Assets/Scripts/RedCircuit.Audio/RedCircuit.Audio.asmdef new file mode 100644 index 0000000..e551f30 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Audio/RedCircuit.Audio.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Audio", + "rootNamespace": "RedCircuit.Audio", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Auth/AuthManager.cs b/client/Assets/Scripts/RedCircuit.Auth/AuthManager.cs new file mode 100644 index 0000000..c02fb61 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Auth/AuthManager.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Auth +{ + /// 认证管理器,处理注册、登录、Token 刷新与会话管理。 + public class AuthManager : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Auth/OAuthClient.cs b/client/Assets/Scripts/RedCircuit.Auth/OAuthClient.cs new file mode 100644 index 0000000..64670c2 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Auth/OAuthClient.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Auth +{ + /// OAuth 客户端,支持 Google / GitHub / Discord 第三方快捷登录。 + public class OAuthClient : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Auth/RedCircuit.Auth.asmdef b/client/Assets/Scripts/RedCircuit.Auth/RedCircuit.Auth.asmdef new file mode 100644 index 0000000..ed9803f --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Auth/RedCircuit.Auth.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Auth", + "rootNamespace": "RedCircuit.Auth", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Auth/TokenStore.cs b/client/Assets/Scripts/RedCircuit.Auth/TokenStore.cs new file mode 100644 index 0000000..53f874c --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Auth/TokenStore.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Auth +{ + /// Token 存储,安全保存 Access Token 与 Refresh Token,支持自动刷新。 + public class TokenStore : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Components/ComponentData.cs b/client/Assets/Scripts/RedCircuit.Components/ComponentData.cs new file mode 100644 index 0000000..40277eb --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Components/ComponentData.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace RedCircuit.Components +{ + /// 元件数据定义,描述元件类型、朝向、可调属性与通电状态。 + [Serializable] + public class ComponentData + { + public string id; + public string type; + public int x; + public int y; + public int rotation; + public Dictionary properties = new(); + public bool isPowered; + } +} diff --git a/client/Assets/Scripts/RedCircuit.Components/ComponentRegistry.cs b/client/Assets/Scripts/RedCircuit.Components/ComponentRegistry.cs new file mode 100644 index 0000000..303efeb --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Components/ComponentRegistry.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Components +{ + /// 元件注册表,管理 80 种元件的数据定义与图标映射。 + public class ComponentRegistry : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Components/PlacementController.cs b/client/Assets/Scripts/RedCircuit.Components/PlacementController.cs new file mode 100644 index 0000000..31bb3aa --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Components/PlacementController.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Components +{ + /// 放置控制器,处理元件拖放放置、删除、旋转操作。 + public class PlacementController : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Components/RedCircuit.Components.asmdef b/client/Assets/Scripts/RedCircuit.Components/RedCircuit.Components.asmdef new file mode 100644 index 0000000..d114d91 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Components/RedCircuit.Components.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Components", + "rootNamespace": "RedCircuit.Components", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Grid/ChunkManager.cs b/client/Assets/Scripts/RedCircuit.Grid/ChunkManager.cs new file mode 100644 index 0000000..c909c4f --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Grid/ChunkManager.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Grid +{ + /// 分块管理器,将画布按 16x16 分 Chunk,仅实例化视口内 Chunk。 + public class ChunkManager : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Grid/GridCanvas.cs b/client/Assets/Scripts/RedCircuit.Grid/GridCanvas.cs new file mode 100644 index 0000000..ef1f74d --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Grid/GridCanvas.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Grid +{ + /// 网格画布渲染器,负责 PCB 风格网格绘制与视口裁剪。 + public class GridCanvas : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Grid/RedCircuit.Grid.asmdef b/client/Assets/Scripts/RedCircuit.Grid/RedCircuit.Grid.asmdef new file mode 100644 index 0000000..94af62b --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Grid/RedCircuit.Grid.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Grid", + "rootNamespace": "RedCircuit.Grid", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Grid/TileRenderer.cs b/client/Assets/Scripts/RedCircuit.Grid/TileRenderer.cs new file mode 100644 index 0000000..e216e13 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Grid/TileRenderer.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Grid +{ + /// 瓦片渲染器,负责单个元件方块的 GPU Instancing 批量绘制。 + public class TileRenderer : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Net/ApiClient.cs b/client/Assets/Scripts/RedCircuit.Net/ApiClient.cs new file mode 100644 index 0000000..76b222e --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Net/ApiClient.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Net +{ + /// REST API 客户端,封装用户认证、商店、蓝图等 HTTP 请求。 + public class ApiClient : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Net/RedCircuit.Net.asmdef b/client/Assets/Scripts/RedCircuit.Net/RedCircuit.Net.asmdef new file mode 100644 index 0000000..137c54c --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Net/RedCircuit.Net.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Net", + "rootNamespace": "RedCircuit.Net", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Net/SyncManager.cs b/client/Assets/Scripts/RedCircuit.Net/SyncManager.cs new file mode 100644 index 0000000..d4f4c5e --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Net/SyncManager.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Net +{ + /// 同步管理器,处理多人协作模式下的电路增量 Delta 同步与冲突解决。 + public class SyncManager : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Net/WsClient.cs b/client/Assets/Scripts/RedCircuit.Net/WsClient.cs new file mode 100644 index 0000000..e936e84 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Net/WsClient.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Net +{ + /// WebSocket 客户端,维持与 relay-server 的长连接,处理实时消息收发。 + public class WsClient : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Save/CloudSync.cs b/client/Assets/Scripts/RedCircuit.Save/CloudSync.cs new file mode 100644 index 0000000..1d738ed --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Save/CloudSync.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Save +{ + /// 云端同步,将本地存档与蓝图同步至服务端,支持冲突合并。 + public class CloudSync : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Save/LocalDatabase.cs b/client/Assets/Scripts/RedCircuit.Save/LocalDatabase.cs new file mode 100644 index 0000000..fe2cadc --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Save/LocalDatabase.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Save +{ + /// 本地数据库,基于 SQLite 存储存档、蓝图与设置,支持离线缓存。 + public class LocalDatabase : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Save/RedCircuit.Save.asmdef b/client/Assets/Scripts/RedCircuit.Save/RedCircuit.Save.asmdef new file mode 100644 index 0000000..bf751e8 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Save/RedCircuit.Save.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Save", + "rootNamespace": "RedCircuit.Save", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Save/SaveManager.cs b/client/Assets/Scripts/RedCircuit.Save/SaveManager.cs new file mode 100644 index 0000000..fac6324 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Save/SaveManager.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Save +{ + /// 存档管理器,管理电路存档的创建、保存、加载与删除。 + public class SaveManager : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Simulation/ComponentBehavior.cs b/client/Assets/Scripts/RedCircuit.Simulation/ComponentBehavior.cs new file mode 100644 index 0000000..9dfe711 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Simulation/ComponentBehavior.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Simulation +{ + /// 元件行为基类,定义元件接收信号后的规则接口。 + public abstract class ComponentBehavior : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Simulation/RedCircuit.Simulation.asmdef b/client/Assets/Scripts/RedCircuit.Simulation/RedCircuit.Simulation.asmdef new file mode 100644 index 0000000..66c5998 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Simulation/RedCircuit.Simulation.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.Simulation", + "rootNamespace": "RedCircuit.Simulation", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.Simulation/SignalPropagator.cs b/client/Assets/Scripts/RedCircuit.Simulation/SignalPropagator.cs new file mode 100644 index 0000000..078144c --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Simulation/SignalPropagator.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Simulation +{ + /// 信号传播器,基于优先级队列 BFS 实现红石信号强度衰减传播。 + public class SignalPropagator : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.Simulation/SimulationLoop.cs b/client/Assets/Scripts/RedCircuit.Simulation/SimulationLoop.cs new file mode 100644 index 0000000..0abf4e0 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.Simulation/SimulationLoop.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.Simulation +{ + /// 仿真主循环,每 Tick 执行信号收集、BFS 传播、元件规则、延迟处理、输出更新。 + public class SimulationLoop : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.UI/EditorWindow.cs b/client/Assets/Scripts/RedCircuit.UI/EditorWindow.cs new file mode 100644 index 0000000..fa64f17 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.UI/EditorWindow.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.UI +{ + /// 编辑器主窗口,管理画布、工具栏、面板的整体布局与生命周期。 + public class EditorWindow : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.UI/InspectorPanel.cs b/client/Assets/Scripts/RedCircuit.UI/InspectorPanel.cs new file mode 100644 index 0000000..8e66f3c --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.UI/InspectorPanel.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.UI +{ + /// 属性面板,显示并编辑选中元件的可调属性(延迟、阻值、模式等)。 + public class InspectorPanel : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.UI/PalettePanel.cs b/client/Assets/Scripts/RedCircuit.UI/PalettePanel.cs new file mode 100644 index 0000000..c87f890 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.UI/PalettePanel.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.UI +{ + /// 元件面板,按 8 大分类展示 80 种元件供玩家选择放置。 + public class PalettePanel : MonoBehaviour + { + } +} diff --git a/client/Assets/Scripts/RedCircuit.UI/RedCircuit.UI.asmdef b/client/Assets/Scripts/RedCircuit.UI/RedCircuit.UI.asmdef new file mode 100644 index 0000000..1d06264 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.UI/RedCircuit.UI.asmdef @@ -0,0 +1,10 @@ +{ + "name": "RedCircuit.UI", + "rootNamespace": "RedCircuit.UI", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "autoReferenced": true, + "defineConstraints": [] +} diff --git a/client/Assets/Scripts/RedCircuit.UI/ToolbarController.cs b/client/Assets/Scripts/RedCircuit.UI/ToolbarController.cs new file mode 100644 index 0000000..18bfac0 --- /dev/null +++ b/client/Assets/Scripts/RedCircuit.UI/ToolbarController.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace RedCircuit.UI +{ + /// 工具栏控制器,管理保存/加载/运行/暂停按钮与模式切换。 + public class ToolbarController : MonoBehaviour + { + } +} diff --git a/client/Packages/manifest.json b/client/Packages/manifest.json new file mode 100644 index 0000000..8335103 --- /dev/null +++ b/client/Packages/manifest.json @@ -0,0 +1,33 @@ +{ + "dependencies": { + "com.unity.2d.sprite": "1.0.0", + "com.unity.2d.tilemap": "1.0.0", + "com.unity.ide.visualstudio": "2.0.22", + "com.unity.ide.rider": "3.0.28", + "com.unity.test-framework": "1.1.33", + "com.unity.ugui": "2.0.0", + "com.unity.ui": "2.0.0", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0" + } +} diff --git a/client/ProjectSettings/ProjectVersion.txt b/client/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..a52c0e2 --- /dev/null +++ b/client/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2024.2.0f1 +m_EditorVersionWithRevision: 2024.2.0f1 (0000000000000) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..c62c672 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,80 @@ +version: "3.9" + +# MRCC 开发环境基础设施 +# 使用: docker compose -f docker-compose.dev.yml up -d + +services: + postgres: + image: postgres:16-alpine + container_name: mrcc-postgres + restart: unless-stopped + environment: + POSTGRES_USER: mrcc + POSTGRES_PASSWORD: mrcc_dev_2026 + POSTGRES_DB: mrcc + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U mrcc"] + interval: 5s + timeout: 3s + retries: 5 + + redis: + image: redis:7.2-alpine + container_name: mrcc-redis + restart: unless-stopped + ports: + - "6379:6379" + volumes: + - redisdata:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 5 + + minio: + image: minio/minio:latest + container_name: mrcc-minio + restart: unless-stopped + command: server /data --console-address ":9001" + environment: + MINIO_ROOT_USER: mrcc + MINIO_ROOT_PASSWORD: mrcc_dev_2026 + ports: + - "9000:9000" + - "9001:9001" + volumes: + - miniodata:/data + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 10s + timeout: 5s + retries: 3 + + rabbitmq: + image: rabbitmq:3.13-management-alpine + container_name: mrcc-rabbitmq + restart: unless-stopped + environment: + RABBITMQ_DEFAULT_USER: mrcc + RABBITMQ_DEFAULT_PASS: mrcc_dev_2026 + ports: + - "5672:5672" + - "15672:15672" + volumes: + - rabbitmqdata:/var/lib/rabbitmq + healthcheck: + test: ["CMD", "rabbitmq-diagnostics", "ping"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + pgdata: + redisdata: + miniodata: + rabbitmqdata: diff --git a/server/Makefile b/server/Makefile new file mode 100644 index 0000000..2e72aa8 --- /dev/null +++ b/server/Makefile @@ -0,0 +1,31 @@ +.PHONY: build run-auth run-economy run-blueprint run-match run-social run-relay tidy lint test + +build: + go build ./cmd/... + +run-auth: + go run ./cmd/auth-service + +run-economy: + go run ./cmd/economy-service + +run-blueprint: + go run ./cmd/blueprint-service + +run-match: + go run ./cmd/match-service + +run-social: + go run ./cmd/social-service + +run-relay: + go run ./cmd/relay-server + +tidy: + go mod tidy + +lint: + go vet ./... + +test: + go test ./... diff --git a/server/cmd/auth-service/main.go b/server/cmd/auth-service/main.go new file mode 100644 index 0000000..9b11b02 --- /dev/null +++ b/server/cmd/auth-service/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "log" + + "mrcc/internal/config" + "mrcc/internal/httpserver" + "mrcc/internal/logger" +) + +func main() { + cfg := config.Load("auth-service", "8081") + logger.WithService(cfg.Name).Info("starting service", "port", cfg.Port) + + srv := httpserver.New(cfg) + + // TODO: 注册认证路由 + // r := srv.Group("/api/auth") + // r.POST("/register", ...) + // r.POST("/login", ...) + + log.Printf("auth-service listening on %s", cfg.Address()) + if err := srv.Run(cfg.Address()); err != nil { + log.Fatal(err) + } +} diff --git a/server/cmd/blueprint-service/main.go b/server/cmd/blueprint-service/main.go new file mode 100644 index 0000000..5c0d78c --- /dev/null +++ b/server/cmd/blueprint-service/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "log" + + "mrcc/internal/config" + "mrcc/internal/httpserver" + "mrcc/internal/logger" +) + +func main() { + cfg := config.Load("blueprint-service", "8083") + logger.WithService(cfg.Name).Info("starting service", "port", cfg.Port) + + srv := httpserver.New(cfg) + + // TODO: 注册蓝图路由 + // r := srv.Group("/api/blueprints") + // r.GET("/", ...) + // r.POST("/", ...) + // r.POST("/:id/buy", ...) + + log.Printf("blueprint-service listening on %s", cfg.Address()) + if err := srv.Run(cfg.Address()); err != nil { + log.Fatal(err) + } +} diff --git a/server/cmd/economy-service/main.go b/server/cmd/economy-service/main.go new file mode 100644 index 0000000..6e16511 --- /dev/null +++ b/server/cmd/economy-service/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "log" + + "mrcc/internal/config" + "mrcc/internal/httpserver" + "mrcc/internal/logger" +) + +func main() { + cfg := config.Load("economy-service", "8082") + logger.WithService(cfg.Name).Info("starting service", "port", cfg.Port) + + srv := httpserver.New(cfg) + + // TODO: 注册经济路由 + // r := srv.Group("/api/user") + // r.GET("/balance", ...) + // r := srv.Group("/api/shop") + // r.GET("/items", ...) + + log.Printf("economy-service listening on %s", cfg.Address()) + if err := srv.Run(cfg.Address()); err != nil { + log.Fatal(err) + } +} diff --git a/server/cmd/match-service/main.go b/server/cmd/match-service/main.go new file mode 100644 index 0000000..ed1f11b --- /dev/null +++ b/server/cmd/match-service/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "log" + + "mrcc/internal/config" + "mrcc/internal/httpserver" + "mrcc/internal/logger" +) + +func main() { + cfg := config.Load("match-service", "8084") + logger.WithService(cfg.Name).Info("starting service", "port", cfg.Port) + + srv := httpserver.New(cfg) + + // TODO: 注册匹配路由 + // r := srv.Group("/api/multiplayer") + // r.POST("/match", ...) + // r.POST("/join", ...) + // r.POST("/result", ...) + + log.Printf("match-service listening on %s", cfg.Address()) + if err := srv.Run(cfg.Address()); err != nil { + log.Fatal(err) + } +} diff --git a/server/cmd/relay-server/main.go b/server/cmd/relay-server/main.go new file mode 100644 index 0000000..0b317ef --- /dev/null +++ b/server/cmd/relay-server/main.go @@ -0,0 +1,167 @@ +package main + +import ( + "log" + "net/http" + "sync" + "time" + + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + + "mrcc/internal/config" + "mrcc/internal/httpserver" + "mrcc/internal/logger" + "mrcc/pkg/response" +) + +// === 数据结构骨架(对照开发文档 18.5 节)=== + +type RoomStatus string + +const ( + RoomCreated RoomStatus = "created" + RoomWaiting RoomStatus = "waiting" + RoomPlaying RoomStatus = "playing" + RoomFinished RoomStatus = "finished" +) + +// Player 玩家连接 +type Player struct { + UserID string `json:"user_id"` + Username string `json:"username"` + Conn *websocket.Conn `json:"-"` + IsReady bool `json:"is_ready"` + JoinedAt time.Time `json:"joined_at"` + SendQueue chan []byte `json:"-"` +} + +// Room 房间 +type Room struct { + ID string `json:"id"` + Status RoomStatus `json:"status"` + HostUserID string `json:"host_user_id"` + MaxPlayers int `json:"max_players"` + Players map[string]*Player `json:"players"` + CreatedAt time.Time `json:"created_at"` + mu sync.RWMutex `json:"-"` +} + +// RelayServer 中转服务器 +type RelayServer struct { + Rooms map[string]*Room + Players map[string]*Player + Register chan *Player + Unregister chan *Player + mu sync.RWMutex +} + +func NewRelayServer() *RelayServer { + return &RelayServer{ + Rooms: make(map[string]*Room), + Players: make(map[string]*Player), + Register: make(chan *Player, 64), + Unregister: make(chan *Player, 64), + } +} + +var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true // 开发阶段允许所有来源 + }, +} + +// HandleWS 处理 WebSocket 连接升级 +func HandleWS(relay *RelayServer) gin.HandlerFunc { + return func(c *gin.Context) { + userID := c.Query("user_id") + if userID == "" { + userID = "anonymous" + } + + conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + log.Printf("websocket upgrade failed: %v", err) + return + } + + player := &Player{ + UserID: userID, + Conn: conn, + JoinedAt: time.Now(), + SendQueue: make(chan []byte, 256), + } + + relay.Register <- player + + log.Printf("player connected: %s", userID) + + // TODO: 实现读写 goroutine、房间管理、消息路由、断线重连 + // 当前骨架仅保持连接并读取消息 + go func() { + defer func() { + relay.Unregister <- player + conn.Close() + }() + + for { + _, _, err := conn.ReadMessage() + if err != nil { + break + } + } + }() + } +} + +func main() { + cfg := config.Load("relay-server", "8086") + logger.WithService(cfg.Name).Info("starting relay server", "port", cfg.Port) + + relay := NewRelayServer() + + // 后台处理注册/注销 + go func() { + for { + select { + case player := <-relay.Register: + relay.mu.Lock() + relay.Players[player.UserID] = player + relay.mu.Unlock() + log.Printf("player registered: %s", player.UserID) + + case player := <-relay.Unregister: + relay.mu.Lock() + delete(relay.Players, player.UserID) + relay.mu.Unlock() + log.Printf("player unregistered: %s", player.UserID) + } + } + }() + + srv := httpserver.New(cfg) + + // WebSocket 端点 + srv.GET("/ws", HandleWS(relay)) + + // 房间信息端点(骨架) + srv.GET("/rooms", func(c *gin.Context) { + relay.mu.RLock() + defer relay.mu.RUnlock() + + rooms := make([]gin.H, 0, len(relay.Rooms)) + for id, room := range relay.Rooms { + rooms = append(rooms, gin.H{ + "id": id, + "status": room.Status, + "playerCount": len(room.Players), + }) + } + response.OK(c, gin.H{"rooms": rooms, "total": len(rooms)}) + }) + + log.Printf("relay-server listening on %s (WS: /ws)", cfg.Address()) + if err := srv.Run(cfg.Address()); err != nil { + log.Fatal(err) + } +} diff --git a/server/cmd/social-service/main.go b/server/cmd/social-service/main.go new file mode 100644 index 0000000..d104bdc --- /dev/null +++ b/server/cmd/social-service/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "log" + + "mrcc/internal/config" + "mrcc/internal/httpserver" + "mrcc/internal/logger" +) + +func main() { + cfg := config.Load("social-service", "8085") + logger.WithService(cfg.Name).Info("starting service", "port", cfg.Port) + + srv := httpserver.New(cfg) + + // TODO: 注册社交路由 + // r := srv.Group("/api/user") + // r.GET("/profile", ...) + // r.GET("/achievements", ...) + // r := srv.Group("/api/leaderboard") + // r.GET("/", ...) + + log.Printf("social-service listening on %s", cfg.Address()) + if err := srv.Run(cfg.Address()); err != nil { + log.Fatal(err) + } +} diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 0000000..5554de8 --- /dev/null +++ b/server/go.mod @@ -0,0 +1,37 @@ +module mrcc + +go 1.22 + +require ( + github.com/gin-gonic/gin v1.10.0 + github.com/gorilla/websocket v1.5.3 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/server/internal/config/config.go b/server/internal/config/config.go new file mode 100644 index 0000000..58f30d5 --- /dev/null +++ b/server/internal/config/config.go @@ -0,0 +1,58 @@ +package config + +import ( + "fmt" + "os" + "strconv" +) + +// ServiceConfig holds configuration shared across all microservices. +type ServiceConfig struct { + Name string // 服务名称,如 auth-service + Port string // 监听端口 + + // 基础设施连接(骨架阶段仅定义,暂不使用) + PostgresDSN string + RedisAddr string + MinIOAddr string + RabbitMQURL string + + // 运行环境: debug / release + GinMode string +} + +// Load 从环境变量加载配置,fallback 到默认值。 +// serviceName 和 defaultPort 用于在没有设置环境变量时提供默认值。 +func Load(serviceName, defaultPort string) *ServiceConfig { + cfg := &ServiceConfig{ + Name: serviceName, + Port: envOr("SERVICE_PORT", defaultPort), + PostgresDSN: envOr("POSTGRES_DSN", "postgres://mrcc:mrcc_dev_2026@localhost:5432/mrcc?sslmode=disable"), + RedisAddr: envOr("REDIS_ADDR", "localhost:6379"), + MinIOAddr: envOr("MINIO_ADDR", "localhost:9000"), + RabbitMQURL: envOr("RABBITMQ_URL", "amqp://mrcc:mrcc_dev_2026@localhost:5672/"), + GinMode: envOr("GIN_MODE", "debug"), + } + return cfg +} + +// Address 返回 :port 格式的监听地址 +func (c *ServiceConfig) Address() string { + return fmt.Sprintf(":%s", c.Port) +} + +func envOr(key, fallback string) string { + if v := os.Getenv(key); v != "" { + return v + } + return fallback +} + +func envIntOr(key string, fallback int) int { + if v := os.Getenv(key); v != "" { + if n, err := strconv.Atoi(v); err == nil { + return n + } + } + return fallback +} diff --git a/server/internal/httpserver/server.go b/server/internal/httpserver/server.go new file mode 100644 index 0000000..f839bd9 --- /dev/null +++ b/server/internal/httpserver/server.go @@ -0,0 +1,60 @@ +package httpserver + +import ( + "time" + + "github.com/gin-gonic/gin" + + "mrcc/internal/config" + "mrcc/pkg/response" +) + +// New 创建一个配置好中间件的 Gin 实例,并注册 /health 端点。 +func New(cfg *config.ServiceConfig) *gin.Engine { + gin.SetMode(cfg.GinMode) + + r := gin.New() + + // 中间件 + r.Use(gin.Recovery()) + r.Use(gin.LoggerWithFormatter(func(p gin.LogFormatterParams) string { + return p.TimeStamp.Format(time.RFC3339) + " | " + p.Method + " | " + p.Path + " | " + + itoa(p.StatusCode) + " | " + p.Latency.String() + "\n" + })) + + // CORS + r.Use(func(c *gin.Context) { + c.Header("Access-Control-Allow-Origin", "*") + c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization") + if c.Request.Method == "OPTIONS" { + c.AbortWithStatus(204) + return + } + c.Next() + }) + + // 健康检查 + r.GET("/health", func(c *gin.Context) { + response.OK(c, gin.H{ + "service": cfg.Name, + "status": "running", + }) + }) + + return r +} + +func itoa(n int) string { + if n == 0 { + return "0" + } + buf := [10]byte{} + pos := len(buf) + for n > 0 { + pos-- + buf[pos] = byte('0' + n%10) + n /= 10 + } + return string(buf[pos:]) +} diff --git a/server/internal/logger/logger.go b/server/internal/logger/logger.go new file mode 100644 index 0000000..391f910 --- /dev/null +++ b/server/internal/logger/logger.go @@ -0,0 +1,26 @@ +package logger + +import ( + "log/slog" + "os" +) + +// 全局默认 logger,使用 JSON handler 输出到 stdout。 +var defaultLogger *slog.Logger + +func init() { + defaultLogger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelInfo, + })) + slog.SetDefault(defaultLogger) +} + +// Default 返回全局 logger 实例 +func Default() *slog.Logger { + return defaultLogger +} + +// WithService 返回带有 service 字段的 logger +func WithService(name string) *slog.Logger { + return defaultLogger.With("service", name) +} diff --git a/server/pkg/response/response.go b/server/pkg/response/response.go new file mode 100644 index 0000000..b1dc30f --- /dev/null +++ b/server/pkg/response/response.go @@ -0,0 +1,27 @@ +package response + +import "github.com/gin-gonic/gin" + +// 标准响应结构 +// {"code": 0, "message": "ok", "data": ...} + +const codeOK = 0 +const codeError = 1 + +// OK 返回成功响应 +func OK(c *gin.Context, data any) { + c.JSON(200, gin.H{ + "code": codeOK, + "message": "ok", + "data": data, + }) +} + +// Error 返回错误响应 +func Error(c *gin.Context, httpStatus int, message string) { + c.JSON(httpStatus, gin.H{ + "code": codeError, + "message": message, + "data": nil, + }) +} diff --git a/完整开发文档.html b/完整开发文档.html new file mode 100644 index 0000000..701e388 --- /dev/null +++ b/完整开发文档.html @@ -0,0 +1,2487 @@ + + + + + + RedCircuit 红石回路 - 完整开发文档 + + + + + + + + + + +
+ + + 完整开发文档 v1.0 + + 2026-08-07 + + + 返回首页 + +
+ + + +
+
+ + +
+

01 / OVERVIEW

+

项目概述

+

RedCircuit · 红石回路是一款融合电路图、Minecraft 像素方块与红石逻辑的桌面客户端游戏,配备完整货币经济与用户体系。

+

RedCircuit 将电路图工程的严谨性、像素方块的视觉表现力与Minecraft 红石逻辑的创造性玩法结合为一款原生桌面客户端游戏。玩家在 PCB 风格的网格画布上放置元器件、搭建信号回路、解谜闯关、自动化生产,或在多人模式中与他人对战协作。游戏内置红石币与金币双货币体系,支持用户注册登录、等级成长与成就解锁。

+
+

核心定位

+
+
目标平台
Windows / macOS 桌面客户端
+
发行渠道
官网独立安装包 + 自动更新
+
目标受众
红石工程师 / 电路爱好者 / 解谜玩家
+
商业模式
免费游玩 + 内购 + 创意工坊分成
+
+
+

核心价值主张

+
+ + + + + + + + + +
维度价值主张差异化优势
玩法深度完整还原红石信号强度、衰减、延迟与 BUD 更新机制市面同类产品多简化逻辑,本作保留硬核仿真
视觉风格PCB 电路板 × 像素方块混搭美学区别于纯像素或纯电路模拟器
内容体量80 种元器件、240 个解谜关卡、4 大模式单机+联机兼顾,内容耐玩度高
经济闭环红石币产出消耗平衡 + 金币充值 + 创意工坊交易UGC 生态自循环,降低内容更新成本
社交竞技多人对战排位赛季 + 协作建造 + 蓝图分享红石领域稀缺的竞技化设计
+
+

关键指标目标

+
+ + + + + + + + + + + +
指标上线首月目标稳定期目标 (M12)说明
DAU15,00060,000日活跃用户
MAU80,000300,000月活跃用户
次日留存42%50%新手引导优化后提升
七日留存22%30%关卡内容驱动
付费率3.5%6%金币充值 + 创意工坊
ARPPU¥28¥45每付费用户平均收益
蓝图上传量2,00020,000/月UGC 生态健康度
+
+
+ + +
+

02 / ARCHITECTURE

+

技术架构

+

客户端-服务端分离架构,桌面客户端负责渲染与本地仿真,服务端负责账户、经济、联机与内容分发。

+ +

2.1 客户端架构

+

客户端基于 Unity 2024 LTS (C#) 构建,采用 2D 瓦片网格渲染器配合自定义红石信号辉光着色器。UI 层使用 Unity UI Toolkit (UXML/USS) 处理数据密集型界面(商店、背包、排行榜),编辑器画布使用 IMGUI 实现高性能即时绘制。电路仿真引擎为自定义基于 ECS 的信号传播系统,本地存储采用 SQLite 存档、蓝图与设置。

+
+ + + + + + + + + + + + +
模块技术方案职责
游戏引擎Unity 2024 LTS (C#)主循环、渲染、资源管理、跨平台打包
渲染层2D Tile 网格渲染器 + 自定义辉光 Shader方块绘制、红石信号高亮、粒子效果
UI 框架Unity UI Toolkit (UXML/USS)商店、背包、排行榜等数据界面
编辑器画布IMGUI 即时模式电路编辑画布高频重绘
仿真引擎自定义 ECS 信号传播系统红石信号强度、衰减、延迟、BUD 计算
本地存储SQLite存档、蓝图、设置、离线缓存
网络层Unity Netcode for GameObjects / Photon多人实时同步、房间管理
反作弊客户端预测 + 服务端校验多人模式经济与比赛结果验证
+
+ +

2.2 服务端架构

+

服务端采用 Go (Gin 框架) 构建 REST API 与 WebSocket 网关,按业务域拆分为五个微服务。主数据库使用 PostgreSQL 存储用户与交易数据,Redis 承担会话缓存、匹配队列与排行榜。文件存储使用 MinIO/S3 存放蓝图与回放,RabbitMQ 处理异步任务(经济结算、成就检查)。

+
+ + + + + + + + + +
微服务职责主要依赖
auth-service注册、登录、Token 签发与刷新、会话管理PostgreSQL、Redis
economy-service红石币/金币余额、交易流水、商店购买、充值核销PostgreSQL、RabbitMQ
blueprint-service蓝图上传、检索、购买、下载、评分、分类PostgreSQL、MinIO
match-service多人匹配、房间状态、对局结果、赛季排位Redis、RabbitMQ
social-service好友、聊天、公会、成就、动态PostgreSQL、Redis
+
+ +

2.3 网络协议

+
+ + + + + + + + +
协议数据格式适用场景
REST APIJSON用户认证、商店、蓝图 CRUD、排行榜查询
WebSocketJSON 帧多人实时同步、聊天、在线状态
二进制协议Protobuf电路编辑器实时协作(增量 Delta 同步)
消息队列AMQP (RabbitMQ)经济结算、成就检查等异步任务
+
+ +

2.4 系统架构图

+
+
+
桌面客户端 (Unity 2024 LTS)渲染 / 本地仿真 / 离线存档
+
+
HTTPS / WSS
+
+
API 网关 (Go / Gin)鉴权 / 路由 / 限流
+
+
gRPC / 内部调用
+
+
auth-service认证
+
economy-service经济
+
blueprint-service蓝图
+
match-service匹配
+
social-service社交
+
+
持久化 / 缓存 / 对象存储 / 异步
+
+
PostgreSQL用户 / 交易
+
Redis会话 / 排行
+
MinIO / S3蓝图 / 回放
+
RabbitMQ异步任务
+
+
+ +

分层职责总览

+
+ + + + + + + + + +
层级技术职责
表现层Unity 2024 LTS + UI Toolkit渲染、交互、本地仿真展示
网关层Go / Gin + Nginx请求路由、JWT 鉴权、限流熔断
服务层5 个 Go 微服务业务逻辑处理、事务编排
存储层PostgreSQL + Redis + MinIO持久化、缓存、对象存储
消息层RabbitMQ异步解耦、事件驱动
+
+
+ + +
+

03 / TECH STACK

+

技术栈选型

+

各技术领域的选型方案、版本、选型理由与替代方案对照。

+
+ + + + + + + + + + + + + + + + + +
领域技术选型版本选型理由替代方案
游戏引擎Unity2024 LTS生态成熟、跨平台打包、Asset Store 资源丰富、C# 开发效率高Godot 4.x
客户端语言C#12Unity 原生语言、强类型、性能优良GDScript (Godot)
UI 框架Unity UI Toolkit2.0类 Web 的 UXML/USS 体系、适合数据密集界面UGUI、IMGUI
后端语言Go1.22高并发、编译快、内存占用低、适合微服务Rust、Java
后端框架Gin1.10轻量高性能、中间件生态完善Echo、Fiber
数据库PostgreSQL16事务可靠、JSONB 支持、扩展性强MySQL、CockroachDB
缓存Redis7.2低延迟、排行榜 ZSET、会话存储Valkey、Memcached
消息队列RabbitMQ3.13可靠投递、路由灵活、异步任务解耦Kafka、NATS
文件存储MinIO / S3-兼容 S3 协议、可自托管或上云、成本低Ceph、阿里云 OSS
CI/CDGitHub Actions-与代码仓库集成、矩阵构建、自托管 RunnerGitLab CI、Jenkins
监控Prometheus + Grafana2.50 / 11指标采集可视化、告警规则灵活Datadog、Zabbix
错误追踪Sentry24客户端崩溃与服务端异常统一收集Bugsnag、Crashlytics
数据分析自建埋点 + ClickHouse24玩家行为分析、留存漏斗、低成本海量查询Mixpanel、Amplitude
+
+
+ + +
+

04 / DATABASE

+

数据库设计

+

核心实体表结构定义,字段类型、约束与说明。

+ +

users · 用户表

+
+ + + + + + + + + + + + + + + +
字段名类型约束说明
idBIGSERIALPK用户主键
usernameVARCHAR(32)UNIQUE NOT NULL用户名
emailVARCHAR(128)UNIQUE NOT NULL邮箱
password_hashVARCHAR(255)NOT NULLbcrypt 哈希
created_atTIMESTAMPTZDEFAULT NOW()注册时间
levelINTDEFAULT 1玩家等级
expINTDEFAULT 0经验值
redstone_coinsBIGINTDEFAULT 0红石币余额
gold_coinsINTDEFAULT 0金币余额
avatarVARCHAR(255)NULL头像 URL
statusSMALLINTDEFAULT 1状态 1正常 0封禁
+
+ +

circuits · 电路表

+
+ + + + + + + + + + + + + + +
字段名类型约束说明
idBIGSERIALPK电路主键
user_idBIGINTFK -> users.id所属用户
nameVARCHAR(64)NOT NULL电路名称
data_jsonJSONBNOT NULL元件布局与连线数据
grid_sizeVARCHAR(16)NOT NULL画布尺寸 如 64x64
costINTDEFAULT 0元件总成本
modeVARCHAR(16)NOT NULL模式 creative/puzzle/auto
created_atTIMESTAMPTZDEFAULT NOW()创建时间
updated_atTIMESTAMPTZDEFAULT NOW()更新时间
is_publicBOOLEANDEFAULT FALSE是否公开
+
+ +

blueprints · 蓝图表

+
+ + + + + + + + + + + + + + +
字段名类型约束说明
idBIGSERIALPK蓝图主键
circuit_idBIGINTFK -> circuits.id关联电路
author_idBIGINTFK -> users.id作者
titleVARCHAR(64)NOT NULL蓝图标题
descriptionTEXTNULL蓝图描述
priceINTDEFAULT 0售价(红石币)
download_countINTDEFAULT 0下载数
ratingNUMERIC(3,2)DEFAULT 0评分 0-5
categoryVARCHAR(32)NOT NULL分类
created_atTIMESTAMPTZDEFAULT NOW()发布时间
+
+ +

transactions · 交易流水表

+
+ + + + + + + + + + + + +
字段名类型约束说明
idBIGSERIALPK流水主键
user_idBIGINTFK -> users.id用户
typeVARCHAR(16)NOT NULL类型 earn/spend/recharge
itemVARCHAR(64)NOT NULL项目说明
amountBIGINTNOT NULL金额
currencyVARCHAR(8)NOT NULL货币 redstone/gold
balance_afterBIGINTNOT NULL交易后余额
created_atTIMESTAMPTZDEFAULT NOW()交易时间
+
+ +

puzzle_levels · 解谜关卡表

+
+ + + + + + + + + + + + + + +
字段名类型约束说明
idBIGSERIALPK关卡主键
chapterSMALLINTNOT NULL章节 1-6
level_numSMALLINTNOT NULL关卡序号
titleVARCHAR(64)NOT NULL关卡标题
descriptionTEXTNULL关卡描述
target_jsonJSONBNOT NULL通关目标条件
constraints_jsonJSONBNOT NULL限制规则
star_costSMALLINTNOT NULL成本星条件
star_delaySMALLINTNOT NULL延迟星条件
rewardINTNOT NULL通关奖励红石币
+
+ +

multiplayer_matches · 多人对局表

+
+ + + + + + + + + + + +
字段名类型约束说明
idBIGSERIALPK对局主键
modeVARCHAR(16)NOT NULL对战模式
statusVARCHAR(16)NOT NULL状态 waiting/playing/ended
players_jsonJSONBNOT NULL玩家列表与分数
result_jsonJSONBNULL对局结果
started_atTIMESTAMPTZNULL开始时间
ended_atTIMESTAMPTZNULL结束时间
+
+ +

achievements · 成就表

+
+ + + + + + + + +
字段名类型约束说明
idBIGSERIALPK记录主键
user_idBIGINTFK -> users.id用户
achievement_idVARCHAR(32)NOT NULL成就标识
unlocked_atTIMESTAMPTZDEFAULT NOW()解锁时间
+
+
+ +
+

05 / API DESIGN

+

API设计

+

REST API 端点清单,涵盖认证、用户、电路、蓝图、商店、解谜、多人与排行榜。

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法路径说明鉴权
POST/api/auth/register用户注册
POST/api/auth/login用户登录
POST/api/auth/logout退出登录
POST/api/auth/refresh刷新 Token
GET/api/user/profile获取个人资料
GET/api/user/balance查询货币余额
GET/api/user/achievements查询成就列表
GET/api/circuits获取电路列表
POST/api/circuits新建电路存档
GET/api/circuits/:id获取电路详情
PUT/api/circuits/:id更新电路
DELETE/api/circuits/:id删除电路
POST/api/circuits/:id/share分享电路为蓝图
GET/api/blueprints浏览蓝图列表
POST/api/blueprints上传蓝图
POST/api/blueprints/:id/buy购买蓝图
GET/api/blueprints/:id/download下载蓝图文件
POST/api/blueprints/:id/rate评分
GET/api/shop/items商店商品列表
POST/api/shop/buy购买商品
GET/api/shop/history购买历史
GET/api/puzzle/levels解谜关卡列表
POST/api/puzzle/:id/submit提交关卡答案
GET/api/puzzle/progress关卡进度
POST/api/multiplayer/match发起匹配
POST/api/multiplayer/join加入房间
POST/api/multiplayer/result提交对局结果
GET/api/leaderboard排行榜
+
+
+ + +
+

06 / SIMULATION

+

信号仿真引擎

+

基于 ECS 的红石信号传播系统,完整还原强度衰减、延迟、BUD 更新等机制。

+ +

仿真流程

+

仿真引擎每个 Tick 执行以下步骤:收集电源、重置信号网格、按强度优先级 BFS 传播、应用元件规则、处理延迟队列、更新输出元件、发射渲染事件。

+
+ + + + + + + + + + + + +
步骤操作说明
1收集电源查询所有 PowerSourceComponent 且处于激活态的元件
2重置网格将所有格子信号归零、标记未更新
3优先级入队按信号强度降序将电源推入优先级队列
4BFS 传播从队列取出格子,向邻居传播衰减后信号
5元件规则对火把/中继器/比较器等应用特殊逻辑
6延迟处理处理中继器等延迟元件的跨 Tick 输出
7输出更新更新灯、活塞、门等输出元件状态
8渲染事件向渲染系统发射变更差量,触发重绘
+
+ +

信号更新优先级

+
+ + + + + + + + + + +
优先级元件类型更新顺序说明
P0电源类最先计算拉杆、按钮、压力板等直接设定信号源
P1红石火把电源之后反相输出,依赖输入端状态
P2比较器火把之后比较/减法模式,需两侧输入
P3中继器比较器之后延迟输出,受锁定信号影响
P4红石粉主动元件之后按强度衰减传播,BFS 遍历
P5输出类最后更新灯、活塞、门读取最终信号
+
+ +

信号属性

+
+ + + + + + + + +
属性取值范围说明
typeredstone / analog红石数字信号或模拟比较信号
strength0 - 15信号强度,15 为满强度
speed1 tick / 格红石粉每格传播延迟 1 tick
directionN / E / S / W / UP / DOWN信号传播方向,支持六向
+
+ +

特殊规则

+
+ + + + + + + + + +
规则触发条件行为
火把反相火把附着方块被激活火把熄灭,停止输出信号(NOT 门)
中继器锁定侧面输入信号中继器锁定当前输出值,不再响应输入变化
比较器检测后方容器有物品输出与物品填充率成正比的模拟信号
活塞链活塞推动含活塞的方块按顺序级联推动,最多 12 格
BUD 更新方块状态变化未直接触发观察者检测邻接变更并发出脉冲
+
+ +

仿真循环伪代码

+
// Redstone Signal Simulation Loop (ECS-based)
+function simulateTick(world):
+    // 1. Collect all power sources
+    powerSources = query(world, PowerSourceComponent)
+
+    // 2. Reset signal grid
+    for each cell in grid:
+        cell.signal = 0
+        cell.updated = false
+
+    // 3. BFS propagation from sources (priority queue by strength)
+    queue = PriorityQueue(descending by strength)
+    for source in powerSources:
+        if source.active:
+            queue.push(source.cell, source.strength)
+
+    // 4. Propagate signals
+    while queue not empty:
+        (cell, strength) = queue.pop()
+        if cell.signal >= strength: continue   // already stronger
+        cell.signal = strength
+        cell.updated = true
+
+        // Apply component-specific rules
+        switch cell.component.type:
+            case WIRE:    propagateToNeighbors(cell, strength - 1)
+            case TORCH:   invertAndPropagate(cell, MAX_STRENGTH)
+            case REPEATER:
+                if cell.locked: break
+                scheduleDelay(cell, strength, 1 tick)
+            case COMPARATOR:
+                output = compare(cell, strength)
+                propagateForward(cell, output)
+            case PISTON:  triggerPiston(cell, strength > 0)
+
+        // BUD (Block Update Detector) check
+        if cell.component.budSensitive:
+            notifyObservers(cell)
+
+    // 5. Resolve scheduled delays (repeaters, etc.)
+    processDelayedQueue(world)
+
+    // 6. Update outputs (lamps, pistons, doors)
+    updateOutputComponents(world)
+
+    // 7. Emit update events to render system
+    emitRenderUpdates(world)
+
+ +
+

07 / COMPONENTS

+

元器件规格手册

+

全部分类元件的编号、成本、信号强度与特殊属性规格,共 8 大类 80 种元件。

+ +

7.1 电源类 POWER

+
+ + + + + + + + + + + + + + +
编号元件名成本(红石币)信号强度特殊属性
P-01POWER 红石火把5015反相输出,可被附着方块熄灭
P-02POWER 红石块10015恒定满强度,不可关闭
P-03POWER 拉杆3015手动开关,双稳态
P-04POWER 按钮4015瞬时脉冲,自动复位
P-05POWER 压力板3515实体踩踏触发,离开复位
P-06POWER 阳光探测器900-15输出随光照强度变化
P-07POWER 阳光探测器(夜)900-15反向模式,夜间满强度
P-08POWER 探测铁轨7015矿车经过时触发脉冲
P-09POWER 直流电源400-15可调稳压输出,输出强度旋钮 0-15 自由设定;适合精密电路调试供电
P-10POWER 电池组8515便携式移动电源,信号强度 15 恒定;可被活塞推动实现移动供电电路;电量有限需充电
+
+ +

7.2 传输类 WIRE

+
+ + + + + + + + + + + +
编号元件名成本(红石币)信号强度特殊属性
W-01WIRE 红石粉515->0每格衰减 1,可爬升 1 格
W-02WIRE 红石中继器8015恢复满强度,1-4 档延迟
W-03WIRE 红石比较器1200-15比较/减法模式,可测容器
W-04WIRE 绝缘导线1515->0不与交叉导线串扰,衰减同红石粉
W-05WIRE 信号桥2515跨层传输信号,不衰减
W-06WIRE 铜导线1215->0低电阻传输,每格仅衰减 0.5(每 2 格衰减 1);成本高于红石粉但传输距离翻倍
W-07WIRE 跳线1815跨格架空连接,可跨越 1 格间隙直接连通两个元件;不与下方交叉导线串扰
+
+ +

信号衰减示意

+
+
+ 15 + -> + 14 + -> + 13 + -> + 12 + -> + 11 + -> + 10 + -> + 9 + -> + 8 + -> + 7 + -> + 6 + -> + 5 + -> + 4 + -> + 3 + -> + 2 + -> + 1 + -> + 0 +
+

红石粉每传播 1 格衰减 1 点强度,中继器可恢复至满强度 15。

+
+ +

7.3 开关/控制类 SWITCH

+
+ + + + + + + + + + + + + + + + +
编号元件名成本(红石币)信号强度特殊属性
S-01SWITCH 按钮木质4015脉冲持续 1.5s
S-02SWITCH 按钮石质4015脉冲持续 1s
S-03SWITCH 拉杆3015双稳态手动开关
S-04SWITCH 压力板木质3515所有实体触发
S-05SWITCH 压力板铁质5015仅玩家触发
S-06SWITCH 压力板金质8015仅玩家触发,信号更长
S-07SWITCH 绊线钩4515绊线被触碰时触发
S-08SWITCH 阳光探测器900-15光照强度模拟输出
S-09SWITCH 观察者15015检测前方方块变更,BUD 脉冲
S-10SWITCH 标靶600-15箭矢命中精度决定强度
S-11SWITCH 拨动开关2515机械双稳态拨动开关,手动切换开/关;比拉杆更紧凑,可密集排列组成 DIP 开关阵列
S-12SWITCH 继电器12015电磁开关,线圈通电吸合触点;支持常开/常闭双触点输出,实现电路隔离与跨域信号传递
+
+

7.4 输出类 OUTPUT

+
+ + + + + + + + + + + + + + + + + + + +
编号元件名成本(红石币)信号强度特殊属性
O-01OUTPUT 红石灯60>=1接收信号即点亮
O-02OUTPUT 活塞150>=1推出方块,断电收回
O-03OUTPUT 粘性活塞200>=1推出并拉回方块
O-04OUTPUT 发射器180>=1脉冲触发发射物品
O-05OUTPUT 投掷器120>=1脉冲触发掉落物品
O-06OUTPUT 漏斗100-信号锁定时停止传输
O-07OUTPUT 音符盒70>=1脉冲触发播放音符
O-08OUTPUT TNT300>=1信号触发引爆
O-09OUTPUT 门(铁)80>=1信号开启,铁门仅受信号控制
O-10OUTPUT 门(木)50>=1信号开启,也可手动开关
O-11OUTPUT 活板门60>=1信号开启翻板
O-12OUTPUT 灯笼55-常亮光源,不受信号控制
O-13OUTPUT LED15>=1低功耗指示灯,多色可选(红/绿/蓝/黄);信号强度决定亮度,体积仅 0.5 格
O-14OUTPUT 蜂鸣器35>=1信号触发鸣响,频率随信号强度变化;可串联实现旋律播放,替代音符盒的精密方案
O-15OUTPUT 数码管900-157 段数码显示管,直接显示输入信号强度数值 0-15;可级联实现多位数字显示
+
+ +

7.5 逻辑门类 LOGIC

+
+ + + + + + + + + + + + + + + +
编号元件名成本(红石币)信号强度特殊属性
L-01LOGIC NOT15015输入反相,单输入门
L-02LOGIC AND20015双输入全高才输出
L-03LOGIC OR20015任一输入高即输出
L-04LOGIC NAND22015AND 后取反
L-05LOGIC NOR22015OR 后取反
L-06LOGIC XOR25015输入不同才输出
L-07LOGIC XNOR25015输入相同才输出
L-08LOGIC 中继器逻辑10015延迟+缓冲,可级联
L-09LOGIC RS 锁存器35015置位/复位双稳态存储
L-10LOGIC D 触发器40015边沿触发数据锁存
L-11LOGIC 计数器5000-15脉冲计数,溢出进位
+
+ +

逻辑门组合规则

+
+ + + + + + + + + + +
组合等效逻辑说明
NOT + NOT缓冲器无逻辑变化,仅作延迟/隔离
AND + NOTNAND通用门,可组合出任一逻辑
OR + NOTNOR通用门,可组合出任一逻辑
NAND + NANDAND双重否定还原与门
NOR + NOROR双重否定还原或门
RS 锁存器 x N寄存器多 Bit 并行存储,构成数据总线
+
+ +

7.6 特殊元件类 SPECIAL

+
+ + + + + + + + + + + + + + +
编号元件名成本(红石币)信号强度特殊属性
X-01SPECIAL 命令方块1000-执行预设指令,仅创意/编辑模式
X-02SPECIAL 结构方块800-保存/加载区域结构,蓝图核心
X-03SPECIAL 信号示波器3000-15实时显示信号波形与延迟
X-04SPECIAL 信号延迟器15015可调 1-16 tick 精确延迟
X-05SPECIAL 信号分配器12015一入多出,不衰减分路
X-06SPECIAL 物品过滤器250-按物品类型筛选传输路径
X-07SPECIAL 物品分类器400-多通道自动分拣,自动化核心
X-08SPECIAL ADC 模数转换器4500-15将模拟信号(连续强度)转为数字信号(二进制 4-bit 输出);连接模拟电路与数字逻辑的桥梁
X-09SPECIAL DAC 数模转换器4500-15将 4-bit 数字信号转为模拟信号强度 0-15 输出;用于驱动模拟负载或生成可变亮度
X-10SPECIAL 555 定时器35015支持单稳态(定时器)、双稳态(锁存)、无稳态(方波振荡器)三种工作模式;外接电阻电容可调频率与占空比
+
+ +

7.7 模拟元件类 ANALOG

+

真实模拟电子元件,引入连续信号与线性电路概念,支持更贴近现实电路的设计体验。需在 Lv.15 解锁。

+
+ + + + + + + + + + + + + +
编号元件名成本(红石币)信号规则特殊属性
A-01ANALOG 电阻20衰减可调串联在导线中,可调阻值 1-15,按比例衰减信号强度;用于限流保护和信号分压
A-02ANALOG 电容60充放电存储信号能量,输入断开后延迟释放(容量可调 1-8 tick);用于平滑脉冲、延时开关、去抖
A-03ANALOG 电感70磁能存储阻碍电流突变,信号突变时产生反电动势;与电容组合可构建 LC 振荡、滤波器;延迟特性与电容互补
A-04ANALOG 二极管45单向导通仅允许信号正向通过、反向截止;等效红石中继器但无延迟、无放大;防信号回流
A-05ANALOG 稳压管55钳位反向击穿后将信号钳位在固定强度(可调 1-15);用于稳压保护、电压基准源、限幅电路
A-06ANALOG NPN 三极管180电流控制三端元件(C/B/E);B 有信号时 C->E 导通,B 无信号时截止;可用作信号开关或放大器
A-07ANALOG PNP 三极管180电流控制与 NPN 互补;B 无信号时 C->E 导通,B 有信号时截止;适合高边开关设计,与 NPN 组合可搭建推挽电路
A-08ANALOG 运算放大器280线性放大高增益差分放大器,支持反相/同相/差分/积分/微分五种工作模式;外接电阻设定增益倍数;模拟计算核心
A-09ANALOG 光耦160光电隔离输入端 LED 驱动光敏管输出,实现电气隔离传输;抗干扰、防地线环路;高压与低压电路安全桥接
+
+ +

运算放大器工作模式

+
+ + + + + + + + + +
模式接法输出典型用途
反相放大输入接反相端,同相端接地,Rf/R1 设定增益Vout = -Vin * (Rf/R1)信号反相放大、加法器
同相放大输入接同相端,反相端分压反馈Vout = Vin * (1 + Rf/R1)信号同相放大、缓冲器
差分放大双端输入,差模放大共模抑制Vout = (V+ - V-) * Gain传感器信号放大、噪声抑制
积分器反馈回路用电容替代电阻Vout = -1/RC * ∫Vin dt波形变换、斜坡发生器
比较器开环工作,无反馈Vout = +Vcc if V+ > V- else -Vcc阈值检测、过零比较
+
+ +

三极管组合应用

+
+ + + + + + + +
组合结构功能
推挽输出NPN + PNP 对管,基极共连双向驱动,可拉高也可拉低,替代活塞推拉逻辑
达林顿管两级 NPN 级联超高增益,极弱信号可驱动大负载
差分对双 NPN 共发射极比较两路信号差值,运放输入级的基础结构
+
+ +

7.8 功率器件类 POWER DEVICE

+

高功率半导体器件,用于大电流驱动与功率控制场景。需在 Lv.20 解锁。适合自动化生产线和大型机械驱动。

+
+ + + + + + + + + + +
编号元件名成本(红石币)信号规则特殊属性
PD-01POWER_DEVICE 单向可控硅 SCR220触发导通门极脉冲触发后持续导通,直至电流降至零才关断;用于整流功率控制、过压保护;半控型器件
PD-02POWER_DEVICE 双向可控硅 TRIAC280双向触发双方向均可触发导通,等效两个 SCR 反并联;交流功率控制核心元件;调光、调速、温控
PD-03POWER_DEVICE IGBT420电压驱动结合 MOS 管高输入阻抗与三极管大电流能力;高压大电流开关核心;逆变器、电机驱动首选
PD-04POWER_DEVICE MOS 管200电压控制电压驱动型场效应管,导通电阻极低;开关速度快,高频功率应用核心;可并联扩流
PD-05POWER_DEVICE 达林顿管300高增益驱动两级三极管复合封装,电流增益达 1000+;微弱信号即可驱动大功率负载;步进电机/继电器阵列驱动
PD-06POWER_DEVICE 继电器模组250多路隔离4 路独立继电器集成模组,每路常开+常闭双触点;可同时控制 4 路独立高功率负载;工业自动化标配
+
+ +

555 定时器工作模式(X-10)

+
+ + + + + + + +
模式接法输出典型用途
单稳态触发端输入脉冲,外接 R+C 定时固定宽度高电平脉冲延时开关、脉冲展宽、防抖
双稳态触发端置位,复位端清零锁存当前状态RS 锁存器替代、记忆电路
无稳态两电阻 + 电容构成振荡回路连续方波信号时钟发生器、PWM 调制、闪烁灯
+
+
+ +
+

08 / GAME MODES

+

游戏模式规则

+

四大游戏模式的规则、限制与奖励机制定义。

+ +

8.1 自由搭建模式 Creative

+
+ + + + + + + + + + + +
规则项设定说明
资源无限所有元件免费无限使用
成本不计不消耗红石币
画布尺寸256x256最大单电路画布
存档槽位20本地+云端各 20 个
仿真实时放置即仿真,可暂停单步
分享允许可发布为蓝图供他人下载
目标纯创造,无强制目标
+
+ +

8.2 解谜关卡模式 Puzzle

+

解谜模式提供 6 种关卡类型,通过 3 星评级衡量通关质量,每章节难度递增,共 6 章 240 关。

+
+ + + + + + + + + + +
关卡类型玩法说明示例目标
信号路由将信号从起点传至终点点亮指定红石灯
逻辑运算搭建满足真值表的逻辑电路实现 XOR 门
时序控制按顺序触发多个输出三盏灯依次点亮
计数挑战统计脉冲数并输出计满 10 次触发
资源优化在元件数限制内通关不超过 15 个元件
延迟竞速在延迟上限内完成总延迟不超过 20 tick
+
+ +

三星评级系统

+
+ + + + + + + +
星级条件奖励
一星完成通关目标基础红石币奖励
二星成本不超过 star_cost 上限1.5x 红石币 + 经验
三星成本达标且延迟不超过 star_delay2x 红石币 + 成就进度
+
+ +

限制规则

+
+ + + + + + + + +
限制类型说明
元件禁用部分关卡禁用高级元件(如命令方块、结构方块)
元件上限限制可放置元件总数
画布缩放缩小可用画布区域增加难度
预设锁定部分元件位置固定不可移动
+
+ +

章节分布 (共 240 关)

+
+ + + + + + + + + + + +
章节主题关卡数难度
第 1 章基础电路入门30简单
第 2 章逻辑门与运算40普通
第 3 章时序与锁存50中等
第 4 章复杂自动化60困难
第 5 章高级电路设计40专家
第 6 章极限挑战20大师
合计-240-
+
+ +

8.3 自动化生产模式 Automation

+

玩家搭建生产线,将原料加工为成品出售赚取红石币。生产链从采集到精炼逐级加工。

+
+ 矿石采集 + -> + 粉碎机 + -> + 精炼炉 + -> + 合成台 + -> + 成品仓库 + -> + 出售获利 +
+
+ + + + + + + + + + + + +
资源类型采购价用途
原矿石5基础原料,粉碎后得矿粉
矿粉12精炼原料,可熔炼为锭
金属锭30合成元件壳体的核心材料
红石粉原料8提纯为可用红石粉
红石结晶80高级逻辑门核心材料
硅片45集成电路板基材
电路板120成品元件必备组件
能量核200特殊元件能源供给
+
+
+ 效率公式:E = (成品数量 / 总耗时) x 100
+ 成本回收:R = 成品售价 - (原料成本 + 元件磨损 + 电力消耗)
+ 净利润:P = R x E x 运行时长 +
+ +

8.4 多人对战/协作模式 Multiplayer

+
+ + + + + + + + +
对战模式人数规则
电路竞速2-4最先完成指定电路搭建者获胜
信号攻防2一方搭建防御电路,另一方破解
资源争夺2-4争夺有限元件资源搭建最优电路
蓝图复刻2-4看图复原电路,最快最准者胜
+
+
+ + + + + + + +
协作模式人数规则
联合建造2-4共同完成大型电路工程
分工流水线2-4各负责生产链一环,协同产出
解谜协作2-4合力攻克高难度解谜关卡
+
+ +

匹配与赛季规则

+
+ + + + + + + + + +
规则项设定说明
匹配机制MMR 段位基于隐藏分匹配相近水平玩家
匹配超时60s超时后放宽段位范围
赛季周期4 周每月一个赛季,结算发放奖励
段位7 级青铜至宗师,每级 3 小段
赛季奖励蓝图+金币按最终段位发放限定蓝图与金币
+
+
+ +
+

09 / ECONOMY

+

货币与经济系统

+

双货币体系设计,红石币为软货币贯穿玩法循环,金币为硬货币用于增值消费。

+ +

9.1 货币类型

+
+ + + + + + + + + +
属性红石币 (软货币)金币 (硬货币)
获取方式解谜通关、自动化生产、每日任务人民币充值、赛季奖励、成就
主要用途购买元件、解锁关卡、购买蓝图购买稀有皮肤、加速、高级蓝图
可交易性不可直接交易,仅通过蓝图间接流通不可交易
上限9,999,99999,999
汇率参考1000 红石币 ≈ ¥110 金币 = ¥1
+
+ +

9.2 产出与消耗平衡

+
+ + + + + + + + + +
产出渠道日预估产出说明
解谜通关800-1500首次通关奖励高,重复递减
自动化生产500-2000取决于生产线效率与在线时长
每日任务300固定日任务奖励
蓝图销售分成0-5000他人购买作者蓝图,作者获 70%
多人对战奖励100-600按胜负与段位
+
+
+ + + + + + + + + +
消耗渠道单次消耗说明
购买元件(单价)5-1000按元件类型差异定价
解锁关卡章节2000-8000逐章递增
购买蓝图0-3000作者定价,平台抽成 30%
商店道具100-500消耗品与装饰品
自动化原料采购5-200生产链原料采购成本
+
+ +

9.3 充值档位

+
+ + + + + + + + +
档位价格金币额外赠送
新手包¥660首充双倍 + 新手元件包
标准包¥3030030 金币 + 限定皮肤
超值包¥68680120 金币 + 赛季通行证
豪华包¥1681680400 金币 + 专属称号
+
+
+ + +
+

10 / USER SYSTEM

+

用户系统

+

注册登录、账号安全、新手引导、等级解锁与成就系统。

+ +

10.1 注册登录

+
+ + + + + + + + + +
规则项要求说明
用户名3-32 字符字母数字下划线,唯一
邮箱有效邮箱用于找回密码与通知
密码8-64 字符需含大小写字母与数字,bcrypt 加密
第三方登录Google / GitHub / Discord支持 OAuth2 快捷登录
验证方式邮箱验证码注册与找回密码需验证
+
+
+ + + + + + + + + +
安全措施说明
密码加密bcrypt 哈希存储,不存明文
JWT Token双 Token 机制,Access 短期 + Refresh 长期
异地登录检测新设备登录需邮箱二次验证
登录频率限制5 次失败锁定 15 分钟
数据传输加密全站 HTTPS / WSS
+
+

新手引导流程

+
+ + + + + + + + + +
步骤内容奖励
1创建账号与角色100 红石币
2基础元件放置教学150 红石币
3完成首个教程关卡200 红石币 + 经验
4商店购买教学拉杆元件 x5
5分享首个电路300 红石币 + 成就
+
+ +

10.2 等级与解锁

+
+ + + + + + + + +
等级段等级范围经验要求解锁内容
新手1-100-5,000基础元件、第 1-2 章、自由搭建
进阶11-255,000-30,000逻辑门元件、第 3-4 章、自动化
高级26-5030,000-120,000特殊元件、第 5-6 章、多人模式
大师51+120,000+全部解锁、蓝图上传、赛季排位
+
+ +

10.3 成就系统

+
+ + + + + + + + + + + +
成就解锁条件奖励
初出茅庐完成新手引导300 红石币
电路学徒通关 10 个解谜关卡500 红石币 + 经验
逻辑大师用逻辑门完成 50 个关卡1000 红石币 + 称号
满星达人累计获得 100 颗星800 金币 + 限定皮肤
蓝图创作者上传首个蓝图200 红石币
人气作者蓝图累计下载 1000 次2000 红石币 + 称号
赛季冠军达到宗师段位5000 金币 + 限定蓝图
+
+
+ +
+

11 / MILESTONES

+

开发里程碑

+

从原型到运营的五阶段开发计划与交付物定义。

+
+ + + + + + + + + +
阶段时间交付物团队规模
Phase 1 原型期M1-M2核心仿真引擎、基础编辑器、5 种元件原型4 人
Phase 2 AlphaM3-M5全部 4 模式、经济系统、用户认证、前 3 章关卡8 人
Phase 3 BetaM6-M8多人联机、蓝图工坊、商店、全 240 关、UI 打磨12 人
Phase 4 发布M9官网上线、监控告警、热修复管线、客服系统12 人
Phase 5 运营M10+赛季内容、限时活动、平衡性补丁、数据分析10 人
+
+
+ + +
+

12 / DEPLOYMENT

+

部署与运维

+

服务端容器化部署、客户端分发、CI/CD 流水线与监控体系。

+
+ + + + + + + + + + + + +
领域方案说明
服务端部署Docker + Kubernetes容器化微服务,HPA 自动伸缩,滚动更新
客户端分发官网安装包 + 自动更新服务官网提供 Windows/macOS 安装包,内置增量更新客户端
CI/CDGitHub Actions推送触发自动构建、单元测试、集成测试、部署
服务端监控Prometheus + GrafanaCPU/内存/QPS/延迟指标,告警规则推送到钉钉
错误追踪Sentry客户端崩溃报告与服务端异常堆栈统一收集
CDN蓝图文件 + 更新补丁静态资源与增量更新包走 CDN 加速分发
日志收集ELK StackElasticsearch + Logstash + Kibana 日志检索
备份策略每日全量 + 实时 WALPostgreSQL 每日全量备份,WAL 实时归档
+
+
+ + +
+

13 / RISKS

+

风险评估

+

技术、市场、运营与安全维度的风险识别与缓解措施。

+
+ + + + + + + + + + + + + + +
风险项类别概率影响缓解措施
大规模电路仿真性能瓶颈技术ECS 优化、分块加载、LOD 降级、多线程
红石逻辑还原度不足技术对照 MC 原版行为单元测试,社区反馈迭代
多人同步延迟与一致性技术客户端预测+服务端权威,Delta 压缩同步
同类竞品挤压市场市场差异化双货币+UGC 生态,社区运营前置
玩家留存不及预期市场数据驱动关卡调优,限时活动促活
UGC 内容审核滞后运营机审+人审双通道,举报快速响应机制
服务器成本超预算运营HPA 弹性伸缩,闲时缩容,预留缓存层
经济系统通胀失控运营产出消耗动态监控,定期平衡性补丁
账号盗号与黑产刷币安全异地登录验证、行为风控、交易限额
客户端被逆向破解安全代码混淆、关键逻辑服务端校验、反调试
+
+
+ + +
+

15 / SPRINT PLAN

+

Sprint 分解与排期

+

以 2 周为一个 Sprint,从 M1 到 M9 共 18 个 Sprint,每个 Sprint 明确交付物和验收标准。

+ +

Phase 1 原型期 (M1-M2, Sprint 1-4)

+
+ + + + + + + + +
Sprint周期交付物验收标准
S1W1-2项目骨架搭建:Unity 工程初始化、Go 项目骨架、CI 基础流水线、Git 仓库与代码规范Unity 可编译运行空场景;Go 服务可启动并返回 health check;CI 可自动构建
S2W3-4网格画布渲染器 + 元件放置系统:16x16 网格、元件拖放放置、基础 8 种元件数据结构可在画布上放置/删除/移动元件;网格坐标正确;元件数据 JSON 序列化通过
S3W5-6信号仿真引擎 v1:红石粉信号传播、衰减计算、电源->导线->输出基本链路红石火把->红石粉->红石灯 链路可点亮;信号强度衰减正确;1 tick = 0.1s 时序正确
S4W7-8仿真引擎 v2 + 工具栏 UI:中继器/比较器/逻辑门仿真、保存/加载/运行/暂停按钮、成本计算逻辑门输出正确(真值表验证);电路可保存为 JSON 并重新加载;成本实时计算
+
+ +

Phase 2 Alpha (M3-M5, Sprint 5-10)

+
+ + + + + + + + + + +
Sprint周期交付物验收标准
S5W9-10用户认证系统:注册/登录 API、JWT Token、SQLite 本地存档、PostgreSQL 用户表注册->登录->获取Token->访问受保护接口 全链路通过;密码 bcrypt 加密;Token 过期自动刷新
S6W11-12解谜关卡系统 v1:关卡数据结构、关卡加载器、前 30 关(第一章)、三星评级算法30 关可游玩;输入/输出验证正确;三星评级按成本和延迟计算
S7W13-14自由搭建模式 + 画布扩展至 128x128 + 全部 80 种元件数据填充128x128 画布流畅运行(>30fps);80 种元件均可放置和仿真;无限资源模式
S8W15-16货币系统 + 商店 UI:红石币/金币数据库表、交易流水、商店 4 标签页、购买逻辑解谜通关奖励红石币正确入账;商店购买扣费正确;交易流水可追溯
S9W17-18自动化生产模式 v1:资源采集->传输->加工->出售 链路、效率计算、8 种资源自动农场可运行产出资源;资源出售获得红石币;效率系数 0.5x-2.0x 正确
S10W19-20解谜第二章 40 关 + 第三章前 25 关 + 成就系统 v1 + 等级系统累计 95 关可游玩;等级升级正确解锁元件;7 个成就可触发
+
+ +

Phase 3 Beta (M6-M8, Sprint 11-16)

+
+ + + + + + + + + + +
Sprint周期交付物验收标准
S11W21-22多人联机核心:WebSocket 网关、客户端预测+服务端校验、实时画布同步2 人同时编辑同一画布延迟 <200ms;冲突解决正确;断线重连恢复
S12W23-24多人对战模式:电路竞速、成本竞速、匹配系统、积分排行4 人匹配对局可完整进行;排行榜实时更新;积分增减正确
S13W25-26蓝图工坊:蓝图上传/下载/评分/搜索、MinIO 文件存储、蓝图市场 UI蓝图可上传并下载复现;评分系统正常;搜索可按名称/作者/标签过滤
S14W27-28解谜第三至第五章共 150 关 + 多人协作模式 + 信号攻防模式累计 245 关可游玩;协作模式 4 人共建正常;信号攻防 2v2 可进行
S15W29-30全 UI 打磨:动效系统、暗色/亮色主题、响应式适配、无障碍优化Lighthouse 评分 >85;动效 60fps;prefers-reduced-motion 生效;键盘可操作
S16W31-32第五章剩余 + 第六章 20 关大师关 + 性能优化 + Bug 修复 + 封闭 Beta 测试240 关全部可游玩;512x512 画布 >30fps;P0 Bug 清零;封闭 Beta 500 人测试
+
+ +

Phase 4 发布 (M9, Sprint 17-18)

+
+ + + + + + +
Sprint周期交付物验收标准
S17W33-34开放 Beta + 压力测试 + 热修复管线 + 客服系统 + 数据分析埋点5000 并发用户稳定;P0 Bug 24h 内修复;数据分析看板可查看 DAU/留存
S18W35-36正式发布 + 监控告警 + 运营活动配置系统 + 赛季系统上线正式环境运行稳定;告警 <5min 响应;第一赛季可正常运行;首周留存 >35%
+
+
+ + +
+

16 / TEAM

+

团队组织与职责

+

按阶段递进的团队配置,明确角色、职责与协作流程。

+ +

团队配置阶段表

+
+ + + + + + + + +
阶段人数角色构成关键职责
Phase 14技术主策 1 + 客户端 1 + 服务端 1 + 美术 1核心引擎原型、美术风格验证
Phase 28+ 客户端 2 + 服务端 1 + 策划 1 + QA 1全模式开发、经济系统、认证系统
Phase 312+ 客户端 1 + 服务端 1 + 美术 1 + QA 1多人联机、蓝图工坊、全关卡、UI 打磨
Phase 4-510-12稳定团队 + 运营 1 + 数据分析 1发布运维、赛季内容、平衡性调优
+
+ +

角色职责矩阵

+
+ + + + + + + + + + + +
角色核心职责技术栈要求产出物
技术主策 / Tech Lead架构决策、技术选型、代码审查、跨端协调Unity C# + Go + 系统设计架构文档、技术方案、Code Review 记录
客户端工程师 x4Unity 渲染、UI Toolkit、仿真引擎客户端、网络层Unity 2024 LTS, C#, UI Toolkit客户端模块代码、性能报告
服务端工程师 x2Go 微服务、数据库设计、WebSocket 网关、反作弊Go, Gin, PostgreSQL, RedisAPI 服务代码、数据库 Migration、接口文档
游戏策划 x1关卡设计、数值平衡、经济系统调优、赛季规划Excel/Python 数据分析、关卡编辑器关卡数据 JSON、数值表、策划案
UI/UX 美术 x2UI 设计、像素元件图标、特效、主题Figma, Aseprite, Unity ShaderUI 切图、图标素材、特效预设
QA 测试 x2功能测试、自动化测试、性能测试、Bug 管理Python, Selenium, Unity Test Framework测试用例、Bug 报告、自动化脚本
运营 / 数据 x1活动配置、数据分析、社区运营、赛季管理SQL, Tableau, 社区工具运营报告、活动配置、数据看板
+
+ +

协作流程

+
+ + + + + + + + + + +
流程工具规则
代码管理Git + GitHubmain 分支保护;feature/* 分支开发;PR 至少 1 人 Review 后合并;Sprint 结束打 tag
任务管理GitHub Projects / JiraSprint Backlog 拆分至 2 人日以内;每日 Standup 15 分钟;Sprint Review + Retro
文档管理Notion / ConfluenceAPI 文档 Swagger 自动生成;设计文档 PR 附带;会议纪要 24h 内归档
CI/CDGitHub ActionsPR 触发自动构建+测试;main 分支自动部署 Staging;Tag 发布 Production
沟通飞书 / Discord技术讨论频道;紧急问题电话优先;每周技术分享 1 小时
Bug 追踪GitHub IssuesP0 当日修复;P1 当 Sprint 修复;P2 排入 Backlog;Bug 复现步骤必填
+
+
+ + +
+

17 / CLIENT MODULES

+

客户端模块详设

+

Unity 客户端的模块拆分、核心脚本职责与数据流设计。

+ +

17.1 模块总览

+
+ + + + + + + + + + + + +
模块命名空间职责核心脚本
GridRendererRedCircuit.Grid网格画布渲染、视口裁剪、LODGridCanvas.cs, ChunkManager.cs, TileRenderer.cs
SimulationEngineRedCircuit.Simulation信号传播、元件仿真、tick 循环SimulationLoop.cs, SignalPropagator.cs, ComponentBehavior.cs
ComponentSystemRedCircuit.Components80 种元件数据定义、放置/删除/旋转ComponentRegistry.cs, PlacementController.cs, ComponentData.cs
UISystemRedCircuit.UIUI Toolkit 界面、工具栏、面板、弹窗EditorWindow.cs, ToolbarController.cs, PalettePanel.cs, InspectorPanel.cs
NetworkClientRedCircuit.NetREST 请求、WebSocket 连接、delta 同步ApiClient.cs, WsClient.cs, SyncManager.cs
SaveSystemRedCircuit.Save本地 SQLite 存档、云端同步、蓝图导出SaveManager.cs, LocalDatabase.cs, CloudSync.cs
AudioSystemRedCircuit.Audio音符盒/蜂鸣器音效、UI 音效、BGMAudioManager.cs, NotePlayer.cs
AuthSystemRedCircuit.Auth登录注册、Token 管理、第三方 OAuthAuthManager.cs, TokenStore.cs, OAuthClient.cs
+
+ +

17.2 仿真引擎核心数据结构

+
+ + + + + + + + + +
类名字段说明
GridCellint x, y; Component component; int signalStrength; List<GridCell> neighbors网格单元,记录坐标、元件实例、当前信号强度、四邻连接
ComponentComponentType type; int rotation; Dictionary<string, int> properties; bool isPowered元件实例,类型、朝向、可调属性(阻值/延迟/模式等)、通电状态
SignalUpdateGridCell target; int newStrength; int tick; SignalSource source信号更新事件,BFS 队列元素,记录目标格、新强度、tick 序号、来源
CircuitGraphDictionary<Vector2Int, GridCell> cells; Queue<SignalUpdate> updateQueue; HashSet<Vector2Int> dirtyCells电路图数据,全格字典 + 信号更新队列 + 脏标记集合
SimulationConfigfloat tickDuration; int maxGridSize; bool enableShortCircuitDetection; bool stepMode仿真配置,tick 时长、最大画布、短路检测开关、步进模式
+
+ +

17.3 渲染性能策略

+
+ + + + + + + + + + +
策略实现方式目标
分块加载画布按 16x16 分 Chunk,视口内 Chunk 才实例化 GameObject512x512 画布内存占用 <512MB
对象池元件 GameObject 预生成 500 个池化,放置时取用而非 Instantiate消除 GC Spike,放置延迟 <16ms
GPU Instancing同类型元件使用 GPU Instancing 批量渲染1000+ 元件同帧 Draw Call <50
信号轨迹 Shader红石信号轨迹用自定义 Shader 绘制,非逐格 GameObject信号动画 60fps,不随电路规模增长
LOD 降级缩放 <50% 时元件图标降级为纯色方块,不渲染细节全景浏览 512x512 保持 >30fps
仿真分帧大电路仿真 BFS 分帧执行,每帧最多处理 2000 格更新避免大电路导致主线程卡顿
+
+ +

17.4 电路数据 JSON 格式

+
{
+  "version": "1.0",
+  "canvasSize": { "width": 128, "height": 128 },
+  "components": [
+    {
+      "id": "comp_001",
+      "type": "REDSTONE_TORCH",
+      "x": 10, "y": 20,
+      "rotation": 0,
+      "properties": {}
+    },
+    {
+      "id": "comp_002",
+      "type": "REDSTONE_DUST",
+      "x": 11, "y": 20,
+      "rotation": 0,
+      "properties": {}
+    },
+    {
+      "id": "comp_003",
+      "type": "AND_GATE",
+      "x": 15, "y": 20,
+      "rotation": 0,
+      "properties": { "inputCount": 2 }
+    },
+    {
+      "id": "comp_004",
+      "type": "RESISTOR",
+      "x": 12, "y": 20,
+      "rotation": 0,
+      "properties": { "resistance": 5 }
+    }
+  ],
+  "wires": [
+    { "from": "comp_001", "to": "comp_002" },
+    { "from": "comp_002", "to": "comp_004" },
+    { "from": "comp_004", "to": "comp_003", "inputIndex": 0 }
+  ],
+  "metadata": {
+    "author": "CircuitMaster",
+    "createdAt": "2026-08-07T12:00:00Z",
+    "cost": 280,
+    "componentCount": 4,
+    "wireCount": 3
+  }
+}
+
+ + +
+

18 / SERVER SERVICES

+

服务端微服务详设

+

5 个微服务的职责边界、核心接口、数据归属与通信协议。

+ +

18.1 微服务总览

+
+ + + + + + + + + +
服务语言/框架端口数据库核心职责
auth-serviceGo / Gin8081PostgreSQL(users)注册/登录/JWT/第三方OAuth/Token刷新
economy-serviceGo / Gin8082PostgreSQL(transactions) + Redis(balance cache)货币余额/交易流水/商店购买/充值回调
blueprint-serviceGo / Gin8083PostgreSQL(blueprints) + MinIO(files)蓝图CRUD/评分/搜索/下载/分类
match-serviceGo + WebSocket8084Redis(matchmaking) + PostgreSQL(matches)匹配/房间管理/实时同步/对战结算
social-serviceGo / Gin8085PostgreSQL(achievements) + Redis(leaderboard)成就/排行榜/好友/赛季/活动
+
+ +

18.2 auth-service 核心接口

+
+ + + + + + + + + +
接口请求响应备注
POST /register{ username, email, password }{ userId, token, refreshToken }密码 bcrypt;发送验证邮件
POST /login{ username, password }{ userId, token, refreshToken, profile }5 次错误锁定 15min
POST /refresh{ refreshToken }{ token, refreshToken }旧 Token 黑名单
POST /oauth/callback{ provider, code }{ userId, token, refreshToken }Google/GitHub/Discord
GET /profileHeader: Authorization{ userId, username, email, level, exp, balance }聚合 economy-service 余额
+
+ +

18.3 economy-service 交易事务

+
// 购买流程伪代码 - 保证原子性和一致性
+func PurchaseItem(userID string, itemID string) error {
+    // 1. 开启数据库事务
+    tx := db.Begin()
+    
+    // 2. 查询商品价格 (行锁)
+    var item ShopItem
+    tx.Clauses(clause.Locking{Strength: "UPDATE"}).
+       First(&item, itemID)
+    
+    // 3. 查询用户余额 (行锁)
+    var balance UserBalance
+    tx.Clauses(clause.Locking{Strength: "UPDATE"}).
+       First(&balance, "user_id = ?", userID)
+    
+    // 4. 校验余额
+    if balance.RedstoneCoins < item.Price {
+        tx.Rollback()
+        return ErrInsufficientBalance
+    }
+    
+    // 5. 扣减余额
+    balance.RedstoneCoins -= item.Price
+    tx.Save(&balance)
+    
+    // 6. 写入交易流水
+    tx.Create(&Transaction{
+        UserID:      userID,
+        Type:        "purchase",
+        Item:        item.Name,
+        Amount:      -item.Price,
+        Currency:    "redstone",
+        BalanceAfter: balance.RedstoneCoins,
+    })
+    
+    // 7. 发放商品 (调用对应服务)
+    if item.Type == "component_pack" {
+        // 发放元件包到用户库存
+    } else if item.Type == "blueprint" {
+        // 标记蓝图为已购买
+    }
+    
+    // 8. 提交事务
+    return tx.Commit().Error
+}
+ +

18.4 数据库索引策略

+
+ + + + + + + + + + + + + +
索引类型查询场景
usersidx_users_usernameUNIQUE B-Tree登录时按用户名查询
usersidx_users_emailUNIQUE B-Tree邮箱验证/找回密码
circuitsidx_circuits_user_idB-Tree查询用户所有电路
circuitsidx_circuits_updatedB-Tree DESC按更新时间排序
blueprintsidx_bp_authorB-Tree作者蓝图列表
blueprintsidx_bp_category_ratingComposite B-Tree分类+评分排序
transactionsidx_tx_user_createdComposite B-Tree DESC用户交易历史分页
puzzle_levelsidx_puzzle_chapter_levelComposite B-Tree章节+关卡序号排序
multiplayer_matchesidx_match_status_startedComposite B-Tree按状态+时间查询对局
+
+
+ + +
+

18.5 / RELAY SERVER

+

联机服务器中转站开发

+

独立于业务微服务的联机中转网关,负责 P2P 打洞辅助、房间管理、实时消息路由与断线重连。

+ +

架构定位

+
+ + + + + + + + + + +
维度说明
服务名称relay-server (Go 1.22 + gorilla/websocket)
端口TCP 8084 (WebSocket) / UDP 8086 (STUN/TURN)
部署形态独立进程,不与 auth/economy 等业务服务混部;可水平扩展多节点 + 负载均衡
核心职责房间生命周期管理 / WebSocket 长连接维护 / 消息路由转发 / P2P 打洞辅助 / TURN 中继兜底 / 断线重连状态恢复
不负责用户认证(由 auth-service 签发 Token,relay 仅校验) / 货币结算 / 蓝图存储
设计目标单节点支持 5000 并发 WebSocket 连接 / 200 个活跃房间 / 消息转发延迟 P99 <50ms
+
+ +

连接拓扑

+
+┌──────────┐         ┌──────────────┐         ┌──────────┐
+│ Player A │◄───────►│  Relay Server │◄───────►│ Player B │
+│ (Client) │  WSS    │  (Go + WS)   │  WSS    │ (Client) │
+└──────────┘         └──────┬───────┘         └──────────┘
+                            │
+                     ┌──────┴───────┐
+                     │  Room Manager │
+                     │  (内存状态机) │
+                     └──────┬───────┘
+                            │
+              ┌─────────────┼─────────────┐
+              │             │             │
+        ┌─────▼─────┐ ┌────▼────┐ ┌─────▼─────┐
+        │  STUN/TURN │ │  Redis  │ │  Kafka   │
+        │  (UDP)     │ │ (状态)  │ │ (事件)   │
+        └───────────┘ └─────────┘ └───────────┘
+
+连接模式优先级:
+  1. P2P 直连 (STUN 打洞成功)  -> relay 仅做信令交换
+  2. TURN 中继 (打洞失败)      -> relay 转发所有游戏数据
+  3. WebSocket 中转 (兜底)     -> relay 中心化转发
+ +

消息协议定义 (Protobuf)

+
syntax = "proto3";
+package relay;
+
+// 客户端 -> Relay 消息
+message ClientMessage {
+  string msg_id     = 1;  // 消息唯一 ID (UUID)
+  int32  msg_type   = 2;  // 消息类型枚举
+  string room_id    = 3;  // 目标房间
+  string user_id    = 4;  // 发送者
+  bytes  payload    = 5;  // 业务载荷 (电路 delta / 聊天 / 状态)
+  int64  timestamp  = 6;  // 客户端时间戳 (ms)
+}
+
+// Relay -> 客户端消息
+message ServerMessage {
+  string msg_id     = 1;
+  int32  msg_type   = 2;
+  string from_user  = 3;  // 消息来源用户
+  bytes  payload    = 4;
+  int64  server_ts  = 5;  // 服务端时间戳
+  int32  seq        = 6;  // 房间内序号 (用于排序)
+}
+
+// 消息类型枚举
+enum MessageType {
+  MSG_JOIN_ROOM      = 0;   // 加入房间
+  MSG_LEAVE_ROOM     = 1;   // 离开房间
+  MSG_CIRCUIT_DELTA  = 2;   // 电路增量同步
+  MSG_CIRCUIT_FULL   = 3;   // 电路全量同步
+  MSG_CHAT           = 4;   // 聊天消息
+  MSG_PRESENCE       = 5;   // 在线状态
+  MSG_CURSOR         = 6;   // 光标位置同步
+  MSG_ACTION         = 7;   // 游戏操作 (放置/删除元件)
+  MSG_GAME_STATE     = 8;   // 游戏状态变更 (开始/暂停/结束)
+  MSG_RECONNECT      = 9;   // 断线重连
+  MSG_HEARTBEAT      = 10;  // 心跳
+  MSG_KICK           = 11;  // 踢出
+  MSG_ERROR          = 12;  // 错误
+}
+ +

房间状态机

+
+  ┌─────────┐  create   ┌──────────┐  all ready  ┌─────────┐
+  │ CREATED │─────────►│ WAITING   │────────────►│ PLAYING  │
+  └─────────┘          └────┬─────┘             └────┬────┘
+                            │ leave                  │ end
+                     ┌──────▼──────┐          ┌──────▼──────┐
+                     │  ABANDONED  │          │  FINISHED   │
+                     └─────────────┘          └─────────────┘
+
+  房间状态流转规则:
+  - CREATED  -> WAITING:     创建者进入,等待其他玩家
+  - WAITING  -> PLAYING:      所有玩家就绪,房主点击开始
+  - WAITING  -> ABANDONED:    所有玩家离开
+  - PLAYING  -> FINISHED:     游戏结束 (计时到/目标达成/房主终止)
+  - PLAYING  -> WAITING:      回到等待 (仅协作模式)
+  - 任意状态 -> ABANDONED:     超时无活动 30min
+ +

核心数据结构 (Go)

+
// Room 房间结构
+type Room struct {
+    ID           string              `json:"id"`
+    Mode         GameMode            `json:"mode"`          // free_build/puzzle/multiplayer
+    Status       RoomStatus          `json:"status"`        // created/waiting/playing/finished
+    HostUserID   string              `json:"host_user_id"`
+    MaxPlayers   int                 `json:"max_players"`
+    Players      map[string]*Player  `json:"players"`       // userID -> Player
+    CircuitData  []byte              `json:"circuit_data"`  // 当前电路快照 (全量)
+    DeltaQueue   chan CircuitDelta   `json:"-"`             // 增量更新队列
+    SeqCounter   int64               `json:"seq_counter"`   // 消息序号计数器
+    CreatedAt    time.Time           `json:"created_at"`
+    UpdatedAt    time.Time           `json:"updated_at"`
+    mu           sync.RWMutex        `json:"-"`
+}
+
+// Player 玩家连接
+type Player struct {
+    UserID       string          `json:"user_id"`
+    Username     string          `json:"username"`
+    Conn         *websocket.Conn `json:"-"`               // WebSocket 连接
+    IsReady      bool            `json:"is_ready"`
+    Cursor       struct {
+        X int `json:"x"`
+        Y int `json:"y"`
+    } `json:"cursor"`
+    JoinedAt     time.Time       `json:"joined_at"`
+    LastActive   time.Time       `json:"last_active"`
+    SendQueue    chan []byte     `json:"-"`               // 发送队列 (异步写)
+}
+
+// CircuitDelta 电路增量更新
+type CircuitDelta struct {
+    PlayerID  string          `json:"player_id"`
+    OpType    DeltaOpType     `json:"op_type"`            // place/delete/move/rotate/wire
+    Component *ComponentData  `json:"component,omitempty"`
+    Wire      *WireData       `json:"wire,omitempty"`
+    Position  *Position       `json:"position,omitempty"`
+    Tick      int64           `json:"tick"`
+    Seq       int64           `json:"seq"`
+}
+
+// RelayServer 中转服务器
+type RelayServer struct {
+    Rooms      map[string]*Room        // roomID -> Room
+    Players    map[string]*Player      // userID -> Player (全局索引)
+    Register   chan *Player            // 注册通道
+    Unregister chan *Player            // 注销通道
+    Broadcast  chan *BroadcastMsg      // 广播通道
+    Redis      *redis.Client           // Redis (持久化房间状态)
+    Logger     *zap.Logger
+    mu         sync.RWMutex
+}
+ +

核心处理流程伪代码

+
// === WebSocket 连接处理 ===
+func (s *RelayServer) HandleConnection(conn *websocket.Conn, userID string, roomID string) {
+    player := &Player{
+        UserID:   userID,
+        Conn:     conn,
+        SendQueue: make(chan []byte, 256),
+        JoinedAt: time.Now(),
+    }
+    
+    // 1. 注册玩家
+    s.Register <- player
+    
+    // 2. 加入房间
+    room := s.GetOrCreateRoom(roomID)
+    room.AddPlayer(player)
+    
+    // 3. 通知房间内其他玩家
+    room.BroadcastExcept(userID, MSG_PRESENCE, &PresencePayload{
+        UserID: userID, Status: "joined"
+    })
+    
+    // 4. 向新玩家发送当前电路全量快照
+    player.Send(MSG_CIRCUIT_FULL, room.CircuitData)
+    
+    // 5. 启动读写 goroutine
+    go s.writePump(player)
+    s.readPump(player, room)
+}
+
+// === 读取客户端消息 ===
+func (s *RelayServer) readPump(player *Player, room *Room) {
+    defer func() {
+        s.Unregister <- player
+        room.RemovePlayer(player.UserID)
+        room.BroadcastExcept(player.UserID, MSG_PRESENCE, &PresencePayload{
+            UserID: player.UserID, Status: "left"
+        })
+        player.Conn.Close()
+    }()
+    
+    for {
+        _, message, err := player.Conn.ReadMessage()
+        if err != nil {
+            break  // 连接断开
+        }
+        
+        var msg ClientMessage
+        proto.Unmarshal(message, &msg)
+        
+        switch msg.MsgType {
+        case MSG_CIRCUIT_DELTA:
+            // 应用增量到房间电路快照
+            delta := parseDelta(msg.Payload)
+            room.ApplyDelta(delta)
+            // 广播给房间内其他玩家
+            room.BroadcastExcept(msg.UserId, MSG_CIRCUIT_DELTA, msg.Payload)
+            
+        case MSG_CHAT:
+            room.BroadcastAll(MSG_CHAT, msg.Payload)
+            
+        case MSG_CURSOR:
+            room.BroadcastExcept(msg.UserId, MSG_CURSOR, msg.Payload)
+            
+        case MSG_ACTION:
+            // 游戏操作需服务端校验 (多人对战模式)
+            if room.Mode == GameModeMultiplayer {
+                if !s.ValidateAction(room, msg) {
+                    player.Send(MSG_ERROR, &ErrorPayload{Code: "invalid_action"})
+                    continue
+                }
+            }
+            room.BroadcastAll(MSG_ACTION, msg.Payload)
+            
+        case MSG_HEARTBEAT:
+            player.LastActive = time.Now()
+            player.Send(MSG_HEARTBEAT, &HeartbeatPayload{ServerTs: time.Now().UnixMilli()})
+        }
+    }
+}
+
+// === 断线重连 ===
+func (s *RelayServer) HandleReconnect(userID string, roomID string, conn *websocket.Conn) {
+    room, ok := s.Rooms[roomID]
+    if !ok {
+        // 房间已不存在
+        conn.WriteMessage(MSG_ERROR, encodeError("room_not_found"))
+        return
+    }
+    
+    player, ok := room.Players[userID]
+    if ok {
+        // 旧连接还存在,关闭旧连接
+        oldConn := player.Conn
+        player.Conn = conn
+        close(player.SendQueue)
+        player.SendQueue = make(chan []byte, 256)
+        oldConn.Close()
+    } else {
+        // 玩家已被清理,重新加入
+        player = &Player{
+            UserID: userID, Conn: conn,
+            SendQueue: make(chan []byte, 256),
+        }
+        room.AddPlayer(player)
+    }
+    
+    // 发送重连成功 + 当前全量快照 + 最近 50 条消息
+    player.Send(MSG_RECONNECT, &ReconnectPayload{
+        Success:    true,
+        CircuitSnapshot: room.CircuitData,
+        RecentMsgs: room.GetRecentMessages(50),
+        Players:    room.GetPlayerList(),
+    })
+    
+    go s.writePump(player)
+    go s.readPump(player, room)
+}
+
+// === 房间广播 ===
+func (r *Room) BroadcastExcept(userID string, msgType MessageType, payload []byte) {
+    r.mu.RLock()
+    defer r.mu.RUnlock()
+    
+    r.SeqCounter++
+    msg := &ServerMessage{
+        MsgType:   int32(msgType),
+        Payload:   payload,
+        ServerTs:  time.Now().UnixMilli(),
+        Seq:       r.SeqCounter,
+    }
+    data, _ := proto.Marshal(msg)
+    
+    for _, player := range r.Players {
+        if player.UserID == userID {
+            continue
+        }
+        select {
+        case player.SendQueue <- data:
+        default:
+            // 队列满,关闭连接
+            close(player.SendQueue)
+            delete(r.Players, player.UserID)
+        }
+    }
+}
+ +

P2P 打洞与 TURN 中继

+
+ + + + + + + + + + + +
阶段行为协议超时
1. ICE 候选收集客户端收集本地/反射/中继候选地址STUN (UDP)5s
2. 候选交换通过 relay-server WebSocket 交换 SDP 和 ICE 候选WebSocket3s
3. 连接检查ICE 对每对候选地址进行连通性检查STUN Binding10s
4a. P2P 直连成功后续游戏数据走 P2P 通道,relay 仅维持信令UDP (P2P)-
4b. P2P 失败 -> TURN分配 TURN 中继地址,所有数据经 TURN 转发TURN (UDP)-
4c. TURN 失败 -> WSS回退到 WebSocket 中心化转发WebSocket-
5. 心跳保活P2P 模式每 15s 发 STUN Binding 保活;WSS 模式 30s 心跳STUN / WS60s 无响应断开
+
+ +

断线重连策略

+
+ + + + + + + + + +
断线时长客户端行为服务端行为恢复方式
<5s自动重连,缓存消息保留房间和玩家状态WebSocket 重连 + 增量同步
5-30s显示"重连中..."UI标记玩家为"暂离",保留位置重连 + 全量快照 + 最近 50 条消息
30s-3min重试退避 (1s/2s/4s/8s)保留房间,玩家标记"掉线"重连 + 全量快照
3-30min提示"连接超时"房间保留,玩家可手动重连重新加入房间
>30min-房间超时回收,玩家移除需重新创建/加入房间
+
+ +

水平扩展方案

+
+ + + + + + + + + + +
组件方案说明
负载均衡L4 TCP 负载均衡 (HAProxy / Nginx stream)WebSocket 长连接用最少连接策略;sticky session by userID
跨节点消息Redis Pub/Sub房间内玩家可能连在不同 relay 节点;消息先发 Redis channel,各节点订阅自己管理的房间
房间状态持久化Redis Hash (room:{id})房间元数据 + 玩家列表持久化,节点故障后可恢复
电路快照存储Redis (热) + MinIO (冷)活跃房间电路快照存 Redis;房间结束后归档 MinIO
连接亲和性Consistent Hash by roomID同一房间的玩家尽量路由到同一 relay 节点,减少跨节点转发
优雅缩容drain 模式节点标记 draining 后拒绝新连接,等现有连接自然结束或迁移
+
+ +

监控指标

+
+ + + + + + + + + + + + +
指标Prometheus Metric告警阈值
在线 WebSocket 连接数relay_connections_total>4500 (单节点)
活跃房间数relay_rooms_active>180
消息转发延迟 P99relay_msg_latency_seconds (histogram)>50ms
消息丢失率relay_msg_drop_rate>0.1%
P2P 打洞成功率relay_p2p_success_rate<70%
TURN 中继流量relay_turn_bytes_total (counter)月预算阈值告警
断线重连成功率relay_reconnect_success_rate<90%
goroutine 数量go_goroutines>10000
+
+ +

开发任务分解

+
+ + + + + + + + + + + + + + + +
任务Sprint人日依赖
WebSocket 连接管理 + 读写 goroutine + 心跳S113
房间状态机 + 玩家管理 + 广播机制S114WS 连接管理
Protobuf 消息协议定义 + 编解码S112
电路增量同步 (delta apply + broadcast)S114房间管理
断线重连 + 全量快照恢复S123增量同步
STUN/TURN 服务集成 + ICE 候选交换S125WS 连接管理
Redis Pub/Sub 跨节点消息S123房间管理
游戏操作服务端校验 (多人对战)S123增量同步
Prometheus 指标埋点 + Grafana 看板S122WS 连接管理
压力测试 (5000 连接 + 200 房间)S163全部功能完成
合计-32-
+
+
+ + +
+

19 / TESTING

+

测试与质量保障

+

四层测试体系:单元测试、集成测试、性能测试、E2E 测试,覆盖客户端与服务端。

+ +

19.1 测试分层

+
+ + + + + + + + +
层级覆盖率目标工具运行频率负责人
单元测试>=80%Unity Test Framework (客户端) / Go testing (服务端)每次 PR开发人员
集成测试核心链路 100%Go test + Docker Compose / Unity PlayMode每日 NightlyQA + 开发
性能测试关键指标达标Unity Profiler / k6 / wrk每 SprintQA
E2E 测试主流程 100%Unity PlayMode + API 自动化每 SprintQA
+
+ +

19.2 仿真引擎单元测试用例

+
+ + + + + + + + + + + + + + +
用例编号测试场景输入预期输出
SIM-001红石粉信号衰减电源(15) + 15 格红石粉第 15 格强度=1,第 16 格=0
SIM-002中继器重置强度衰减至 1 的信号经中继器中继器输出强度=15
SIM-003AND 门真值表4 种输入组合 (00/01/10/11)输出 0/0/0/1
SIM-004红石火把反相附着方块有信号火把熄灭,无输出
SIM-005中继器锁存侧面输入信号时输出冻结在当前状态
SIM-006活塞推动链13 个连续方块推动失败(超过 12 个上限)
SIM-007短路检测两个电源直连同一导线触发短路警告,仿真暂停
SIM-008555 无稳态振荡R=10, C=4输出方波,周期 = 0.693*(R1+R2)*C tick
SIM-009运放反相放大Vin=5, Rf=10, R1=5Vout = -10
SIM-010ADC 4-bit 转换模拟输入强度=13数字输出 = 1101
+
+ +

19.3 性能指标与压测目标

+
+ + + + + + + + + + + + + +
场景指标目标值工具
客户端 - 小型电路 (50 元件)仿真 FPS>=60 fpsUnity Profiler
客户端 - 大型电路 (500 元件)仿真 FPS>=30 fpsUnity Profiler
客户端 - 超大画布 (512x512)渲染 FPS>=30 fpsUnity Profiler
客户端 - 内存占用峰值内存<=1GBUnity Memory Profiler
服务端 - 登录接口P99 延迟<=100mswrk
服务端 - 商店购买P99 延迟<=200mswrk
服务端 - 并发用户最大并发>=5000k6
多人同步 - 画布编辑端到端延迟<=200ms自定义压测脚本
多人同步 - 匹配等待平均等待<=30s日志统计
+
+ +

19.4 Bug 分级与响应 SLA

+
+ + + + + + + + +
级别定义响应时间修复时限
P0 阻塞崩溃/数据丢失/核心功能不可用/安全漏洞30 分钟24 小时内
P1 严重核心功能异常/性能严重退化/支付错误2 小时当前 Sprint 内
P2 一般非核心功能异常/UI 错位/文案错误1 个工作日下个 Sprint
P3 轻微体验优化/建议类3 个工作日Backlog 排期
+
+
+ + +
+

20 / PERFORMANCE

+

性能优化方案

+

客户端、服务端、网络三个维度的具体优化措施与实施节点。

+ +

20.1 客户端优化

+
+ + + + + + + + + + + + +
优化项问题方案实施节点
ECS 仿真大电路 GameObject 方式导致 GC Spike仿真数据迁移至 ECS (Entities 1.0),元件数据用 IComponentData,信号传播用 IJobChunkS4 仿真引擎重构
分块渲染512x512 画布全量渲染卡顿16x16 Chunk + 视口裁剪,仅渲染可见区域 + 1 格缓冲S2 画布开发时
信号轨迹 GPU 绘制每格信号线逐个 GameObject 性能差ComputeBuffer + 自定义 Shader,全画布信号轨迹一次 DrawCallS4 仿真引擎 v2
对象池放置/删除元件频繁 Instantiate/Destroy预生成 500 个元件 GameObject 池,按需取用/归还S2 画布开发时
仿真分帧大电路单 tick BFS 导致主线程阻塞BFS 分帧执行,每帧最多 2000 格更新,跨帧续传S4 仿真引擎 v2
LOD 降级全景浏览时细节渲染浪费 GPU缩放 <50% 时元件降级为纯色方块,关闭信号动画S15 UI 打磨
纹理图集80 种元件图标各自纹理导致 DrawCall 多所有元件图标打包为 1024x1024 Atlas,单次 DrawCallS7 元件填充时
异步加载关卡数据/蓝图加载阻塞主线程JSON 反序列化放入 async Task,加载完成回调切换S6 关卡系统
+
+ +

20.2 服务端优化

+
+ + + + + + + + + + +
优化项问题方案实施节点
Redis 余额缓存每次请求查 PostgreSQL 余额慢余额写入 Redis Cache-Aside,写操作回写 DB + 失效缓存S8 货币系统
连接池数据库频繁建连开销大pgxpool 连接池,最大 25 连接/服务,空闲 60s 回收S5 认证系统
排行榜 ZSET排行榜分页查询慢Redis Sorted Set 存储积分排名,ZREVRANGE 分页S12 多人对战
蓝图搜索 ESPostgreSQL LIKE 搜索全表扫描蓝图数据同步至 Elasticsearch,支持全文搜索+标签过滤S13 蓝图工坊
API 限流恶意刷接口Nginx 层 rate_limit 100req/min/IP;关键接口令牌桶 10req/s/userS5 认证系统
异步任务队列成就检查/经济结算阻塞请求RabbitMQ 消费者异步处理,请求仅入队即返回S8 货币系统
+
+ +

20.3 网络优化

+
+ + + + + + + + + +
优化项方案效果
Delta 同步多人编辑仅同步变更的格子和元件,非全量画布带宽减少 90%+
Protobuf 编码实时同步消息用 Protobuf 替代 JSON消息体积减少 60%+
WebSocket 压缩开启 permessage-deflate 压缩带宽减少 50%+
客户端预测元件放置/删除本地立即生效,服务端确认后修正操作延迟感知 <50ms
断线重连WebSocket 断开 30s 内重连,恢复画布状态用户体验连续
+
+
+ + +
+

21 / SECURITY

+

安全实施方案

+

认证安全、数据安全、反作弊、基础设施安全四层防护体系。

+ +

21.1 认证与授权

+
+ + + + + + + + + + +
措施实现方式说明
密码加密bcrypt cost=12服务端加盐哈希,不可逆
JWT TokenRS256 签名,Access 15min + Refresh 7dAccess Token 无状态;Refresh Token Redis 黑名单
登录保护5 次错误锁定 15min + IP 限流防止暴力破解
异地登录验证新设备/新IP 邮箱二次验证码6 位数字验证码,5min 有效
OAuth 第三方Google/GitHub/Discord OAuth2不存储第三方密码,仅存 provider+providerId
API 鉴权Bearer Token + RBAC 权限校验每个接口声明所需角色,中间件统一校验
+
+ +

21.2 数据安全

+
+ + + + + + + + + + + +
措施实现方式
传输加密全站 HTTPS TLS 1.3;WebSocket over TLS (wss)
敏感数据加密邮箱/手机号 AES-256-GCM 加密存储;密钥 KMS 管理
SQL 注入防护Go ORM 参数化查询,禁止字符串拼接 SQL
XSS 防护蓝图描述/用户名等 UGC 内容 HTML 转义后存储
CSRF 防护SameSite=Strict Cookie + CSRF Token 双重防护
数据备份PostgreSQL 每日全量 + WAL 实时归档;7 日保留期
GDPR 合规支持账号注销+数据导出;隐私政策明确告知数据用途
+
+ +

21.3 反作弊系统

+
+ + + + + + + + + + +
场景检测方式处理措施
解谜作弊服务端校验电路数据合法性 + 输出验证拒绝奖励,记录异常行为
货币刷取产出频率监控 + 行为模式分析异常产出冻结账户,人工审核
多人对战作弊关键操作服务端权威校验 + 客户端预测修正判定无效,扣除积分,封禁 7 天
蓝图抄袭蓝图哈希比对 + 相似度算法下架抄袭蓝图,警告作者
客户端修改代码混淆 + 关键逻辑服务端校验 + 完整性校验完整性校验失败拒绝登录
黑产刷币交易频率监控 + IP 设备指纹 + 金额异常检测冻结资产,IP 封禁,上报风控
+
+
+ + +
+

22 / CI/CD

+

CI/CD 流水线

+

从代码提交到生产部署的自动化流水线配置。

+ +

22.1 流水线阶段

+
+ + + + + + + + + + + +
阶段触发任务预计时长
Lint & BuildPR / PushGo vet + golangci-lint;Unity Build;编译检查3 min
Unit TestPR / PushGo test -race -cover;Unity EditMode + PlayMode Test5 min
Integration TestPush to mainDocker Compose 启动全链路;API 集成测试8 min
Build ArtifactsPush to main / TagGo 二进制编译;Unity 客户端打包(Win+Mac)15 min
Deploy StagingPush to mainDocker 镜像推 Harbor;K8s 滚动更新 Staging5 min
Smoke TestDeploy Staging 后核心接口可用性检查;客户端启动测试3 min
Deploy ProductionTag v* 手动触发人工确认 -> K8s 滚动更新 Production5 min
+
+ +

22.2 环境配置

+
+ + + + + + + + +
环境用途数据库部署方式
Local开发调试SQLite + 本地 Redisdocker-compose dev
Staging集成测试 + QA 验收PostgreSQL(单机) + Redis(单机)K8s staging namespace
Beta封闭/开放 Beta 测试PostgreSQL(主从) + Redis(哨兵)K8s beta namespace (2 副本)
Production正式生产PostgreSQL(主从+读写分离) + Redis(集群)K8s production namespace (3+ 副本 + HPA)
+
+ +

22.3 发布与回滚

+
+ + + + + + + + + + +
操作方式预计耗时
正常发布Git Tag -> CI 自动构建 -> K8s 滚动更新(零停机)15-20 min
热修复hotfix 分支 -> 快速 CI -> 直接部署 Production10-15 min
紧急回滚kubectl rollout undo deployment/xxx --to-revision=N2 min
数据库回滚Migration down 脚本 + WAL 恢复15 min
客户端热更新配置/数值/关卡 JSON 增量下发即时
客户端全量更新官网安装包替换 + 增量补丁用户下次启动
+
+
+ + +
+

23 / BUDGET

+

预算与成本估算

+

9 个月开发期 + 首年运营期的成本估算(人民币)。

+ +

23.1 人力成本

+
+ + + + + + + + + + + +
阶段人数月数人均月薪小计
Phase 1 (M1-2)4225,000200,000
Phase 2 (M3-5)8325,000600,000
Phase 3 (M6-8)12325,000900,000
Phase 4 (M9)12125,000300,000
开发期合计-9-2,000,000
首年运营 (M10-12)10325,000750,000
总计首年-12-2,750,000
+
+ +

23.2 基础设施成本(月度)

+
+ + + + + + + + + + + + + + + +
项目规格月费用备注
应用服务器8C16G x3 (K8s 节点)3,600阿里云 ECS
数据库PostgreSQL 8C32G 主从4,500RDS 高可用版
Redis4G 集群版800阿里云 Redis
对象存储MinIO/OSS 500GB500蓝图文件+截图
CDN1TB/月 流量500更新包+静态资源
消息队列RabbitMQ 2C4G600异步任务
Elasticsearch2C8G1,200蓝图搜索
监控+日志Prometheus+Grafana+ELK1,500自建+云服务混合
域名+SSLredcircuit.game + 通配符证书100年费摊月
月度合计-13,300-
首年合计-159,600-
+
+ +

23.3 其他成本

+
+ + + + + + + + + + + +
项目费用说明
Unity 订阅0Unity Personal 免费版(年收入 <20万刀);Pro 版 $204/月/座 (年收入超限后)
开发工具20,000Figma Pro + JetBrains IDE + 其他工具年费
第三方服务15,000邮件服务/SMS 验证码/OAuth/API 网关
美术外包80,000部分元件图标/特效/UI 切图外包
QA 外包30,000Beta 测试期间外包测试
营销推广100,000首发推广+B 站/KOL 合作
其他合计245,000-
+
+ +

23.4 总预算汇总

+
+ + + + + + + + + + +
类别金额占比
人力成本2,750,00087%
基础设施159,6005%
其他成本245,0008%
总计首年预算3,154,600100%
建议预留缓冲 (15%)473,190-
建议总预算3,627,790-
+
+
+ + +
+

24 / ROLLOUT

+

上线发布策略

+

分阶段灰度发布、数据监控、应急预案与运营节奏。

+ +

24.1 灰度发布计划

+
+ + + + + + + + + +
阶段时间用户量目标通过标准
内测 AlphaM5 结束团队 20 人核心功能验证P0 Bug 清零
封闭 BetaM8 结束500 人邀请制全功能验证 + 压力测试P0/P1 清零;留存 >30%
开放 BetaM9 W1-25,000 人公开注册服务器压测 + 数据收集5000 并发稳定;P0 清零
正式发布M9 W3全网开放商业化运营启动首周 DAU >5,000;留存 >35%
推广期M10+持续增长KOL 推广 + 社区运营MAU >50,000
+
+ +

24.2 发布日监控清单

+
+ + + + + + + + + + + + + +
监控项工具告警阈值负责人
服务器 CPUPrometheus>80% 持续 5min服务端工程师
服务器内存Prometheus>85% 持续 5min服务端工程师
API P99 延迟Grafana>500ms服务端工程师
API 错误率Sentry>1%服务端工程师
客户端崩溃率Sentry>2%客户端工程师
WebSocket 连接数Grafana>4000服务端工程师
数据库慢查询pg_stat_statements>1sDBA / 服务端
登录成功率Grafana<95%QA
支付成功率Grafana<98%QA + 运营
+
+ +

24.3 应急预案

+
+ + + + + + + + +
故障等级触发条件响应流程恢复目标
S1 严重故障全服不可用 / 数据丢失 / 支付异常电话通知全员 -> 紧急 War Room -> 修复 -> 事后复盘1 小时内恢复
S2 主要故障核心功能不可用 / 性能严重退化飞书告警 -> 值班工程师处理 -> 升级判断4 小时内恢复
S3 一般故障非核心功能异常 / 少数用户受影响工单系统 -> 工作时间内处理24 小时内恢复
回滚预案新版本引入严重 Bugkubectl rollout undo -> 数据库回滚 -> 客户端提示旧版10 分钟内回滚完成
+
+ +

24.4 首年运营节奏

+
+ + + + + + + + +
月份运营重点内容更新活动
M9 发布月稳定性保障 + 新手引导优化240 关 + 80 元件首发首发七日登录奖励
M10数据驱动调优 + 社区建设限时活动关卡 20 关万圣节主题电路设计赛
M11赛季 1 启动 + 蓝图生态新增元件 5 种 + 赛季排行赛季 1 排位赛 + 双倍红石币周末
M12留存提升 + 平衡性补丁大师关卡 +10 关 + 蓝图审核优化圣诞/元旦限定皮肤 + 年度总结
+
+
+ + +
+

25 / APPENDIX

+

附录

+

元件成本速查表与常见电路设计模式参考。

+ +

A. 元件成本速查表

+

全部元件按成本升序排列,便于快速查阅预算规划。共 80 种元件。

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
序号编号元件名类别成本(红石币)
1W-01红石粉WIRE5
2O-13LEDOUTPUT15
3W-04绝缘导线WIRE15
4W-06铜导线WIRE12
5A-01电阻ANALOG20
6W-07跳线WIRE18
7W-05信号桥WIRE25
8S-11拨动开关SWITCH25
9P-03拉杆POWER30
10S-03拉杆SWITCH30
11P-05压力板POWER35
12S-04压力板木质SWITCH35
13O-14蜂鸣器OUTPUT35
14P-04按钮POWER40
15S-01按钮木质SWITCH40
16S-02按钮石质SWITCH40
17P-09直流电源POWER40
18A-04二极管ANALOG45
19S-07绊线钩SWITCH45
20P-01红石火把POWER50
21S-05压力板铁质SWITCH50
22O-10门(木)OUTPUT50
23A-05稳压管ANALOG55
24O-12灯笼OUTPUT55
25A-02电容ANALOG60
26O-01红石灯OUTPUT60
27O-11活板门OUTPUT60
28S-10标靶SWITCH60
29A-03电感ANALOG70
30O-07音符盒OUTPUT70
31P-08探测铁轨POWER70
32P-10电池组POWER85
33W-02红石中继器WIRE80
34S-06压力板金质SWITCH80
35O-09门(铁)OUTPUT80
36O-15数码管OUTPUT90
37P-06阳光探测器POWER90
38P-07阳光探测器(夜)POWER90
39S-08阳光探测器SWITCH90
40P-02红石块POWER100
41O-06漏斗OUTPUT100
42L-08中继器逻辑LOGIC100
43S-12继电器SWITCH120
44W-03红石比较器WIRE120
45O-05投掷器OUTPUT120
46X-05信号分配器SPECIAL120
47S-09观察者SWITCH150
48O-02活塞OUTPUT150
49L-01NOTLOGIC150
50X-04信号延迟器SPECIAL150
51A-09光耦ANALOG160
52O-04发射器OUTPUT180
53A-06NPN 三极管ANALOG180
54A-07PNP 三极管ANALOG180
55PD-04MOS 管POWER_DEVICE200
56O-03粘性活塞OUTPUT200
57L-02ANDLOGIC200
58L-03ORLOGIC200
59PD-01单向可控硅 SCRPOWER_DEVICE220
60L-04NANDLOGIC220
61L-05NORLOGIC220
62PD-06继电器模组POWER_DEVICE250
63L-06XORLOGIC250
64L-07XNORLOGIC250
65X-06物品过滤器SPECIAL250
66PD-02双向可控硅 TRIACPOWER_DEVICE280
67A-08运算放大器ANALOG280
68PD-05达林顿管POWER_DEVICE300
69O-08TNTOUTPUT300
70X-03信号示波器SPECIAL300
71X-10555 定时器SPECIAL350
72L-09RS锁存器LOGIC350
73L-10D触发器LOGIC400
74X-07物品分类器SPECIAL400
75PD-03IGBTPOWER_DEVICE420
76X-08ADC 模数转换器SPECIAL450
77X-09DAC 数模转换器SPECIAL450
78L-11计数器LOGIC500
79X-02结构方块SPECIAL800
80X-01命令方块SPECIAL1000
+
+ +

B. 常见电路设计模式

+
+ + + + + + + + + + + + +
模式核心元件用途
T 触发器RS 锁存器 + 边沿检测按钮单次脉冲切换开关状态
时钟发生器中继器环形振荡产生周期性脉冲信号
脉冲缩短器比较器 + 中继器将长脉冲截断为单 tick 短脉冲
脉冲延长器多级中继器链延长脉冲持续时间
二进制计数器D 触发器级联多 Bit 二进制计数与溢出进位
优先编码器OR 门阵列 + NOT多输入中输出最高优先级
边沿检测器比较器 + 中继器检测信号上升沿或下降沿
数据选择器 MUXAND + OR + NOT按控制端选择多路输入之一输出
+
+
+ +
+
+ +
+

RedCircuit · 红石回路 - 完整开发文档 v1.0

+

© 2026 RedCircuit Studio. 保留所有权利。

+

文档生成日期:2026-08-07 | 机密文档仅供内部使用

+
+ + +