你可以在Releases页面下载编译好的版本,下载适用于你的系统及架构的版本后直接运行即可。
scripts/build.sh # 构建当前平台(产物在 dist/)
scripts/build.sh --all # 交叉编译全部常用平台
go run ./cmd/gmcs # 运行;首次启动生成 gmcs.json 与 world/构建产物为纯 Go 静态二进制(
CGO_ENABLED=0、-trimpath、剥离符号)并默认启用 PGO(配置随仓库提交,scripts/genpgo.sh可重新生成;PGO=off可关闭)。 性能与产物体积数据见 PERFORMANCE.md。
首次运行自动生成;缺失字段回退默认值;命令行 -listen 可覆盖监听地址。
| 字段 | 说明 | 默认值 |
|---|---|---|
listen_address |
TCP 监听地址 | :25565 |
motd |
服务器列表消息 | A gmcs 1.21.11 development server |
version_name |
列表中显示的版本名 | gmcs-1.21.11 |
protocol_version |
协议号(同时用于拒绝不兼容客户端) | 774 |
max_players |
列表显示的最大玩家数 | 100 |
max_connections |
最大并发连接数 | 256 |
view_distance |
发送给客户端的视距(区块,2–32) | 10 |
world_dir |
地图数据目录 | world |
world_seed |
地形生成种子(首次启动随机生成并固定) | 随机 |
world_border_size |
世界边界边长(方块,正方形,以 0,0 为中心;0 不限制) | 0 |
game_mode |
新玩家的游戏模式(survival/creative/adventure/spectator) | survival |
spawn_monsters |
是否在玩家附近生成敌对生物 | true |
max_mobs |
同时存在的生物上限(0 表示不生成) | 8 |
autosave_seconds |
自动保存间隔(秒,0 表示禁用) | 300 |
online_mode |
启用正版验证(通过会话服务器确认账号) | false |
enforce_secure_profile |
强制安全档案(正版模式下校验聊天消息签名,缺失或非法签名按原版断开连接;离线模式忽略) | true |
session_server_url |
会话验证服务基地址(在线模式使用) | https://sessionserver.mojang.com |
starting_items |
新玩家初始物品(命名空间 ID;name 或 name*数量,数量上限 64;可写数组或单个字符串) |
["minecraft:stone"] |
ops |
管理员玩家名列表(使用管理命令;项可写 name(等价 4 级)或 name:level(1–4);可写数组或单个字符串) |
[] |
permissions |
细粒度命令权限节点(按玩家名,大小写不敏感;"*" 表示所有玩家;支持 gmcs.command.* 前缀通配与 * 全通配) |
{} |
log_file |
服务器日志文件(按大小轮转,空值只输出控制台) | logs/gmcs.log |
log_level |
日志级别(debug/info/warn/error) | info |
log_max_size_mb |
日志轮转大小(MiB;超过后当前文件重命名为 <文件>.1) |
16 |
audit_log_file |
审计日志文件(JSONL:聊天/命令/加入退出/击杀等,空值禁用) | logs/audit.jsonl |
pprof_address |
pprof 诊断监听地址(如 127.0.0.1:6060,空值表示关闭;仅本地诊断,勿暴露公网) |
"" |
进入世界后可在聊天栏使用(已通过 Declare Commands 向客户端声明):
| 命令 | 说明 |
|---|---|
/help |
显示可用命令 |
/list |
列出在线玩家 |
/spawn |
传送回出生点 |
/seed |
显示世界种子(需要权限等级 2) |
/say <消息> |
向所有玩家广播消息(需要权限等级 2) |
/gamemode <模式> |
切换游戏模式(survival/creative/adventure/spectator,等级 2) |
/tp <x> <y> <z> 或 /tp <玩家> |
传送到坐标或在线玩家(含其所在维度,等级 2) |
/give <物品> [数量] |
给予物品(带/不带 minecraft: 前缀;放不下时掉落,等级 2) |
/time set <day|noon|night|midnight|tick> / /time add <tick> / /time query |
查询/修改世界时间(等级 2) |
/weather <clear|rain|thunder> [秒] |
设置天气(省略秒数时按原版区间随机,等级 2) |
/xp add <数量> |
增加经验值(等级 2) |
/clear [玩家] |
清空物品栏(等级 2) |
/kick <玩家> |
踢出在线玩家(等级 3) |
/kill [玩家] |
击杀玩家(走正常死亡流程,等级 3) |
/dimension <overworld|the_nether|the_end> |
传送到目标维度出生点(等级 3) |
/save-all |
立即保存全部已加载世界(等级 3) |
命令补全(Tab)覆盖命令名、
/gamemode//time//weather//dimension参数与/kick//tp//clear//kill在线玩家名,聊天输入时还会补全在线玩家名;ops名单项支持name(等价 4 级)或name:level(1–4 级),命令树按玩家等级过滤并在执行时再次校验 (/say、/gamemode、/seed、/tp、/give、/time、/weather、/xp、/clear需 2 级,/kick、/kill、/dimension、/save-all需 3 级;/help、/list、/spawn所有玩家可用)。 也可以不改ops,而在permissions中按玩家授予权限节点(如"permissions": {"Alice": "gmcs.command.gamemode", "*": "gmcs.command.spawn"}): 拥有节点即可使用对应命令,节点形式为gmcs.command.<命令名>。
点击展开查看详情
- 种子地形(
world_seed):大陆度/山脊/丘陵/细节噪声高度图(深海—平原—山地)、 河流(海平面附近的河道切口)、深板岩(y<0)、水(海平面约 Y=62)与生物群系 (雪原/针叶林/平原/森林/桦木林/深色橡木林/沼泽/沙漠/恶地/稀树草原/丛林/草甸/ 雪坡/冻峰/石峰/河流/沙滩/石岸/雪滩/海洋/深海等 24 种,按温度、湿度与海拔划分, 4×4 格分辨率随区块数据下发);群系化地表与植被(草/沙/红沙/陶瓦条带/雪/砾石、 橡树/云杉/桦木/深色橡木/丛林/金合欢/仙人掌/甘蔗/向日葵/莉花等)。 同种子同坐标结果恒定,出生点在世界边界内搜索陆地(候选列要求玩家碰撞盒 不与任何碰撞形状相交且脚下确有支撑面,栅栏/墙/箱子顶面之类的列会被跳过; 恢复存档时若位置被方块占据,会先向上推、再就近寻找可站立空位)。 - 树叶衰减:玩家放置的树叶为
persistent=true,永不衰减;自然树叶在原木 或树叶被移除(含爆炸摧毁)时对周围 15³ 做一次“6 格内是否仍有原木”的判定, 没有则按方块战利品表掉落(树苗/木棍等)并立即消失(原版用distance属性 逐格扩散,最多约 14 tick,gmcs 表现为砍完即刻消失)。 - 洞穴与矿物:3D 噪声大型洞穴(cheese caves)与随机游走隧道(worm),保留 地表密封与基岩层;8 种矿物随机游走成脉(煤/铜/铁/金/红石/钻石/青金石/绿宝石, y<0 时为深板岩变种)。观感与原版相近,但不是原版算法。
- 多维度:主世界/下界/末地三套独立世界,按需生成与持久化(主世界使用
world/,下界/末地为world/the_nether/、world/the_end/子目录):下界含 基岩地板(y=0)与天花板(y=127)、净岩、岩浆海、石英/远古残骸矿物与萤石/灵魂沙/ 玄武岩装饰;末地含主岛(末地石、黑曜石柱)、外岛与虚空。玩家所在维度随players.json持久化,重连恢复;跨维度切换用/dimension或下界/末地传送门。 - 传送门:下界传送门(黑曜石框 2×3–21×21,打火石点燃;进入按 1:8 坐标缩放传送, 到达侧无门时自动建造出口,带冷却与音效,回程双向)与末地传送门(12 个末地传送门 框架 + 末影之眼激活后进入末地,第一次进入生成出口平台;从末地返回主世界出生点); 破坏框架会清除附近的传送门方块。
- 区块流式加载:进入世界按由近到远发送视距内的区块;发送前用后台预生成 (8 个 worker + 请求去重)并行准备区块,预取范围比发送范围多一圈(视距+1), 跨区块移动时下一批区块已在后台就绪;跨区块移动时增量发送、超出 视距+2 卸载; 每 5 秒把距所有玩家超过 视距+4 的区块移出内存(未保存先落盘),连续超出 15 秒宽限后才真正卸载(玩家在卸载边界来回移动不会反复加载/卸载/写盘); 无玩家的已打开维度空闲 30 秒后释放全部区块(脏区块先落盘);所有玩家退出后 立即释放全部区块、区块帧缓存与区域文件句柄(未保存先落盘),跑图与空闲都 不会让内存持续增长。区块突发以 Chunk Batch Start/Finished 标记(客户端据此 调整加载速率;暂未按客户端回报速率限流)。
- heightmap:区块数据携带 WORLD_SURFACE/MOTION_BLOCKING 高度图(方块修改 即时生效),供客户端渲染与光照使用。
- 世界边界(
world_border_size):正方形、以 (0,0) 为中心;下发官方边界包, 越界位置被拉回,生物不会生成或移动出边界。 - 更换
world_seed不会重建已有区块,交界处可能出现地形突变;需要全新地形时 换用新的world_dir。
- 敌对生物五种:僵尸(追踪 32 格、近战 2 点)、骷髅(保持 3–16 格距离射箭,
箭矢 2 点伤害)、苦力怕(靠近 3 格点燃 1.5 秒引信后爆炸:半径 3 格摧毁方块,
6 格内线性衰减最多 24 点伤害与击退)、蜘蛛(速度更快、近战 2 点)、
末影人(40 点生命,被注视或受击后仇恨并随机瞬移,末地生成,掉落末影珍珠)。
被动生物三种:牛/猪/羊(白天地表草地方生成)。僵尸/骷髅 20 点生命,蜘蛛 16 点;
敌对生物在夜晚(世界时间 13000–23000)或下界/末地生成,玩家周围 24–36 格按权重
生成,直至
max_mobs;距所有玩家超过 64 格清理(服务器无玩家时不清理); 创造/旁观不参与索敌。 - 近战生物进入 1.9 格且视线无遮挡时先抬手 0.5 秒再造成伤害;无目标时游荡; A 寻路*(地表 4 邻接网格:绕开墙壁/地形障碍、上跳 1 格、下落最多 3 格, 每 10 tick 重算;被完全堵住时随机侧移);爆炸会摧毁半径内的方块 (基岩/黑曜石等高抗性方块除外,无掉落),并对范围内生物按距离结算伤害 (可致死并走正常掉落)、击飞范围内的掉落物。
- 昼夜循环:24000 tick(20 分钟)一天,进入世界与每 20 tick 同步世界时间;
/time set|add|query可查询与修改。无光照引擎,因此刷怪只看时间、不看亮度 (洞穴内白天不刷怪)。 - 天气:主世界按原版
advanceWeatherCycle周期推进下雨与雷暴 (下雨 3600–15600 tick、放晴 12000–180000 tick,雷暴同理),强度以 0.01 步进平滑并广播 Game Event 1/2/7/8;/weather clear|rain|thunder [秒]可手动 指定。降雨只影响主世界:浇灭火焰、阻止火焰蔓延、清除玩家与生物身上的火、 滋润耕地(isRainingAt= 下雨 + 看得到天空 + 上方无阻挡方块)。 未实现闪电、炼药锅积水与积雪、群系降水类型;天气不持久化(重启后晴朗)。 - 数值:玩家 20 点生命;玩家攻击 4 点,下落中攻击为跳跃暴击(×1.5);受击无敌帧 0.5 秒与击退;掉落物:僵尸 0–2 腐肉与稀有铁锭/胡萝卜/土豆、骷髅骨头与箭、 苦力怕火药、蜘蛛线/蜘蛛眼、末影人末影珍珠、牛皮革/牛肉、猪猪排、羊白色羊毛/羊肉; 击杀获得的经验以经验球形式掉落(僵尸 5 点,按原版拆分表拆成 3+1+1 三个球)。
- 饥饿系统:疾跑/跳跃/攻击/受伤积累疲劳度(每 4 点消耗 1 点饥饿值);饥饿值 ≥18 时 每 4 秒恢复 1 点生命(优先消耗饱食度),饥饿值归零后每 4 秒受 1 点饥饿伤害(最低到 1); 长按右键 1.6 秒完成进食(切换槽位/松开使用键中断),恢复饥饿与饱食度 (数值来自官方物品数据,共 44 种食物)。
- 经验与经验球:击杀生物掉落经验球(原版拆分表 2477/1237/…/3/1;同值经验球 合并计数);经验球有重力、水中上浮、岩浆弹跳与 8 格内追踪玩家(加速度方向 归一化 × (1−√距离/8)² × 0.1),玩家靠近后自动拾取(拾取动画 + 经验条同步); 玩家死亡掉落 min(等级×7, 100) 点经验球;经验随玩家数据持久化、死亡清空(同原版)。
- 反馈完整:挥手/受伤闪红/死亡动画、Damage Event、音效、生命/饥饿/经验同步、头部朝向广播。
- 生物持久化到各维度世界目录的
entities.json(主世界<世界目录>/entities.json, 下界/末地为the_nether/、the_end/子目录;位置/生命/朝向、掉落物与飞行中的 箭矢(含速度/伤害)),重启后恢复。 - 远程武器与盾牌:弓(主手/副手)蓄力 1 秒满蓄力,释放时按蓄力发射箭矢
(箭速 3 格/tick、伤害 ceil(箭速×(2+0.5×力量))),消耗箭与 1 点耐久;
力量/冲击/火矢/无限/不灭附魔生效,创造模式与无限附魔不消耗箭;
箭矢命中生物或其他玩家(跳过射手本人)并结算伤害、击退与点燃;
盾牌按住右键格挡正面、不穿透
bypasses_shield的伤害,按 1+floor(伤害) 损耗耐久(不灭可免除),盾牌损坏自动解除格挡。 - 护甲与附魔数值效果:护甲值与韧性来自官方物品数据,近战/弹射/爆炸/火焰/摔落
伤害按原版
CombatRules结算(护甲吸收 + EPF 上限 20);护甲每次受非穿甲伤害 损耗 max(1, 伤害/4) 耐久;保护/火焰保护/爆炸保护/弹射保护/摔落保护、锋利/ 亡灵杀手/节肢杀手、击退、火焰附加、抢夺、效率、水下速掘、精准采集、时运、 不灭、经验修补、绑定/消失诅咒均已生效(数值展开自 1.21.11 附魔数据)。 - 经验球随维度目录的
entities.json保存 Value/Count/Age/速度,重启后恢复 (未拾取的经验球不再丢失)。 - 限制:生物寻路为地表模型(不考虑头顶净空与水中游泳;末影人瞬移为随机尝试)、 爆炸无方块掉落、无光照引擎、无状态效果/药水效果;完整列表见 TODO.md。
- 生存/创造可破坏与放置方块:修改广播附近玩家并随区块保存;生存挖掘完成后生效、 放置消耗物品;创造即时且不消耗;支持创造物品栏取放;冒险/旁观不可交互;无挖掘时间。
- 容器交互:右键箱子/陷阱箱/木桶(27 槽)、发射器/投掷器(9 槽)、漏斗(5 槽)、
酿造台(5 槽)与潜影盒(含 16 色)打开窗口;支持取放(左/右)、Shift 快速移动、数字键交换、
创造复制、Q 丢弃、拖拽分发与双击收集;内容随区块持久化,破坏时内容掉落;潜行右键改为放置方块。
窗口在方块被破坏/替换或玩家离开交互距离时自动关闭(原版
stillValid每 tick 校验, 含工作台/切石机/锻造台/铁砧/砂轮机/附魔台;gmcs 在每个入站数据包处理前校验, 玩家走出交互距离后的下一个包即触发关闭)。 - 漏斗传输(对照 1.21.11 反编译的
HopperBlockEntity):每游戏刻检查一次, 把最左侧物品沿朝向推 1 个到前方容器(一次搬运后冷却 8 tick,向漏斗推送时为 目标设置 7 tick 冷却错峰);传送冷却随方块实体持久化(原版TransferCooldown, 重启后从剩余冷却继续);上方是容器时从其抽取 1 个(按目标面规则: 熔炉上方只能进原料槽、侧面只能进燃料槽、产物槽只出不进;酿造台上方只能进材料槽、 侧面可进瓶子/燃料、下方可抽瓶子与玻璃瓶),否则收集 吸入盒(方块本格 + 上方一格,下沿 11/16)内的掉落物(整个堆叠,每 tick 最多一个); 被红石供电时锁定(enabled=false,不推不吸但仍可被其他漏斗输入或抽取); 放置朝向按点击面反方向(竖直退化为向下);内容随区块持久化,破坏时内容掉落。 - 破坏掉落:生存模式按方块掉落表生成掉落物(石头→圆石、草方块→泥土、矿石→原矿/宝石、 黏土→黏土球、雪块→雪球、西瓜→西瓜片等);精准采集保留玻璃/冰/树叶/ 草方块/矿石/西瓜/黏土/雪块等方块本身,时运影响矿石(ore_drops)、 红石/青金石/西瓜与砂砾的燧石概率,剪刀可采集树叶/草类/枯灌木/藤蔓; 作物按成熟度掉落(小麦/甜菜根未成熟只掉种子,胡萝卜/马铃薯未成熟掉 1 个, 成熟时按原版二项分布叠加时运;下界疣/甜浆果丛/火把花/可可豆/瓜类茎/ 瓶子草与海泡菜也已按官方表实现;双格植物破坏任一半只掉落一次并移除另一半); 墙式告示牌/旗帜/火把掉落站立变体;创造模式不掉落。 掉落表尚未覆盖所有方块的完整战利品表(如生物头颅等极少见掉落; 爆炸不产生掉落),见 TODO.md。
- 掉落物与拾取:生存/创意下 Q 丢 1 个、Ctrl+Q 丢整组(沿视线抛出);掉落物运动对照原版
ItemEntity(重力 0.04、落地反弹 ×-0.5、水平阻尼 0.98、落地摩擦取脚下方块的 slipperiness(普通方块 0.6×0.98、冰更滑)、逐轴 AABB 碰撞);水中水平 ×0.99、 缓慢上浮(5.0E-4/tick)并受水流推动;同类堆叠周期合并(跨方块边界移动时每 2 tick、 静止时每 40 tick 检查,0.5 格内、不隔墙),走近 1 格内自动拾取(含拾取动画与音效); 5 分钟消失、掉入虚空/岩浆/火/仙人掌移除;死亡掉落整个物品栏;随world/entities.json持久化。 - 堆叠上限按物品数据(官方
minecraft:max_stack_size,如雪球 16、工具 1), 背包合并/容器点击/创造物品栏/掉落物都按实际上限处理。 - 玩家装备槽(对照 1.21.11 的
InventoryMenu/ArmorSlot与官方minecraft:equippable组件数据):盔甲 4 槽只接受对应部位的装备 (头颅/南瓜等可装备物品也行,槽位上限 1),副手槽不限物品; Shift 点击可装备物品在对应装备槽为空时会直接穿上,否则退回主背包 ↔ 快捷栏; 右键不同物品的槽位按原版整栈交换;绑定诅咒在生存/冒险模式阻止从装备槽取出 (创造模式可取出),消失诅咒在死亡时销毁物品;盾牌可在主手或副手格挡 (见「远程武器与盾牌」)。 - 合成:玩家物品栏 2×2 与工作台(右键打开)3×3 合成;配方数据驱动 (官方 recipe JSON:706 有序、304 无序、116 烹饪;支持标签原料), 结果槽实时计算,取走产物消耗原料,支持 Shift 快速合成;关闭窗口合成格归还背包。
- 切石机与锻造台:右键打开对应窗口;切石机支持全部 254 条原版切石配方
(放入原料按原版不自动选中,点击配方列表项后才计算产物,重复取走保持选择、
输入物品变化清空选择,取走产物消耗 1 个原料;选中下标经 Set Container Property
同步给客户端高亮);
锻造台支持 12 条升级配方 + 18 条纹饰配方(模板+基底+添加物→产物,取走消耗三个输入各 1):
纹饰产物为基底副本 +
minecraft:trim组件(保留耐久/附魔等组件), 相同图案与材质重复应用无产物(与原版SmithingTrimRecipe.applyTrim一致); 输入槽按原版属性集校验(模板槽只接受锻造模板、基底槽只接受可锻造物品、 添加物槽只接受升级材料/纹饰材质)。两者的输入槽为窗口临时状态, 关闭窗口时归还背包(放不下则掉落)。 - 配方书:进入世界时发送原版配方属性集(Update Recipes:7 个属性集 + 254 条切石机配方;属性集是客户端锻造槽位放入校验与配方书筛选的前提) 并下发全部显示条目(Recipe Book Add,默认全部解锁); 在物品栏/工作台点击配方会向服务端发送 Place Recipe,自动把原料放入合成格 (Shift 点击为“尽可能多次合成”);切石机 UI 的配方列表由切石机配方声明驱动。
- 熔炉家族:熔炉/高炉/烟熏炉(右键打开):原料+燃料熔炼,双进度条
(Set Container Property),高炉/烟熏炉双倍速,熔炼获得经验,
燃料槽只接受燃料(空桶例外),湿海绵烘干时空桶→水桶,
燃烧与烹饪进度随区块保存(断线/重启后继续);燃烧时方块
lit属性置为 true 并广播方块更新(原版setLit),熄火后复位,因此熔炉会正常发光。 - 酿造台(对照 1.21.11 反编译的
BrewingStandBlockEntity/PotionBrewing): 3 个瓶子槽 + 材料槽 + 燃料槽(烈焰粉,1 个 = 20 次);400 tick 一轮酿造, 完成时对每个瓶子应用配方(水瓶→粗制→效果→延长/强化/腐化,火药→喷溅, 龙息→滞留)、材料消耗 1 个并播放完成音效与粒子(World Event 1035); 全部 63 条药水配方与 2 条容器配方逐条对照字节码移植;药水通过potion_contents组件携带(颜色/效果由客户端从药水种类推导); 瓶子槽只接受药水类/玻璃瓶且必须为空、材料槽只接受酿造材料、燃料槽只接受烈焰粉; 方块状态has_bottle_*随瓶子变化更新;进度随区块保存(存储格式 v5)。 - 铁砧(对照 1.21.11 反编译的
AnvilMenu.createResult逐字节码移植): 右键打开修复窗口(标题「Repair」),输入槽 2 个 + 结果槽 + 等级成本属性 (Set Container Property);支持材料修复(每个材料修复 min(当前损坏, 耐久上限/4)、 成本 +1/个)、同物品合并(剩余耐久 + 12% 上限奖励、成本 +2)、附魔合并与重命名 (custom_name 组件、成本 +1;名称与默认悬停名相同时不设组件;空白输入清除已有名字)。 附魔合并(对照字节码 434-726):逐个处理添加物附魔(附魔书取 stored_enchantments、 其余物品取 enchantments):同名附魔取较高等级、等级相同时 +1 并钳制到最大等级; 附魔必须可作用于输入物品(supported_items;创造模式或输入本身是附魔书时豁免), 与结果已有附魔冲突时该附魔不生效且每个冲突成本 +1,全部附魔都因冲突未生效时 结果无效;生效附魔按 anvil_cost × 目标等级计入成本(附魔书减半、至少 1; 输入堆叠数大于 1 时成本直接为 40)。 成本 = 两输入累积惩罚(repair_cost)之和 + 操作成本,达到 40 级且非创造模式时 无法取走(纯重命名封顶 39 级);取走时扣经验等级(创造模式豁免)、消耗材料、 清空输入与结果并播放音效(World Event 1030);非创造模式 12% 概率损坏铁砧 (anvil → chipped_anvil → damaged_anvil → 拆除,事件 1029/1030,朝向保留)。 物品组件(damage/custom_name/repair_cost、附魔 enchantments/附魔书 stored_enchantments 与纹饰 trim)随槽位网络编码下发并随区块与 玩家数据持久化(存储格式追加字段均向后兼容读取);输入槽为窗口临时状态, 关闭窗口归还背包(放不下则掉落);窗口有效性校验(方块仍是铁砧 + 8 格距离 近似;原版为交互距离属性 4.5 + 4.0)。 物品耐久由挖掘(按工具damage_per_block)与护甲受伤消耗,不灭附魔按原版 概率免除;经验修补在拾取经验时以 2 点耐久/点经验修复。 - 附魔台(对照 1.21.11 反编译的
EnchantmentMenu/EnchantmentTableBlock逐字节码移植):右键打开附魔窗口(标题「Enchant」),输入槽(至多 1 个)+ 青金石槽 + 三个随机选项与附魔线索(10 个数据槽:成本 3、附魔线索 3、 等级线索 3、附魔种子);书架提升选项等级(32 个偏移:外圈 x/z、y∈{0,1}, 书架 + 中点透明方块(#replaceable)才计数,上限 15);随机序列与java.util.Random(LegacyRandomSource 的 48 位 LCG,含拒绝采样)逐位一致 (用 JDK 参考值验证);附魔选取复刻EnchantmentHelper(等级修正 ±15%、 加权随机、互斥过滤、等级减半循环、书特例);候选筛选按 supported_items 且 primary_items 命中判定(5 个附魔限定主物品池,如锋利/亡灵杀手仅剑/矛可用、 荆棘仅胸甲;铁砧与书不受 primary_items 限制);附魔注册表与物品池由tools/genregistries从数据包生成(ID = 文件路径字典序,已与外部数据源 交叉验证);普通书附魔为附魔书;附魔以minecraft:enchantments组件 (非附魔书物品用 ID 13、附魔书用 stored_enchantments 41,注册表引用为裸 ID, 经官方服务端抓包验证)随槽位发送并随区块与玩家数据持久化(存储格式追加字段 向后兼容读取);点击选项扣 id+1 级(创造豁免)并重播玩家附魔种子; 缺口音效(block.enchantment_table.use);关闭窗口归还输入。 附魔的数值效果已生效(见「生物与战斗」的护甲与附魔段落): 锋利/亡灵杀手/节肢杀手、击退/火焰附加/抢夺、效率/水下速掘、保护类、 摔落保护、呼吸、不灭、经验修补、精准采集/时运、绑定/消失诅咒。 已知限制:横扫之刃、弩/三叉戟相关附魔(无对应武器系统)、附魔统计与进度、 钓鱼等其他附魔途径未实现;弓附魔(力量/冲击/火矢/无限)已生效。 - 砂轮机(对照 1.21.11 反编译的
GrindstoneMenu逐字节码移植):右键打开 修复/祛魔窗口(标题「Repair & Disenchant」),输入槽 2 个 + 结果槽(39 槽); 输入槽只接受可损坏物品或带附魔物品;同物品合并(剩余耐久相加 + 5% 上限奖励, 耐久上限取两者较大值);祛魔移除全部非诅咒附魔(附魔书清空后变为普通书, 诅咒无法移除,repair_cost重置为与剩余诅咒数对应);不可损坏的堆叠物品 要求组件完全一致(结果为 2 个);双方附魔书不可合并(原版 maxStackSize < 2); 取走时按两输入附魔的最低成本之和发放经验球(ceil(total/2) + 随机(0, ceil/2))、 播放世界事件 1042(砂轮机使用音效)、清空两个输入;输入槽为窗口临时状态, 关闭窗口归还背包;窗口有效性校验(方块仍是砂轮机 + 8 格距离近似)。 - 堆肥桶(对照 1.21.11 反编译的
ComposterBlock逐字节码移植): 115 种可堆肥物品与成功率(从字节码提取,见internal/registry/compost.go); 右键填入:空桶必定成功、其余按概率掷骰,结果通过世界事件 1500 同步 (客户端播放音效与粒子),非创造模式消耗 1 个;level 7 时使用不填入不消耗; level 7 → 8 为 20 tick 定时转换(就绪音效);满桶时使用弹出 1 个骨粉掉落物、 重置为 0 并播放清空音效;level 随方块状态随区块持久化;漏斗交互按原版 容器面规则(输入容器只允许上方插入、产出容器只允许下方抽出骨粉、 level 7 无槽位)。 定时转换本身不写入区块(原版存入区块的 scheduled tick);区块加载时会 立即扫描 level 7 并重新登记,另有周期全量扫描兜底。 - 农业(对照 1.21.11 反编译的
HoeItem/CropBlock/FarmBlock/BoneMealItem逐字节码移植):锄头把草方块/土径/泥土耕成耕地(砂土 → 泥土、 缠根泥土 → 泥土并掉落垂滴根须;要求点击面不是底面且目标上方是空气), 消耗 1 点耐久并播放item.hoe.till;作物物品按原版放置规则种在耕地 (下界疣只能种在灵魂沙),非创造模式消耗 1 个;作物随机刻按原版CropBlock.getGrowthSpeed(3×3 耕地含水量 + 行列/对角减半)与nextInt(25/speed+1) == 0生长,下界疣按 1/10 概率生长;耕地随机刻在附近 有水时升到湿度 7、无水时逐级衰减、湿度 0 且上方无maintains_farmland方块时退化为泥土;玩家落到耕地上会按FarmBlock.fallOn踩踏退化;骨粉按BoneMealItem.applyBonemeal催熟 2–5 级(满龄不消耗)并广播世界事件 1505。 已知近似:gmcs 无光照引擎,天光近似为“上方整列无方块”,因此只有露天农田 可以种植与生长;雨天会通过isRainingAt(pos.above())把耕地湿度提升到 7。 - 末影箱:右键打开按玩家独立的 27 槽空间(所有末影箱共享同一份内容),
随玩家数据(
players.json的ender_inventory)持久化。 - 玩家皮肤层:其他玩家可见的皮肤层(披风/外衣/袖子/裤腿/帽子)按客户端 Client Information 设置显示(实体元数据索引 16)。
- 玩家装备同步:其他玩家可见的手持物品与盔甲(Set Equipment,0x64):
玩家实体出现在视野时下发全部 6 个装备槽(主手/副手/靴子/护腿/胸甲/头盔),
此后变更时广播给附近(64 格内)玩家;空槽也会下发(count=0)以避免观察者
保留旧物品。编码格式对照官方服务端抓包(
64 <实体> 80 <主手> 05 <头盔>, 槽位字节高位表示“后面还有条目”)。生物装备(僵尸穿盔甲)未实现。 - 方块碰撞形状:全部方块状态的碰撞盒表(半砖/台阶/栅栏/墙/栅栏门/门/活板门/ 雪层/仙人掌/蛋糕/耕地/床/箱子/压力板等,常量取自原版实现),玩家移动、摔落与 掉落物物理统一使用形状级 AABB 碰撞(相触可贴面滑动)。
- 方块放置形态(对照 1.21.11 反编译的
StairBlock/SlabBlock/RotatedPillarBlock/HorizontalDirectionalBlock/TrapDoorBlock/LadderBlock/WallOrFloorItem/FaceAttachedHorizontalDirectionalBlock): 台阶按玩家朝向放置并区分上下半格; 半砖按点击面与点击高度决定上下半格,点击同种单半砖直接叠成双半砖; 原木/玄武岩/锁链等柱状方块按点击面设置轴向;箱子/熔炉/南瓜灯/木桶/潜影盒/ 织布机/切石机/蜂箱/营火/讲台等朝向方块按玩家朝向放置(木桶与潜影盒含上下 朝向);活板门按点击面决定半格并可右键开合;梯子只能贴在侧面; 火把点击侧面时放置墙式变体;拉杆与按钮按点击面决定附着面(floor/wall/ ceiling)与朝向(墙式朝向决定它给哪个方块供电);门需要上下两格空间,放置时 同时创建两半,右键开合会把另一半同步为相同的 open 值,破坏任一半会移除 另一半且只掉落 1 个门(只有下半格掉落,与原版战利品表一致),铁门不能手动 开合;栅栏门按玩家朝向放置并可右键开合;门/活板门/栅栏门都会响应邻居红石 信号(通电打开、断电关闭,门的两半同步,powered位随之设置); 门/活板门/栅栏门开合时广播开合音效(按材质分组:木质/铁质/铜质/竹/ 樱花木/下界木,栅栏门统一block.fence_gate.*,音量 1、音高 0.9–1.0)。 放置形态表由tools/genregistries生成,只保存放置会用到的属性组合(约 35 KiB 源码), 不为每个台阶展开全部 80 个状态,避免启动内存膨胀。已知近似:台阶不做 邻居形状更新(shape 恒为 straight)、含水状态一律 false。栅栏门的in_wall(沿朝向轴两侧有墙时为 true)与门的铰链(邻居坚固面/相邻下半格门 + 点击位置 回退,对齐DoorBlock.getHinge)均按原版在放置时计算;放置位置或上方一格有 红石信号时,门/栅栏门直接以打开(通电)状态放置。 - 摔落伤害:下落超过 3 格落地受伤,每多 1 格 1 点(
ceil(下落−3));改由服务器端 支撑面检测(脚底碰撞形状顶面)判定落地(不依赖客户端标志),落水/游泳中断下落; 落在干草堆(×0.2)/床(×0.5)/粘液块/蜂蜜块/细雪上免伤或减伤;传送/重生/回拉后重置。 - 移动校验:拒绝 NaN/越界 Y、单包超过 100 格与逐 tick 速度超限(允许距离 ≤10×√tick 数, 与原版一致)的位移,并检测穿墙(终点嵌入方块碰撞形状时拒绝并拉回); 潜行边缘保护(潜行不会走出支撑面边缘,沿边缘滑动)与悬空上升限制 (一次腾空累计上升 ≤1.3 格,覆盖原版跳跃弧顶约 1.2522 格;生存/冒险模式的简易飞行检测); 支持走上台阶/半砖(≤1 格高差)与水中自由上游(水中不受上升限制)。
- 环境效果:接触岩浆受到 4 点/0.5 秒伤害并着火 15 秒(每秒 1 点火焰伤害,入水熄灭); 头部浸水 15 秒后每秒 2 点溺水伤害;站在岩浆块上每 0.5 秒 1 点伤害 (着火/氧气状态随 Set Entity Data 同步)。
- 性能与安全:多玩家共享区块/注册表压缩帧(同区域近 100% 缓存命中;
同一区块的并发请求合并为一次编码)、区块卸载/预取/宽限策略
(见上“区块流式加载”)、保存与卸载编码不阻塞世界锁、区域文件句柄缓存;
会话级令牌桶限流(聊天/命令、移动、交互、容器点击、创造模式物品操作、
Tab 补全)抵御包洪泛;
max_players满员时按原版踢出 (multiplayer.disconnect.server_full,同 UUID 重连允许替换加入)。
- 电源:拉杆(右键切换)/按钮(按下后自动弹起:石质 20 tick、木质 30 tick)/红石块/ 红石火把(点亮时);红石线在同一网络内按“电源 15、每格 -1”衰减(多电源取最大值, BFS 重算);红石灯相邻电源或 power>0 的红石线时点亮;放置/破坏方块与切换开关后 都重算相连网络并仅广播变化的方块。
- 组件按原版语义实现(对照 1.21.11 官方 mappings 反编译的组件类): 中继器(朝向单向、右键 1–4 档延迟、每档 2 tick、侧向二极管可锁定); 比较器(比较/减法模式、右键切换、读取容器填充度与“穿过导体方块”的容器); 侦测器(面向方块变化输出 2 tick 脉冲);红石火把(支撑方块被供电时熄灭, 60 tick 内切换 8 次后熔断 160 tick);活塞/粘性活塞(结构解算器:最多推 12 格、 粘性链与分支、DESTROY 方块被破坏、BLOCK/不可推动方块阻挡、PUSH_ONLY 不可拉取、 活塞头与基座联动、准连接 QC、推动实体)。
- 方块强充能与连接指向:推反应/非导体表由
tools/genregistries从反编译数据生成; 中继器/比较器/拉杆/火把的 direct signal 可把导体方块强充能(“中继器 → 方块 → 上方红石线”可用);红石线的连接方向按原版getConnectionState计算(含直线贯通 规则与“向机构方块供电需指向”),供电与客户端渲染同源。 - 压力板:全部 16 种原版压力板(12 种木质 + 石质/抛光黑石 + 金/铁加权)。 检测盒为方块坐标 (1/16–15/16, 0–4/16, 1/16–15/16),与原版一致; 木质检测全部实体(含掉落物与经验球),石质/抛光黑石检测生物,加权(金 15/铁 150) 检测全部实体;加权信号 = ceil(min(数量, 上限) × 15 / 上限)(金 = 实体数、铁 ≈ 每 10 个 1 级); 松开延迟:轻型 20 tick、加权 10 tick;按下/弹起播放对应木质/石质/金属点击音效。
- 已知差异:活塞无移动动画(原版 MOVING_PISTON 移动方块实体,本实现同 tick 落位); 计划刻无优先级;比较器不读取物品展示框(无该实体);绊线/阳光传感器等 其他电源未实现。红石灯点亮立即、熄灭有 4 tick 延迟(与原版一致)。详见 TODO.md。
- 放置:打火石/发射器按原版
BaseFireBlock.canBePlacedAt规则放置(目标必须是 空气且能存活),下方为灵魂沙/灵魂土时放置灵魂火;每次推进重新排程 30 + rand(0..9) tick。 - 可燃数值表:206 个方块的“鼓励值(蔓延)/燃烧速率(被烧)”机械提取自官方
1.21.11 服务端
FireBlock反汇编(internal/registry/fire_flammables.go), 未列出的方块一概不可燃。 - 推进与蔓延:age 每 tick 增加 0–1(上限 15);六邻域内无可燃方块时,下方顶面
完整且 age ≤ 3 才保留,否则熄灭;有可燃方块时 age 到 15 后每 tick 有 1/4 概率在
下方不是可燃方块时熄灭;对六邻域按水平 300/垂直 250 的基数做燃烧判定,命中后
点燃(
age + rand(0..4)/4)或直接烧毁,命中 TNT 会点燃 TNT;以空气为目标的蔓延 概率为(可燃度 + 40 + 难度 × 7) / (age + 30)(群系increased_fire_burnout减半), 越往上越难蔓延。 - 永燃与灵魂火:下界岩/岩浆块按维度的
infiniburn_*标签永燃(不下雨也不会熄); 灵魂火没有 tick(不推进、不蔓延、不自行熄灭),失去灵魂沙/灵魂土即消失。 - 玩家半径:与原版 1.21.11 一致,火焰只在 128 格内存有非旁观玩家时推进
(规则
fire_spread_radius_around_player的默认值;gmcs 无游戏规则), 区块未加载时同样只重新排程。 - 已知差异:无难度设置(按默认 Easy)、含水方块状态未建模、 雷暴不产生闪电。详见 TODO.md。
- 着火(玩家与生物):站在火/灵魂火方块上点燃 8 秒(玩家在火中每 tick 额外
+1…2 tick),接触岩浆点燃 15 秒并受 4 点岩浆伤害;着火每秒 1 点火焰伤害
(受受伤无敌帧限制),入水立即熄灭;着火状态通过实体共享标志(Set Entity Data
索引 0 bit0,变化时才广播)同步,并随 entities.json 持久化。火/水/岩浆的相交按
实体碰撞盒覆盖的方块判定(收缩 1e-7,与原版
Entity.checkInsideBlocks的 AABB 处理一致),而不是只看脚部与上方一格。降雨时也会熄灭实体着火(Entity.isInRain) 以及火焰方块(FireBlock.tick的浇灭分支)。
- 服务器日志按
log_file/log_level输出到控制台与文件,超过log_max_size_mb时轮转为<文件>.1(保留一份历史)。 - 审计日志(
audit_log_file,JSONL)记录聊天/命令/加入退出/踢出/击杀等事件, 便于事后排查;空值禁用。
- 玩家以实体互相可见:加入/退出、移动与朝向在 64 格内同步;皮肤来自正版档案属性。
- 实体跟踪:每名玩家维护“客户端当前持有的实体集合”(生物/掉落物/箭矢/TNT/ 经验球/其他玩家),实体进入 64 格时补发 Add Entity、离开 80 格时补发 Remove Entities;维度切换与死亡重生后(客户端清空世界)自动重新下发范围内实体。 加入时只发送 64 格内的既有实体。
- 可攻击其他玩家:伤害/受伤动画/生命同步与生物战斗一致;挥空也播放挥手动画。
- 位置校验:拒绝 NaN/越界 Y、单包超过 100 格的位移与逐 tick 速度超限(见上文), 并把客户端拉回服务器记录的位置。
pprof_address:启用后在/debug/pprof/*提供 CPU/内存/goroutine 分析 (go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=20)。cmd/gmcsload:离线模式负载压测客户端(登录 → 配置 → 进入世界 → 持续移动), 输出进入世界耗时、收包量、流量与包类型分布;单机 loopback 结果见 docs/PERFORMANCE.md。
- 退出/关服与每 30 秒周期保存位置、生命/饥饿/饱和、疲劳度、氧气、着火时长、
经验、游戏模式、物品栏与选中的快捷栏槽位,重连恢复且不重复发放
starting_items;进入世界/跨维度传送/重生后发送set_held_slot同步客户端 选中的槽位;死亡状态同样持久化(重连后保持死亡,发送重生请求后复活); 物品按命名空间 ID 存储,跨版本可读。 - gmcs 自定义格式(非原版
playerdata);强杀或崩溃最坏丢失约 30 秒进度。
- 启用后完成 AES-128/CFB8 加密握手并通过
hasJoined验证账号,透传签名属性; 服务器列表与游戏内标记enforcesSecureChat=true,玩家列表携带皮肤。 - 聊天会话(
chat_session_update):服务器保存客户端上报的会话公钥,并通过 Player Info 的 Initialize Chat 动作分发给其他玩家。 - 聊天消息签名(
enforce_secure_profile):保存会话后建立消息链,按原版校验每条 聊天消息的 RSA-SHA256 签名(签名覆盖发送者 UUID、会话 UUID、链序号、盐、时间戳、 消息与确认窗口)与消息确认窗口(offset/位图/校验和);校验通过后把签名与确认列表 转发给所有玩家(安全聊天标记),失败按原版组件断开连接 (chat.disabled.invalid_signature、chat.disabled.out_of_order_chat、multiplayer.disconnect.chat_validation_failed等)。 - 已知差异:gmcs 没有 Mojang 的会话服务公钥,因此不校验会话公钥的 Mojang 签名
(原版会校验
KeySignature);ServerboundChatCommandSigned的命令参数签名也未校验。 - 默认离线模式:UUID 按原版离线规则由用户名推导,聊天按未签名消息广播 (与原版离线服务器一致)。
scripts/test.sh # gofmt + build + vet + 单元测试 + race
scripts/test.sh --bench # 附加 benchmark
go test -race ./... # 仅数据竞争检测
go run ./cmd/gmcsload -addr 127.0.0.1:25565 -players 50 -duration 20s # 负载压测关键路径的 benchmark 方法与实测数据见 docs/PERFORMANCE.md。
# 1. 用官方服务端 jar 生成数据报告(reports/registries.json、blocks.json、items.json 等)
java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports
# 2. 从官方客户端 jar 与报告生成本仓库的注册表/方块/物品/食物/堆叠上限数据
go run ./tools/genregistries \
-jar <client.jar> \
-reports generated/reports/registries.json \
-blocks generated/reports/blocks.json \
-items generated/reports/items.jsoncmd/gmcs 服务器入口
cmd/gmcsload 负载压测客户端(离线模式模拟并发玩家)
internal/config 配置结构与 JSON 持久化
internal/protocol 协议包编解码(握手/登录/配置/Play、NBT、Slot 等)
internal/registry 生成的注册表、方块状态与物品 ID 数据
internal/world 区块模型、地形/维度生成、区域文件存储、世界管理器
internal/item 物品堆栈与玩家物品栏
internal/logging 日志文件轮转与审计日志(JSONL)
internal/server 服务器、会话生命周期、玩家列表与广播
tools/genregistries 数据生成器
scripts 跨平台构建与测试脚本
docs 文档(贡献指南、迁移指南、TODO、性能基准)
- docs/TODO.md:进度、待办与已知限制(路线图)
- docs/PERFORMANCE.md:性能基准与复现方式
- docs/CONTRIBUTING.md:贡献指南(开发环境、测试与提交流程)
- docs/MIGRATION.md:迁移指南(升级、更换 Minecraft 版本、与原版互迁)