Unlight 是一款超過十年的遊戲,在 Flash 已經無法使用的這個時代,我們該如何快速將原本使用 Flash + TCP 的架構轉換為 HTML5 + WebSocket 的設計呢?
Unlight 從 TCP到 WebSocket 的 HTML5 之路Photo by Nastya Dulhiier on Unsplash
View Slide
THE PROGRAMMEROF CREATIVE࣌ݭ@elct9620
@2020
評估後預計以 Unity 開發,並以⼿機平台為主原始計畫
Unity 可以使⽤ TCP 連線不⽤調整過多伺服器設計原始計畫
合作夥伴在其他國家希望以 HTML5 版本發⾏意外發⽣
Unity 的 WebAssembly 無法使⽤ DLL 套件意外發⽣
@2021
從第三⽅獲取建議可以使⽤ Cocos Creator 開發新計畫啟動
Cocos Creator 有類似 Unity 的介⾯,但是有很多限制存在新計畫啟動
原本暫時不處理的 TCP 連線問題需要⽀援 WebSocket連線問題
評估後以團隊成員熟悉的 Golang 進⾏開發 Proxy Server連線問題
Unlight 使⽤的是⾃訂的資料結構,需要⽤⼆進位⽅式處理封包問題
JavaScript 在處理⼆進位資料上非常不好實作封包問題
跟 Proxy 共⽤封包解析套件,⽤ WebAssembly 提供⽀援封包問題
⽬前設計
Server (Ruby) Proxy (Go)Cmd Lib (Go)Bridge Lib (JS)State Lib (TS)Client (JS)
伺服器部分維持現況不調整,是⽬前相對穩定的部分Server
Proxy 提供單⼀ WebSocket 連接,再由 Proxy 連到不同伺服器Proxy
TCP 連線狀態由 Proxy 管理,斷線可以⽤相對少修改⽅式解決Proxy
Golang 本⾝有不錯的 WebSocket / IO 處理⽀援,因此省下不少時間理由
透過 Code Generate 產⽣能⾃動編碼和解碼封包的套件Cmd Lib
Proxy 可以針對玩家封包做紀錄,JS 端可以透過 Wasm 直接⽤於解析理由
透過 ProtoBuf 和 WebAssembly 跟 Proxy 溝通和解析指令Bridge Lib
gRPC 其實是把 Protobuf 封裝加入了 Lookup 資訊找到對應的⽅法概念
因為 gRPC 還需要其他處理,因此我們⽤⾃⼰的⽅式做 Lookup概念
在將 Golang 綁定到 JavaScript 上時,我們遇到⼀些問題困難
除此之外我們因為 Code Generate 讓 WebAssembly 非常⼤困難
封裝成事件跟 Promise 物件,提供非同步的操作Bridge Lib
基本上是為了能有⼀個可以重複利⽤的連線模組並解決指令問題理由
發現 Client 端開發無法很好使⽤ Bridge Lib且對狀態管理沒有概念State Lib
Unlight 原有設計的狀態和事件是混合且嚴重耦合State Lib
把互動完全抽象化,Client 端只需要知道狀態有變化並更新即可State Lib
使⽤ TypeScript 加入型別檢查跟封裝避免協作時理解錯誤State Lib
在設計上就盡可能減少耦合,同時降低我們在協作時需要掌握的資訊理由
總結
原本認為重寫網路模組會很不好處理,不過改⽤ Proxy 後協助後修改成本並沒有想像中⾼TCP
原本選⽤ Unity 主要是 JavaScript ⼤多必要套件無法使⽤,不過使⽤ WebAssembly 後效果雖不好但仍能解決問題WASM
過程中調整次數最多的是 JavaScript 的部分,連線模組的設計到複雜結構的管理才讓我們從JavaScript 開始轉到 TypeScript 上,並且想辦法解耦來改善協作JS Lib
THANKS