星期五報道#415-修復、改進、優化


3樓貓 發佈時間:2024-06-22 00:25:02 作者:Wube Software Language

大家好 

雖然2.0開發中的許多時間花在了新功能和遊戲質量上,但我們也在關注一些較小的細節和技術改進。

有確定性的多線程很難

最近一個同步異常錯誤被報告給了我們,涉及修改API以及多臺玩家使用的Windows和Linux計算機。我的第一直覺是又有mod開發者幹了什麼好事,但這些年來我看到了足夠多的錯誤報告,我知道在沒有事先調查的情況下就下定論是個壞主意,也很容易挨迴旋鏢打臉。

我無法復現這個bug,但玩家們輕鬆的做到了。一開始我以為這是Windows與Linux之間的問題(我們已經遇到過很多這樣的問題),但後來玩家能夠在兩臺Linux系統的計算機上覆現。接下來,我認為這是一個硬件問題,我們曾經看到過一些有故障的計算機,它們只是沒有做它們應該做的事情。但即使在最好的情況下,說服某人他們的硬件壞了也要大費周章。

在幾次嘗試在我的一臺電腦上覆現這個問題失敗後,Boskid使用他的多臺電腦成功了。我想,成功在本地重現錯誤大約佔了修復這個錯誤時間的90-95%。隨著Boskid不斷深究這個問題,他把問題出現的範圍縮小到了不同計算機CPU內核數量不同這一問題。有了這些新發現的知識,他得以進行一項測試,可以在我的一臺計算機上覆現,通過人為讓系統判定我電腦CPU內核比實際少來複現此bug。

這個問題的發生有四個條件,只有全部滿足才會暴露出這個由多線程導致的問題,自2017年7月22日我把它放在那裡以來,這個問題一直存在於遊戲中。

1.一個需要監視區塊生成的事件,並在某些事件發生時更改區塊上的地塊的mod。

2.一個請求生成幾個地塊mod。

3.一個立即強制生成所有請求的地塊的mod。

4.遊戲在兩臺CPU核數不同的計算機上運行。

“立刻”生成地塊的邏輯會嘗試使用所有可用的CPU內核,但這樣做會導致,內核的數量——有變化時——會稍微改變地塊生成結果。 

該修復程序實現起來並沒有那麼複雜,將在2.0中實現,但它表明多線程很難、有確定性的多線程更難。

多人遊戲自動暫停

我們給專用服務器添加了這個功能,當最後一個玩家斷開連接時,服務器會自動暫停。這非常有效,意味著你可以保留一個專用服務器,而不用擔心當你離開時,蟲子會吃掉你的基地。不過,有些邊緣案例我們(直到現在)都沒有時間處理。

情況1:當你加入自動暫停的服務器時,它會立即恢復運行——即使你還沒有完全加載到遊戲中。事實證明,這是一個非常簡單的問題,只是因為一些原因,它多年來一直被忽略了。對於2.0,自動暫停的服務器將保持暫停狀態,直到至少有一名玩家完全加載到遊戲中。

案例2:加入遊戲的玩家需要趕上正在進行的遊戲進度。這對“正常”遊戲非常有效,先加入服務器的玩家可以繼續玩,不必等待新加入的玩家。但是,在玩家使用的地圖較大或網速太慢時會遇到問題。如果服務器在他們沒有加載完的情況下繼續運行,加入的人可能需要1、2或幾分鐘的時間來下載、加載並完全趕上服務器的進度。對於2.0,我們添加了一個選項“當玩家加入時自動暫停”,它的作用和它的名字一樣。

更快建造機器人的任務

感覺每隔一週就會有人問“為什麼我的建築機器人不工作?”在他們提供的屏幕截圖中,有一個小警報顯示“600個工作崗位缺少材料/機器人”。這個問題從機器人誕生之初就一直存在,直到今天我們還沒有一個很好的解決方案。

問題是,給定建築機器人需要完成的任務,遊戲需要從物流網絡中找到能夠完成該任務的最佳機器人。檢查“該物流網絡是否在實體範圍內”定義為O(Roboport數量,即後文N)。我們無法控制檢查速度,因為玩家可以建造1個Roboport,或100000個,或他們的計算機所能承受的上限。因此,我們需要確保這種檢查不會在運行時使遊戲卡死。我們通過限制每幀處理建築機器人的任務上限處理。

在1.1版本中,遊戲每次刷新將檢查3個建築任務。如果找不到機器人就將會在這次刷新時停止尋找。而尋找機器人失敗的警報持續10秒。因此,在一秒刷新60次,每個警報持續10秒的情況下,這意味著在第一個警報超時之前將創建了600個警報。這就是神奇的“600個工作崗位缺少材料/機器人”警報數量的來源。

自從我在Factorio上工作以來,它一直是這樣工作的,並且可能會在一些基本層面上繼續這樣工作。我們不能簡單增加每次刷新檢查的任務數量,因為我們知道這會影響加載速度,玩家構建的roboport越多,加載就越慢。

今年早些時候,有人(論壇帖子)再次遇到了這個問題,但他們決定自己“解決”這個問題,通過做我們說不能做的事情:“每次更新檢查任務”,從每次更新1個增加到374個。此外,他們還建造了36815個roboport。正如預測的那樣,遊戲加載會變慢。

星期五報道#415-修復、改進、優化-第0張

但這讓我思考,如果我能加快判定速度呢?比如優化算法?當我想起我們在遊戲中已經有了一套邏輯來處理roboport的物流和施工區域,並計算得到的矩形並集時,我受到了啟發。簡單地說,它所做的就是生成一組漂亮的消除重複的矩形,覆蓋所有roboport的總面積。我們將其用於渲染,以避免roboport彼此靠近時出現大量過度渲染。

再加上對生成的矩形進行排序,這意味著我可以進行簡單的二進制搜索,檢查給定的任務是否在網絡區域內。最後,檢查範圍從36815個機器人端口上的O(N),到900個矩形並集區域上的O(N),再到900個矩形並集區域的O(logN)。

檢查“它在這個物流網絡中嗎”的時間大大縮短。有了這個加速,我就可以加快2.0版的機器人任務檢查速度,並有望解決這個問題。



© 2022 3樓貓 下載APP 站點地圖 廣告合作:asmrly666@gmail.com