2011-04-17 51 views
9

我正在製作客戶端服務器MMO風格的遊戲。到目前爲止,我已經設置了框架,以便服務器和客戶端相互交互以提供狀態更新。服務器維護遊戲狀態並定期計算下一個狀態,然後每隔一段時間(每n毫秒)發送一次新狀態給所有客戶端。用戶可以在客戶端查看並響應這個新狀態。這些操作然後被髮送回服務器進行處理併發送出去進行下一次更新。同步客戶端 - 服務器遊戲狀態

顯而易見的問題是,這些更新需要花時間在服務器和客戶端之間傳輸。如果客戶有攻擊敵人的行爲,那麼在更新返回到服務器時,服務器很可能已經進入了足夠遠的遊戲狀態,以至於敵人不再處於同一地點,並且超出範圍。

爲了解決這個問題,我一直試圖想出一個好的解決方案。我看了下面的內容,並且幫助了一些,但不是完全的:Mutli Player Game synchronization。我已經得出結論,我可以傳輸其他信息,例如方向(或AI運動的目標位置)和速度等信息,而不僅僅傳輸當前的遊戲狀態。從這個角度來看,我需要在客戶端「猜測」一些什麼,通過將遊戲狀態推進到未來幾毫秒來確定實際狀態(如服務器所看到的)。

問題是確定進展狀態的時間量,因爲它取決於服務器和客戶端之間的延遲時間,這可能會有很大的差異。此外,我是否應該將遊戲狀態改爲當客戶端查看它時的狀態(即只考慮更新到達客戶端的時間),還是應該進一步處理,以便在發送響應時回到服務器,到那時它將是正確的狀態(考慮到旅途和往返旅程)。

有什麼建議嗎?

重申:

1)什麼是計算的時間發送和接收之間的時間量的最佳方法?

2)我是否應該將客戶端狀態進行得足夠遠以便計算整個往返時間,或者只是將數據從服務器傳輸到客戶端所需的時間?

編輯:我想出迄今

因爲我已經有很多包來回的客戶端和服務器之間,我不希望添加到交通,如果我不得不這樣做。目前,客戶端發送狀態更新數據包(UDP)到服務器約150毫秒(只有在發生變化時),然後由服務器接收和處理。目前,服務器不會對這些數據包發送任何響應。

首先,我會讓客戶試圖估計他們的滯後時間。我會默認它爲50到100毫秒。我建議大約每2秒(每個客戶端)服務器將立即響應這些數據包之一,並以特殊的定時更新數據包的形式發回數據包索引。如果客戶端接收到定時數據包,它將使用該索引來計算該數據包發送多久之前,然後使用數據包之間的時間作爲新的滯後時間。

這應該保持客戶合理的最新滯後,沒有太多的多餘的網絡流量。

聲音可以接受,還是有更好的方法?這仍然不回答問題二。

回答

2

2)我是否應該將客戶端狀態進行得足夠遠以便計算整個往返時間,或者只是將數據從服務器獲取到客戶端所用的時間?

我們假設服務器在時間T0發送狀態,客戶端在時間T1看到它,在時間T2發生反應,服務器在時間T3獲得他們的答案,並立即處理它。 這裏,往返延遲是T1-T0 + T3-T2。在理想的世界中,T0 = T1和T2 = T3, 並且觀察時間和玩家動作處理之間的唯一延遲是玩家的反應時間,即T2-T1。 在現實世界中,它是T3-T0。 所以爲了模擬,你需要減去整個往返延遲的理想世界:

T2-T1 = T3-T0 + (T1-T0 + T3-T2) 

這意味着較慢的網絡上的玩家看到更先進的狀態快速網絡上的球員。 但是,這對他們來說沒有任何好處,因爲它需要更長的時間才能處理它們的反應。 當然,如果兩個玩家坐在一起並使用不同的速度網絡,它會變得很有趣。 但這是非常不可能的情景,不是嗎?

整個程序存在問題: 您在未來進行外推,這可能會導致無意義的情況。他們中的一些人,比如潛入牆壁可以很容易地被阻止,但那些取決於玩家的交互不能。

也許你可以把你的想法倒掛: 取而代之的預測,試圖評估球員當時的T3行動 - (T1-T0 + T3-T2)。如果你確定一個角色會以這種方式命中,則相應地降低其生命值。 這可能比原來的想法更容易和更現實,或者可能更糟,或者根本不適用。只是一個想法。


試想一下兩位選手互相運行。 根據推斷它們在右側通過彼此。事實上,他們中的一個改變了方向,最後它們在左側相互傳遞。

+0

「但這是非常不可能的情景,不是嗎?」如果一臺設備使用蜂窩連接而另一臺使用wifi?只是一個想法。無論哪種方式,您都在說我會向用戶展示遊戲將在他們的響應回到服務器時的狀態,對嗎? – 2011-04-20 06:14:46

+0

*「蜂窩連接和WiFi」* - 通常,兩者都會嘗試使用更快的連接。他們可以試圖以這種方式作弊,但它看起來有點過於複雜。這會是一種欺騙,但是在MMO中​​有更簡單的作弊方式。 – maaartinus 2011-04-20 11:25:58

+0

是的,我正在說這個。現在我補充一點,你可以減少所有球員的時差。較少的外推可能意味着更少的問題;只是一個想法。 – maaartinus 2011-04-20 11:30:05

2

的一種方式有種問題是在客戶端服務器上運行遊戲模擬。

因此,不要模擬服務器上的世界,而是在客戶端上進行。只需將客戶端做的事情(例如「玩家擊中怪物」)發送到服務器即可。服務器運行相同的模擬並檢查事件。

如果它們不匹配(玩家作弊,滯後),它會向客戶端發送否決權,並且該操作在服務器上不會被記錄爲成功。這意味着所有其他客戶端都不會注意到它(服務器不會將操作轉發給其他客戶端)。

這應該是一個非常有效的方式來處理滯後,特別是如果你有很多PvM戰鬥(而不是PvP):由於怪物是一個模擬,沒有關係,如果有一個長時間的滯後客戶端和服務器。

這就是說:大多數網絡速度非常快,以至於滯後應該在幾毫秒的時間內。這意味着你「只是」必須使服務器速度足夠快,以便它可以響應100毫秒,並且玩家不會注意到。

相關問題