最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【戴森球計劃】游戲內(nèi)傳送帶結(jié)構(gòu)與刷新機制與環(huán)帶爆帶bug原理及游戲內(nèi)外修復方法

2023-07-07 19:11 作者:蒔槡_makuwa  | 我要投稿

首先,關于非環(huán)帶的所有屬性說明與機制的視頻版教程在這:傳送帶刷新機制、優(yōu)先級、以及兩個重要問題

以下內(nèi)容為包括環(huán)帶結(jié)構(gòu)在內(nèi)的傳送帶主要結(jié)構(gòu)與機制的圖文版說明:

1、貨物在傳送帶上的存儲方式

傳送帶中的最小存儲單元為buffer(byte型數(shù)據(jù)),每個貨物占用10buffer的空間,在這10個buffer中,最上游的5個buffer表示物塊的位置偏置,值從246~250;接著由2個buffer表示貨物的id、1個buffer表示堆疊數(shù)、1格buffer表示噴涂點數(shù)的信息,這4個buffer的數(shù)值都不超過100;最后是一個值為255的頂部buffer。即對于一個這樣的傳送帶上的貨物:

一個貨物占用傳送帶10個buffer

這10個buffer在游戲數(shù)據(jù)中存儲的值為:

上圖為氫在傳送帶上時,游戲內(nèi)部表示這個氫的傳送帶上對應的十個buffer的數(shù)據(jù)

而當且僅當傳送帶上某些buffer為空時(并不在任何一個物品的10buffer范圍內(nèi),如不連續(xù)的物品間的空隙等),其值為0。

2、傳送帶可推擠插入的機制

這一部分內(nèi)容我在關于藍帶并帶無法跑滿的bug與解決方法中提到過,以下為文字版:

當并帶或分揀器等發(fā)生在線路中部的可推擠插入發(fā)生時,首先,有個插入的目標buffer,即一節(jié)傳送帶的中心buffer:

一節(jié)傳送帶的中心buffer的id,即符號"@"后面的那個數(shù)字

可推擠并帶插入時,首先判斷從目標buffer之后的向下游5個buffer的區(qū)間內(nèi)是否存在空buffer,即是否存在空隙。若不存在空隙則無法插入

此處模擬一個并帶結(jié)構(gòu),左邊的黃色區(qū)域是往右輸入的一個并帶的物塊,右邊是往上移動的傳送帶,表格中每一行代表一個buffer,左邊的物塊指向為插入的目標index的位置,綠色區(qū)域中至少有一個buffer為空隙時,插入才有可能發(fā)生

若這5個buffer中存在空隙,則會從空隙處開始向下游遍歷到最多目標index+10的位置,找最下游的空隙,并從最下游的空隙開始向前遍歷尋找足夠的空隙來保證線路中有足夠讓物塊插入并推擠的空間。遍歷時,出于卡頓考慮,最多遍歷2880個buffer,如果遍歷2880buffer或者遍歷到傳送帶的最上游(buffer[0]處)時仍未找到10個空buffer,則判定為沒有足夠的空間推擠插入,此次插入不會發(fā)生。反之如果在那之前找到了10個空buffer,則判定可以發(fā)生推擠插入,物塊會被成功輸出到這節(jié)傳送帶上,并且如果一開始沒有10個連續(xù)的空buffer就會將上游貨物向后推擠,以塞下這一個物塊。

3、線路總?cè)萘?、線路貨物數(shù)

在線路數(shù)據(jù)中其它比較重要的信息為線路總?cè)萘亢途€路貨物數(shù),對于一條非環(huán)帶的不閉合線路來說,線路總?cè)萘烤褪瞧鹪趦?nèi)存中的buffer數(shù),而線路貨物數(shù)則是此時線路上有多少個物塊的統(tǒng)計數(shù)量。由第一個概念可以知道,因為1個物塊就需要10buffer的存儲空間,所以一條線路上能夠存放的物塊數(shù)量不能超過(線路總?cè)萘俊?0)后向下取整的值。

此處一條線路的線路總?cè)萘繛?15,代表這條線路上最多放11個物塊

然而,對于環(huán)帶來說,其實際上的線路容量為面板顯示的線路總?cè)萘?9,即如果上述這條線路的信息是一條環(huán)帶的線路信息的話,那么我們實際上可以往線路中放下12個物塊。但是如果 環(huán)帶的物塊數(shù)量≥(線路總?cè)萘俊?0) 的話,環(huán)帶就會發(fā)生爆帶現(xiàn)象,此時環(huán)帶上的物塊將不再刷新,直到外部將物塊取走讓線路貨物數(shù)重新小于線路總?cè)萘俊?/p>

4、環(huán)帶/非環(huán)帶末端輸出與貨物流動邏輯

無論是環(huán)帶還是普通傳送帶都有始末端,buffer[0]所在的位置為始端,buffer[實際線路容量-1]所在的位置為末端。進入線路末端貨物輸出的判定邏輯為末端buffer的內(nèi)容是否為255,即此時是否有一個貨物已經(jīng)頂?shù)骄€路底部無法再在線路內(nèi)向前移動。僅在這種情況下會進行嘗試輸出的判定。此時非環(huán)帶會進行上文說過的可推擠插入的判定,若成功推擠插入,則當貨物數(shù)據(jù)放到目標節(jié)點對應位置后會把最末端的十個buffer清0,相當于完成了一次貨物的轉(zhuǎn)移。對于環(huán)帶來說,其末端輸出是輸出到自己頭節(jié)點的非推擠輸出,他會直接判斷自己的0~9buffer是否為空,若為空則直接轉(zhuǎn)移貨物。若末端輸出失敗,則從有空隙的地方開始向上游遍歷貨物讓貨物依據(jù)傳送帶等級和前方具有的空隙總數(shù)更新。

為了表述得更易懂,下面舉一個例子表示當藍色環(huán)帶上某一貨物接近末端而未抵到末端時的更新情況。


藍帶環(huán)線上物品貨物刷新情況舉例(圖中橫向每格為1buffer,藍色代表貨物所占buffer)

5、環(huán)帶爆帶bug發(fā)生的原理

當環(huán)帶上有[線路真實容量/10]([x]表示不超過x的最大整數(shù))個貨物時,線路上剩余的空隙數(shù)量不超過10個buffer。即使這些空隙全部聚集在0~9buffer內(nèi),也無法保證0~9的十個buffer全為空,所以環(huán)帶末端永遠無法成功輸出,這就導致了整條環(huán)帶堵死。

于是,制作組為環(huán)帶加上了9節(jié)“隱藏buffer”,這就是上面說的對于一個線路容量顯示為n環(huán)帶,其實際線路容量為n+9的原因。然而,這9節(jié)buffer除了沒有統(tǒng)計在環(huán)帶的屬性面板上以外與普通的buffer并無不同。所以這種方式相當于僅僅是擴大了一下環(huán)帶的線路容量而已,它的確讓線路容量為10n+1以上的環(huán)帶在具有n個貨物時可以維持轉(zhuǎn)動,但是與一個線路容量為原線路容量+9的環(huán)帶并無區(qū)別。當環(huán)帶上有n個貨物時,由于這多加的9節(jié)buffer,很有可能多塞一個貨物變成線路上有n+1個貨物。然后就會發(fā)生所謂的爆帶現(xiàn)象。

下附環(huán)帶爆帶前后過程:

圖中藍色區(qū)域為貨物區(qū)域,白色區(qū)域為空隙區(qū)域,貨物順時針流動,插入點后的5buffer黃色豎線的中間區(qū)域即第二節(jié)(《傳送帶可推擠插入的機制》)附圖中綠色的插入判定的空隙搜尋區(qū)域

這邊演示的是藍帶環(huán)帶上貨物離線路末端只有不到5buffer時貨物的運動情況。離底端不到5buffer空隙(此處為3buffer空隙)會使所有物塊只能向前流動3buffer,而不是2buffer插入到線路前端,8buffer留在線路末端。
再之后,由于上一幀所有貨物移動了3buffer,線路始端有13buffer的空隙,這一幀開始時貨物輸出到前10buffer,然后便和上一個貨物之間產(chǎn)生了3buffer的空隙。當著3buffer空隙流動到插入點時,如果剛好處在起始節(jié)點空buffer+空隙數(shù)量>10buffer的情況下就會發(fā)生成功插入,如果其實節(jié)點只有5buffer的空隙,而流動空隙又不足5buffer,那就無法成功插入。這也是環(huán)帶并帶有的時候不會發(fā)生爆帶而有時候會的原因。在推擠沒有波及起始節(jié)點空隙的情況下連續(xù)貨物在環(huán)帶上流動時起始節(jié)點的空隙又5buffer和10buffer兩種情況,相鄰兩幀這兩種情況輪流更替。


6、環(huán)帶爆帶的游戲內(nèi)預防方法及原理

關于這個bug,一種游戲內(nèi)的處理思路就是為環(huán)帶增加一種柔性緩存。這種柔性緩存需要在堵塞時可以比起暢通時額外容納至少一個物塊的能力。除了利用四向制造具有一定邏輯的線路之外(這點視頻里可能會提到,但由于是不推薦的方法在此就不提了)。還可以利用一節(jié)建筑的特性制造更低卡頓、更具功能性的防爆帶結(jié)構(gòu)。以下推薦集裝機法和物流塔法。

方便起見,我們將以類似原理防止環(huán)帶爆帶現(xiàn)象發(fā)生的結(jié)構(gòu)狀態(tài)分為三類:不飽和狀態(tài)、飽和狀態(tài)與堵塞狀態(tài)。

不飽和狀態(tài)下,線路中仍有許多空隙??紤]環(huán)帶的起始節(jié)點,有的時候會產(chǎn)生10buffer以上的空隙后才有新的物塊輸出,此時后輸出的物塊與上一個物塊之間就會產(chǎn)生空隙,給外部插入提供空間。

飽和狀態(tài)時,起始節(jié)點只要一有10buffer以上的空隙就一定會有貨物在頂?shù)较乱粋€貨物的位置進行輸出,這樣就會把線路中的所有空隙鎖在起始節(jié)點處,不會有任何空隙流經(jīng)下游的外部輸入口,防止外部輸入的再次發(fā)生。這就是這些結(jié)構(gòu)防止爆帶的主要手段。

堵塞狀態(tài)即為環(huán)帶末端貨物無法輸出,環(huán)帶始端空隙不足其它貨物輸入,防堵結(jié)構(gòu)自身倉儲已滿或者沒有倉儲的情況。下述防爆帶結(jié)構(gòu)在提到的不適用情況之外不會出現(xiàn)這種情況。

注:下述例子中,環(huán)帶內(nèi)部所有節(jié)點傳送帶等級相同。

物流塔在不飽和狀態(tài)下,因為傳送帶流速相等,所以輸入的相鄰兩個物塊的間隔幀足以讓上一個輸出的物塊移動10buffer,故而在輸出口端物塊沒有被外部推擠的情況下只要有輸入口有輸入即可在輸出口馬上輸出,即使發(fā)生了外部推擠而導致物流塔內(nèi)囤積一個貨物,也會因為環(huán)線不飽和而很快在下一個空隙到達時講內(nèi)部的貨物輸出出去。

由此,只要空隙滿足外部貨物就會不停輸入,直到某次輸入以后堵塞了物流塔的輸出口,讓物流塔內(nèi)有了一個貨物的堆積,并且此時環(huán)線上總空隙數(shù)不滿10buffer,此后,由于物流塔內(nèi)通常一直有1個貨物存在,物流塔將會連每幀都嘗試輸出,只要輸出端口一有10buffer以上的空隙滿上就會倍物流塔內(nèi)部輸出的物塊頂上。不會有空隙往下游流動,于是直到環(huán)帶上貨物被外部取走之前,外部插入永遠不會再次發(fā)生。

集裝機與物流塔邏輯類似,實際上集裝機也具有兩格的存儲空間,故而其也可以從不飽和狀態(tài)進入飽和狀態(tài)而非堵塞狀態(tài)。由于集裝機的斷電狀態(tài)、缺電狀態(tài)、正常供電狀態(tài)以及環(huán)帶上貨物連續(xù)/不連續(xù)等各種情況種類過于龐雜,這邊不方便一個個詳細解釋。并且只要直到集裝機的底層邏輯,集裝狀態(tài)的集裝機在環(huán)帶中運行時的情況并不難推論,故而這邊只講述集裝狀態(tài)的集裝機(對應的解壓狀態(tài)的集裝機邏輯并不能防止爆帶,這邊也不會解釋)。

集裝機內(nèi)部具有兩格的存儲空間,其每幀更新邏輯如下:


集裝機集裝狀態(tài)下的更新邏輯

集裝狀態(tài)的集裝機在正常供電時的更新邏輯如圖所示,每幀會嘗試從輸入端抓取貨物,被抓到的貨物會被放在第一格進行等待,等待時間與集裝機所連的傳送帶等級有關。具體的在《集裝機集裝條件以及單帶4集裝方案》中講過。

對于供電率off狀態(tài)的集裝機,可以認為他的等待時間只有1幀,黃電狀態(tài)的集裝機比較鬼畜,它在某些時候會罷工讓誰都不能過,不過也不會因為黃電而導致放集裝機的環(huán)帶出現(xiàn)爆帶現(xiàn)象,這點可以放心。

7、環(huán)帶爆帶的代碼修復方案參考

代碼上的修復方法有很多種,在此推薦個人認為最合適的一種:

最基礎的更改環(huán)帶自插入的判定條件,將原先貨物頂?shù)綄嶋H最大線路容量時才觸發(fā)自插入判定的邏輯改為只要貨物頂?shù)斤@示線路容量的最大值時就觸發(fā)嘗試自插入的判定。并且將環(huán)帶自插入時只輸出到buffer0~9的邏輯改為輸出到buffer0~14的可輸出位置的最前端。

這樣做的原理就是讓環(huán)帶末端本身具備貨物容量緩沖的性質(zhì)。當貨物到達線路最大容量-9時便會被嘗試輸出到線路始端,倘若發(fā)生了一次堵塞,就不過是讓貨物在線路上多移動一幀,而在這一幀之后由于嘗試輸出到0~14buffer最下游可輸入位置的特性可以保證貨物的無縫隙輸出,這樣在環(huán)線下游就不會有空隙流經(jīng)外部輸入口。

然而這樣并不能完全修復爆帶bug,因為當外部輸入目標為環(huán)帶起始節(jié)點時由于目前常規(guī)的一格節(jié)點間距環(huán)帶帶起始節(jié)點的中心bufferid為10,故如果當id為0~10+x(0<x≤5)的buffer為空的時候起始節(jié)點有可能在被自插入之前被外部輸入搶先塞入物塊。所以這種方式只是避免了大部分環(huán)帶的爆帶現(xiàn)象,無法完全修復這個bug。

不過對于上述遺留問題對玩家來說有一種完全沒有成本的解決方案——那就是將環(huán)帶中所有傳送帶(或者至少環(huán)帶中有外部輸入的部分)替換為節(jié)點間距在1.5格赤道格長度以上傳送帶,使用藍圖可以比較輕松地達到這個目的。這樣做就能保證有外部輸入的起始節(jié)點的中心buffer的id一定在15以上。

如果不希望玩家需要了解這一機制并給出對應解決方法,想要從游戲代碼上完全杜絕爆帶情況,還有接下來兩種方案。

第一種是更改環(huán)帶生成時的數(shù)據(jù)結(jié)構(gòu),直接從代碼上保障環(huán)帶頭節(jié)點的中心buffer在15以上,也即給環(huán)帶的頭節(jié)點前部加上固定15個buffer(有點類似現(xiàn)在加在環(huán)帶末尾的隱藏buffer的意思)。這樣即使是節(jié)點間距為0.2赤道格長度的環(huán)帶始節(jié)點,其中心buffer的id也能在15以上。

另一種是繼續(xù)更改邏輯,不過這工作量可能會很大,需要考慮各種各樣的情況?;舅悸肥窃诃h(huán)帶自插入判定的過程中若找到10buffer空隙時代表當前bufferid的index值若<10則需要從環(huán)帶末尾開始向前遍歷那9節(jié)隱藏buffer,然后將空隙數(shù)減去非空的隱藏buffer的數(shù)量。因為這里的隱藏buffer可以看作是為了維持環(huán)帶運作的不可占用的buffer,只不過有時環(huán)帶始端會借用這隱藏buffer的空隙,故而在外部嘗試插入向前遍歷空隙時需要弄清起始節(jié)點向隱藏buffer的“借款”,防止錯誤估計起始節(jié)點的資產(chǎn)安排項目之后沒有足夠空隙周轉(zhuǎn)造成壞賬。

要讓環(huán)帶更真實、更符合背景設定,就像現(xiàn)實生活中中轉(zhuǎn)圈圈的傳送帶一樣的話,還要更改邏輯讓外部輸入環(huán)帶時并不是每次向前遍歷空隙到buffer0處就停止了,而是應該遍歷一整圈或者2880buffer。不過這樣就需要在更新邏輯中寫下更多的情況了,包括“環(huán)帶長度是否>2880buffer”、“插入點id區(qū)間為[0,2870]還是[2871,2880]還是[2880,∞)”等等分類討論。不過這一問題對于玩家來說如果不刻意觀察細節(jié)會很難發(fā)現(xiàn),不像現(xiàn)在的環(huán)帶爆帶bug一樣,基本接觸過混帶的玩家都深受其害。

混帶玩法是目前游戲內(nèi)上限和可玩性都比較高的一種藍圖流派,若果能修復這一bug可以給混帶玩法的走線更多自由的空間(至少不用因為擔心爆帶而強塞一個集裝機,有些走線可以更密甚至不落地),也能降低這種藍圖的卡頓(畢竟集裝機單線程,卡頓也不低),作為玩家而言我還是比較希望能早日修復這個bug的。

【戴森球計劃】游戲內(nèi)傳送帶結(jié)構(gòu)與刷新機制與環(huán)帶爆帶bug原理及游戲內(nèi)外修復方法的評論 (共 條)

分享到微博請遵守國家法律
霍林郭勒市| 建始县| 通河县| 新兴县| 金华市| 阳东县| 甘孜| 蒙城县| 石阡县| 隆安县| 陇西县| 鄂托克前旗| 左贡县| 曲周县| 博湖县| 临澧县| 日喀则市| 葫芦岛市| 成安县| 卢氏县| 永川市| 平安县| 黔西| 临西县| 资中县| 宾川县| 贞丰县| 崇阳县| 禹州市| 淮滨县| 德州市| 吉安县| 青田县| 肇源县| 珲春市| 黎城县| 日土县| 韶关市| 建湖县| 奇台县| 恩施市|