WebAssemblyGoogleMicrosoftMozillaApple WebAssemblyWebAssemblyJSWebAssemblyJSWebAssemblyWebAssembly

Panzr.io 简介

WebGo

Panzr.io 架构

Panzr.io 部署架构

Triebwerk 简介

项目源码:

项目 Status:

TriebwerkGo

游戏是如何运行的?

服务器权威架构

  • 仅通过服务器进行通讯
  • 客户端将所有输入发送到服务器
  • 服务器有权进行模拟
  • 防止作弊并引入延迟

客户端预测和服务器协调

QuakeWorld

客户端插值

UpdatesFrames

定义边界

限制:

2D

服务器实现

玩家移动

碰撞检测

二进制数据传输

  • 最小化资源使用
  • 防止数据包分段
  • 最小化丢包的影响

WebAssembly 模块

Game logicServerClient
  • 文件大小 > 2MB
  • 服务器和客户端根据相同的逻辑计算状态
  • 通过二进制类型进行数据传输

编译:

GOOS=js GOARCH=wasm go build -o tanks.wasm cmd/wasm/tanks.go

Client:

<script src="/game/wass_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(featch("/game/tanks.wass"), go.importObject).then(result => {
    go.run(result.instance);
});
</script>

Server:

js.Global().Set("updateNetworkPlayer", js.FuncOf(updateNetworkPlayer))

在 Go 中编码 state

posX := float32(30.457777)
posY := float32(10.336666)
buf := make([]byte, 8)

binary.LittleEndian.PutUint32(buf[0:], math.Float32bits(posX))
binary.LittleEndian.PutUint32(buf[4:], math.Float32bits(posY))

var uint8Array = js.Global().Get("Uint8Array")
dst := uint8Array.New(len(buf))
js.CopyBytesToJS(dst, buf)

在 Javascript 中解码 state

let dv = new DataView(state.buffer)
let posX = dv.getFloat32(0, true)
let posY = dv.getFloat32(4, true)

在线试玩

Refs