Minecraft背后的逻辑
游戏内概念
Minecraft是一个方块的世界,每个方块叫做Block ;一组方块叫做区块,当提到“区块(Chunk)”的时候一般存在两种理解:
- 把16*256*16个方块称为一个区柱(Colume),把16*16*16个方块称之为区块(Chunk)
- 把16*256*16个方块称为一个区块(Chunk),把16*16*16个方块称之为区段(Section)
为了统一,约定在Spaze中采用后者。即16*16*16个Block为一个Section,16个Section为一个Chunk。
MC网络通信协议
以下是客户端连接服务器时的通信过程
- Client connects to server
- C→S: Handshake State=2
- C→S: Login Start
- S→C: Encryption Request
- Client auth
- C→S: Encryption Response
- Server auth, both enable encryption
- S→C: Login Success
- S→C: Join Game
- S→C: Plugin Message: minecraft:brand with the server’s brand (Optional)
- S→C: Server Difficulty (Optional)
- S→C: Spawn Position (“home” spawn, not where the client will spawn on login)
- S→C: Player Abilities
- C→S: Plugin Message: minecraft:brand with the client’s brand (Optional)
- C→S: Client Settings
- S→C: Player Position And Look (Required, tells the client they’re ready to spawn)
- C→S: Teleport Confirm
- C→S: Player Position And Look (to confirm the spawn position)
- C→S: Client Status (sent either before or while receiving chunks, further testing needed, server handles correctly if not sent)
- S→C: inventory, Chunk Data, entities, etc
准备在Spaze服务器中,1~8由Gate处理,9~19由Unit中的初始化方法处理,20之后才是正常游戏的数据。
原版Tick结构
Tick {
tickWorlds {
命令处理(commandFunctions)
foreach world {
同步时间(timeSync)per 20 ticks
world.tick
}
connection.tick
updatePlayers
更新服务器GUI
}
更新玩家列表(Sample)per 5 sec
自动保存(AutoSave)per 6000 ticks
snooper.update per 6000 ticks
tallying
}
world.tick {
WorldBorder.tick
更新天气
所有玩家睡觉时跳过夜晚
计算环境亮度(ambientDarkness)
更新时间(tickTime)
服务器区块管理器更新
方块tick
流体tick
村庄袭击tick
portalForcer.tick
raidManager.tick
游商tick
Block事件
dimension.update //目前仅用于末地末影龙战斗
global {
foreach entities {
entity.tick
}
}
regular {
某种没看懂的神奇循环 {
刷出动物
刷出NPC
所骑乘的实体被移除时更新状态
实体tick
删除被删除的实体
}
}
}
tickChunk {
打雷时生成骷髅骑士和闪电
下雪时铺雪和结冰
foreach 区段(Section) {
随机刻
}
}