什麼是 WebAssembly
?由 Google
、Microsoft
、Mozilla
、Apple
等發起的 WebAssembly
是一種新的位元組碼格式,主流瀏覽器都已經支援 WebAssembly
。 和 JS
需要解釋執行不同,WebAssembly
位元組碼和底層機器碼很相似可快速裝載執行,因此效能相對於 JS
解釋執行大大提升。WebAssembly
並不是一門程式語言,而是一份位元組碼標準,需要用高階程式語言編譯出位元組碼放到 WebAssembly
虛擬機器中才能執行。
Panzr.io 簡介
- 基於開源技術的遊戲
- 使用
Web
作為發行平臺 - 輕巧快速
- 探索基本的多人遊戲技術
- 擴充套件
Go
技術知識
Panzr.io 架構
Panzr.io 部署架構
Triebwerk 簡介
專案原始碼:
專案 Status:
Triebwerk
是一個開源的多人遊戲伺服器- 使用
Go
語言編寫 - 目前僅是基礎原型
遊戲是如何執行的?
伺服器權威架構
- 僅通過伺服器進行通訊
- 客戶端將所有輸入傳送到伺服器
- 伺服器有權進行模擬
- 防止作弊並引入延遲
客戶端預測和伺服器協調
- 最早由
QuakeWorld
推廣 - 本地模擬運動
- 不斷與伺服器狀態同步
- 根據伺服器狀態更正本地狀態
客戶端插值
- 網路更新(
Updates
) < 每秒幀數(Frames
) - 過去狀態之間的插值
- 保守演算法
- 沒有推斷
定義邊界
限制:
- 所有遊戲邏輯僅在
2D
空間中 - 均勻表面
- 僅通過鍵盤進行輸入控制
- 限制地圖尺寸
- 緩慢移動的車輛
- 沒有物理引擎
伺服器實現
玩家移動
碰撞檢測
二進位制資料傳輸
- 最小化資源使用
- 防止資料包分段
- 最小化丟包的影響
WebAssembly 模組
遊戲邏輯(Game logic
):Server
-> Client
- 檔案大小 > 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
我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)