目前我的遊戲服務器很小(一個區域和〜50 AI),並且每次發送狀態更新數據包(UDP)時,都會向每個客戶端發送一個完整狀態。這會創建大約1100字節的數據包大小。幾乎所有的發送是所有實體的以下信息:提供實時遊戲狀態更新的服務器
int uid
int avatarImage
float xPos
float yPos
int direction
int attackState
24 bytes
編輯:更高效的結構
int uid
byte avatarImage
float xPos
float yPos
byte direction & attackState
14 bytes
但我將需要發送最終的詳細信息的實體。比如我加入到這個:
float targetXPos
float targetYPos
float speed
由於需要更多的數據爲每個實體發送,我很快就要到來,很可能已經通過數據包的最大尺寸。所以我試圖想到一些可能的方法來解決我的問題:
1)只是建立狀態更新包,直到我用完了房間,然後剩下的其餘部分。非常糟糕的客戶視圖。不是一個真正的選擇。
2)只將N個最近實體的數據發送給客戶端。這要求每個狀態更新計算出每個客戶端最近的N.這可能非常耗時。
3)一些如何設計數據包,以便我可以發送多個相同的更新。目前,客戶端假定數據包的結構如下:
int currentMessageIndex
int numberOfPCs
N * PC Entity data
int numberOfNPCs
N * NPS Entity data
然後客戶端接受這個新數據並完全覆蓋其狀態副本。由於數據包是完全獨立的,即使客戶端錯過了一個數據包,也是可以的。我不知道我將如何實現同一更新的多個數據包的想法,因爲如果我錯過其中的一個,那麼呢?我無法用更新,部分狀態覆蓋完整,過時的狀態。
4)只發送改變的實際變量。例如,對於每個實體,我添加一個int,這是每個字段的位掩碼。諸如速度,目標,方向和avatarImage等事物不需要在每次更新時發送。我仍然回到如果客戶端錯過實際需要更新其中一個值的數據包時會發生什麼情況的問題。我不知道這將是多麼重要。這還需要在客戶端和服務器端創建/讀取數據包時進行更多的計算,但不要太多。
有更好的想法嗎?
我喜歡4號的想法。但是,如果任何信息相互連接(如速度和方向)。確保它們一起發送。如果在這兩種情況下客戶端都會丟失數據包......它仍然會錯過更新......數據是一次全部發送還是僅在發生更改時發送。 – 2011-04-20 06:44:33
壓縮呢?或某種自定義編碼?如果事先知道某些值的範圍,則可以在每個字段上丟失一些比特... – Dan 2011-04-20 06:58:28
我也喜歡數字4。除了發送* update *包之外,您還可以根據客戶端的要求發送* whole_status *包。當你在* update *包中包含序列號時,客戶端知道它應該何時請求* whole_status *。 – 2011-04-20 06:59:34