今天的計劃
今天的工作重點是進行吸引模式(attract mode)的開發,主要是處理游戲的進出和其他一些小的細節問題,這些是之前想要整理和清理的部分。我做了一些工作,將游戲代碼中的不同部分分離到邏輯上獨立的區域,這樣就可以更容易地管理和切換不同的游戲模式。
例如,我可以啟動一個獨立的過場動畫,它是完全自包含的;同樣,我也可以啟動世界模式,它也是自包含的,這樣就能方便地在它們之間切換并進行操作。這些就是我想要完成的主要目標,雖然昨天我們大部分做完了,但因為時間不夠,沒能完全完成。所以今天的任務就是把剩下的部分完成。
回顧昨天取得的進展
現在回頭看看我們昨天留下的狀態,基本上我們已經把所有需要的部分都提取出來了,但最后的一些內容還沒有來得及完成。目前游戲已經無法正常啟動了,因為我們把啟動相關的那部分邏輯移除了。
現在的流程是,會先進入過場動畫,這部分運行是正常的,也就是說,過場動畫的啟動已經被成功地獨立出來,結構上也比較合理。然而,如果此時按下空格鍵,原本應該讓角色進入游戲世界的功能卻沒有任何反應。同時,按下 ESC 鍵也不能退出游戲了。
也就是說,原本在游戲運行過程中用來處理界面交互的那一部分代碼已經不在當前流程中了,導致無法響應用戶輸入。因此我們接下來需要修復這些問題,把這些邏輯重新接入進來。
此外,也開始思考為什么當前這個場景會出現這樣的狀況,以及可能的原因。這就是今天需要集中處理的部分。
臨時調整以修復開場動畫鏡頭的縮放問題
我們發現當前某一個鏡頭完全沒有進行預期的縮放操作。昨天其實已經注意到了這個問題,當時還在想是否不小心把這個鏡頭的縮放邏輯刪除了。查看代碼后發現,這個鏡頭(比如鏡頭2)是有設置縮放的:從 (0,0,0)
縮放到 (5, -5, -1)
,按理說應該是有動態變化的。
但實際運行時卻完全感覺不到鏡頭的縮放變化,非常奇怪。其他鏡頭的縮放操作都能正常工作,只有這個出現了異常。于是我們開始嘗試定位問題。
首先確認各個圖層的深度(Z 值)是不同的,比如角色、樹、墻、窗戶和冰柱等,它們都位于不同的深度層級上,所以從邏輯上講,不應該出現畫面靜止不動的情況。
為了進一步驗證問題,我們人為地把縮放的時間增量(dt)加大,使其縮放效果更加明顯,這樣可以觀察是否有任何視覺上的縮放運動。結果顯示確實有縮放,只不過幅度太小,肉眼幾乎察覺不到。因此判斷問題在于縮放太過微弱,導致看起來好像沒有發生任何變化。
于是我們嘗試將縮放速率加倍,測試是否能讓運動更加明顯。發現確實更容易看出鏡頭在運動了,但依舊顯得很微妙。最終推測,等到之后要把配音或者背景音樂和鏡頭同步的時候,再回來調整這個鏡頭,讓它看起來更有戲劇性一些。
此外,還有一個小問題:當前的角色和樹似乎在畫面中的位置太突出,導致整體視覺效果不夠協調,缺少景深感。所以也考慮稍微把它們往后推一點,讓它們更靠近背景,從而提升整體畫面的層次感。
最后的結論是,當前需要繼續思考在過場動畫、吸引模式(Attract Mode)等不同階段如何處理 UI 的顯示與交互。對于過場動畫這類內容,傾向于盡量不添加過多 UI 操作邏輯,讓畫面保持簡潔專注。總體目標還是希望不同模式之間可以順暢切換,同時讓畫面和交互都保持良好的用戶體驗。
重申模式切換的工作方式
我們目前在思考如何處理過場動畫和吸引模式(Attract Mode)期間的 UI 問題。我們的想法是,在這兩個階段中,UI 應該盡量簡化,保持干凈整潔。因為在這些階段中,唯一真正需要響應的交互行為,就是玩家試圖開始游戲的操作——例如按下“開始”按鈕。在這種情況下,系統應該立即切換到游戲模式。
除此之外,吸引模式和過場動畫階段不需要處理其他任何復雜的交互邏輯。一旦切換到了游戲模式,那些游戲內的功能,比如角色加入、多人參與等,都會由游戲模式本身來處理,這樣流程也會更加清晰。
我們也考慮到了可能支持多位玩家的情況。雖然還沒有最終決定是否在正式發布版本中開放多人模式,但我們希望從結構上預留這個可能性。為此,我們設想加入游戲的機制應該是隨時都可用的,而不是某個特定狀態下(比如在過場動畫期間)才生效。換句話說,“加入游戲”的操作不能受限于當前是哪一種模式,它應該在任何時候都有效,這樣才能支持流暢的多人游戲體驗。
因此,我們的決定是:
- 將所有與 UI 有關的處理邏輯集中放在游戲模式中;
- 在吸引模式或過場動畫中,僅實現一個非常基礎的響應邏輯:只要有玩家觸發“開始”操作,就立即切換到游戲世界;
- 進入游戲世界后,由該模式負責處理所有后續的 UI 和交互流程。
這種方式既保持了結構的清晰,也避免了在非游戲階段引入復雜的交互處理,從而保證了系統整體的健壯性和可擴展性。
對縮放效果進行最后調整
我們目前的過場動畫視覺表現已經比之前好很多了,運動感變得更明顯,看起來更加自然,不再顯得那么生硬。雖然目前還不是最終效果,但已經接近可以接受的程度了。暫時先不繼續優化這一部分,等以后再來處理。現在主要是確認了一下整體鏡頭的動態是否如預期那樣逐漸推進,并驗證了角色在鏡頭中是否合適。
我們稍微調整了角色的位置和大小,之前角色有點偏移和比例不對,現在進行了居中和比例微調,看起來更合理了。雖然這個優化細節不太重要,但為了后續劇情表現更自然,我們還是選擇花點時間把這個視覺效果做好。
之后我們準備繼續處理邏輯部分,本來計劃進入“吸引模式(attract mode)”的相關文件,但發現根本不需要那個文件,所以將其刪除。因為我們其實不是真的需要一個獨立的吸引模式,而是通過過場動畫(cutscene)來完成吸引模式的作用。也就是說,我們把“吸引模式”和“劇情開場”合并為一個系統,在進入游戲前就用同一個機制處理,避免邏輯重復。
所以現在的流程設計是:
- 啟動游戲后默認進入過場動畫(同時作為吸引模式);
- 玩家在任何時候按下“開始”鍵或其他輸入,就直接跳轉進入游戲模式;
- 游戲模式內部負責處理玩家加入、交互界面等所有復雜功能;
- 保證邏輯清晰分離:吸引/過場只負責展示,交互和控制只在游戲模式內處理;
- 同時,我們也順便在視覺細節上微調了人物位置與比例,使畫面更平衡自然。
總之,我們現在的整體邏輯和美術層都在朝著模塊清晰、表現自然的方向推進,打下了進一步開發的基礎。
為開場動畫和標題屏幕的游戲模式添加輸入處理
我們現在正在處理游戲啟動流程中與“標題畫面”和“過場動畫”相關的輸入邏輯整合工作。目標是讓玩家在這些階段只要按下“開始”鍵,就可以無縫進入游戲世界,且這一行為邏輯保持一致。
目前的邏輯結構是這樣的:
我們有兩個初始界面:一個是“標題畫面”,另一個是“過場動畫”。這兩個模塊都需要響應玩家的輸入,特別是“開始游戲”或“退出游戲”的操作。因為它們的行為幾乎相同,所以我們決定將這段輸入檢測邏輯抽取出來,封裝成一個統一的函數,例如叫做 check_for_start
或更廣義的 check_for_meta_input
。
這個新函數的職責就是:
- 遍歷所有的控制器;
- 檢查是否有玩家按下了“開始”鍵或者“返回/退出”鍵;
- 如果按了“開始”,我們就立即切換到游戲世界模式;
- 如果按了“退出”,就設置一個退出標志,通知主程序進行游戲關閉操作;
- 一旦有任何輸入發生(無論是開始還是退出),就終止進一步輸入處理(比如跳出循環),避免重復處理。
為了實現切換到游戲世界,我們使用了一個叫 PlayWorld
的函數,它會啟動游戲世界并初始化玩家數據。當玩家按下“開始”鍵后,我們調用 PlayWorld
,并將當前游戲狀態傳進去用于初始化。之后,如果需要進一步控制,比如直接渲染第一幀游戲畫面,也可以調用 UpdateAndRenderWorld
。
關于退出的處理,我們注意到之前的邏輯是通過訪問 game_memory
來設置 QuitRequested
標志。不過考慮到代碼結構和邏輯職責劃分,我們現在傾向于把 QuitRequested
放在 game_input
中,這樣可以避免到處傳遞 game_memory
,邏輯也更加集中。因為退出本質上是一種輸入行為,放在輸入模塊里更合適。
接下來,我們還有一些細節邏輯上的規劃:
- 如果在檢查到“開始”按鈕被按下之后要切換到游戲模式,我們可能不希望當前畫面繼續更新和渲染。相反,我們可能要“跳過”本幀的后續處理,讓下一個模塊(游戲模式)接手;
- 因此,我們會在輸入檢查后判斷是否有模式切換,如果有就直接返回,避免多余操作;
- 我們可能還會設計一個更系統化的框架,例如統一管理模式切換、狀態持有和切換后的初始化流程。
整體來說,我們正在朝著結構清晰、邏輯分離的方向重構啟動階段的邏輯,確保標題畫面和過場動畫都具備一致且穩定的輸入響應行為,同時為之后的游戲世界模式提供清晰入口。最終目標是讓整個游戲從啟動到進入游戲的過渡流暢自然,不存在邏輯沖突或混亂。
在游戲模式調度中添加一個循環,允許在發生模式切換時立即重新運行更新/渲染
我們現在正在整理并優化游戲主循環中的模式切換邏輯,尤其是當游戲從標題畫面或過場動畫切換到實際游戲世界時的流程控制。目標是確保當輸入發生導致模式發生切換時,系統能立即響應并跳過當前不再適用的邏輯,快速進入新的模式,同時結構上保持簡潔、靈活、可維護。
核心思路如下:
我們在主循環(位于 handmade.cpp
)中,通過判斷當前的游戲模式(Game Mode)來調用相應的更新與渲染邏輯,例如調用 UpdateAndRenderCutscene
或 UpdateAndRenderTitleScreen
。但在這種結構中,一旦模式發生改變,比如玩家按下開始鍵,導致從“標題畫面”或“過場動畫”進入游戲世界模式,原來的邏輯不會立即跳出,而是會繼續執行剩余部分,可能導致邏輯混亂或畫面撕裂。
為了解決這個問題,我們引入了一個標志變量,例如 rerun = false
,表示是否需要“重新執行一次主循環判斷”。具體做法如下:
- 在每幀主循環中增加一個
do-while
或等效結構,允許在模式切換后立即重新判斷游戲當前模式; UpdateAndRenderCutscene
和UpdateAndRenderTitleScreen
被調整為在處理完輸入后返回一個布爾值;- 如果返回
true
,表示模式已經改變,需要“重新執行”一次主循環流程; - 如果返回
false
,表示沒有變動,可以繼續處理當前模式;
- 如果返回
- 模式切換函數不需要直接跳出邏輯,而是通過設置返回值來通知主循環“我切換了模式”;
- 對于退出游戲的請求(
QuitRequested
),它不會觸發 rerun,因為不會改變模式,僅僅設置一個退出標志即可。
示意邏輯如下:
bool rerun;
do {rerun = false;switch (GameMode) {case MODE_CUTSCENE:rerun = UpdateAndRenderCutscene(...);break;case MODE_TITLE:rerun = UpdateAndRenderTitleScreen(...);break;case MODE_GAME:UpdateAndRenderGame(...);break;// 其他模式...}
} while (rerun);
這種設計的好處是:
- 結構清晰:每個模式只需關心自己的邏輯和是否需要切換,不需要直接控制全局跳轉;
- 響應迅速:模式切換立即生效,不會延遲到下一幀;
- 易于擴展:未來添加新模式也可以用相同方式接入;
- 邏輯解耦:輸入處理、模式切換、渲染更新各自分離,通過清晰的信號傳遞進行配合。
目前的初步框架已經搭建完成,接下來可以逐步將現有模式模塊化,確保它們都遵循這一約定方式,并統一返回是否需要“rerun”的結果,讓主循環驅動整個狀態流轉。整體邏輯更加穩固且靈活。
將原有的輸入處理代碼移動到世界游戲模式中
我們考慮將當前這部分內容移出,并將其放入 game world 模塊 中。我們傾向于將其放在這個位置,因為感覺這是更合適的歸屬地,但目前還不能完全確定它到底屬于哪里。也有可能它應該放在其他地方,比如某個相關模塊中,但這還需要進一步探索。
對于 controlled heroes(受控英雄) 的歸屬問題,我們也進行了思考。盡管它與 game world 存在聯系,但我們認為它不應該僅僅存在于 game world 中。因為 controlled heroes 可能會在不同的上下文之間持續存在,所以將它放在更廣義的 game state(游戲狀態) 中更為合理。這樣可以確保它的生命周期和作用范圍不會被限制在特定的 game world 中。
基于這一判斷,我們決定將 game state 傳入當前邏輯中,使其能夠在使用過程中靈活地訪問和操作整個游戲狀態,從而實現更高層次的控制和數據管理。這個結構能更好地支持我們后續的功能擴展與模塊解耦。
修復導致的編譯錯誤和頭文件包含順序問題
當沒有英雄存在時,使世界游戲模式切換回開場動畫模式
我們現在處理的是退出流程的邏輯。之前我們的做法是:如果沒有英雄存在,就直接退出。因此我們設置了一個類似 “heroes exist” 的判斷邏輯。現在我們想更進一步完善這個機制,也就是說——
在邏輯執行到末尾時,如果檢測到英雄仍然存在,我們就什么都不做,繼續保持當前狀態;但如果 沒有英雄存在,我們就需要切換游戲狀態,比如 重新進入引導動畫(cutscene) 的狀態。因此我們調用 PlayIntroCutscene
來重新開始流程,同時切換游戲狀態。
在這個切換狀態過程中,我們意識到其實并不需要重新運行任何舊的邏輯,流程也不會受到影響,所以現階段這個切換是安全的。
但當嘗試調用 PlayIntroCutscene
時,發現編譯器報錯:標識符未找到。這個問題確實是之前提到過的 依賴管理 的真實案例。也就是說,PlayIntroCutscene
這個符號需要被暴露給當前模塊,而它還沒有被正確引入。因此我們要把這部分函數上移到更高的作用域(例如頭文件),以便其他模塊能夠調用它。
隨后我們檢查 PlayIntroCutscene
依賴的所有內容,確保都被正確包含和傳遞。同時注意到另一個問題:UpdateAndRenderTitleScreen
函數必須返回一個值。編譯器提示我們遺漏了 return 的部分,這一塊我們已經做了修正,確保它能返回正確的狀態。
此外,我們還意識到在處理標題畫面時,需要同時檢測 meta 輸入,這是用戶交互的重要一環,因此也一并加上了處理邏輯。
最后一個錯誤是:QuitRequested
并不是 game_memory
的成員。這是因為我們此前已經調整了結構,把與退出相關的邏輯從 game_memory
中移走了,可能現在屬于另一個結構或者模塊。因此需要同步更新調用部分,使其與最新的數據結構保持一致。
綜上所述,這一系列工作主要圍繞以下幾個方面展開:
- 基于英雄存在與否決定是否切換狀態;
- 將引導動畫函數暴露給外部模塊使用;
- 補全返回值和輸入判斷邏輯;
- 修復因結構調整導致的成員訪問錯誤;
- 進一步清理并理順模塊之間的依賴關系和調用路徑。
調試新代碼
我們現在的目標是讓當前的這套流程真正運作起來,但這需要一些時間和調試。目前我們正在嘗試初始化某個流程,不過此時傳入的是一個完全無效的 world mode 指針,這顯然是不對的。
我們在調用 fill_ground_chunk
時出現了問題,從現象來看,是傳入了一個錯誤的 world mode。問題是——到底是誰負責提供這個 world mode 的?我們目前并不清楚這個指針的來源,也無法準確確認是哪個模塊或函數生成了它。
進一步回顧整個結構時我們意識到,其實對 ground chunk
的處理我們可能根本不需要。發現這個功能在新的設計方向下很可能不會真正啟用。雖然以前可能有用武之地,但現在它的必要性已經存疑。
盡管如此,我們仍然決定把它先 調試清楚,確保當前流程中不會因為它而出錯。哪怕之后我們完全刪除這部分邏輯,也必須先確認它不會影響其他流程的穩定性。
因此我們接下來要做的是:
- 調查 world mode 的傳入路徑,找出錯誤的來源;
- 明確
fill_ground_chunk
是否在當前或未來版本中還具備實際價值; - 即使未來可能移除,也先保證目前運行狀態下不出錯;
- 整體上繼續理順資源傳遞鏈、數據初始化順序等底層邏輯問題。
這部分的工作主要集中在調試、理清責任鏈、排查無效指針來源,以及決定某些功能是否值得保留的問題上。雖然有些模塊未來可能會被刪減或重構,但在現階段依然必須保證整體系統的穩定性與可預測性。
思考新模式切換代碼如何與多線程交互
我們目前在處理 mode 切換的問題時,面臨一個比較棘手的點——當退出 world mode(或關閉一個 world 實例)時,必須考慮到 仍然可能有線程正在使用這個 world mode 的情況。這是一個線程安全性和資源管理的問題。
換句話說,world mode 相關的數據很可能還被其他線程在后臺訪問,尤其是在執行渲染任務或者是 ground chunk 的生成過程中。如果我們在這些線程仍然運行時就去銷毀 world mode 使用的內存,那么這些線程一旦訪問到被釋放的內存,就會發生嚴重錯誤,甚至導致崩潰。這種場景非常危險,所以必須特別注意。
雖然這次的問題并不是因為我們真的嘗試關閉了一個 world,但這是我們在整體設計中必須重視的隱患之一。
為了簡化當前調試并避免 ground chunk 造成干擾,我們決定 暫時禁用所有 ground chunk 的生成邏輯。具體做法是,直接移除了 fill_ground_chunk
的調用,這樣可以完全避免地面塊渲染所帶來的線程問題和錯誤行為。
禁用后重新運行程序,情況明顯好轉。我們現在可以更清楚地看到系統其他部分的實際運行狀態,也能更容易追蹤和定位其他潛在問題。這種分步調試的方式有助于理清當前混亂的狀態,并逐步驗證每個模塊是否正常運作。
這段調整的核心內容包括:
- 意識到退出 world mode 時需要確保沒有線程仍在訪問其資源;
- 暫時禁用 ground chunk 的異步工作,避免訪問非法內存;
- 移除相關調用后重新運行系統,確認現階段問題得到緩解;
- 為后續的多線程安全管理與資源生命周期控制埋下設計基礎。
整體策略是先停掉有潛在風險的部分,優先理順主流程,再逐步引入并重新實現復雜模塊,確保系統穩定性與可維護性。
更改世界初始化方式
我們發現當前代碼存在一個非常明顯的問題:在真正初始化 world(世界)之前,就嘗試向它壓入結構體(push struct),這是明顯錯誤的。邏輯順序上必須先進行 world 的初始化,否則后續的內存使用都是未定義的。
因此我們決定重新組織這一部分邏輯。現在的做法是:game_state
會負責分配 world 對象,然后再調用初始化函數來完成設定。但從設計角度來看,其實更合理的方式是:讓初始化函數 initialize_world
自己完成 world 的內存分配和子 arena 的創建。因為在初始化過程中本身就需要一個獨立的子 arena,所以由它自己分配內存、并初始化該 arena,會更加清晰、封裝更好。
基于這個想法,我們重命名了初始化函數,從 initialize_world
改成 create_world
,其職責不再是“配置一個傳入的對象”,而是“構造并返回一個全新的 world 對象”。
具體流程變為:
- 在父 arena 上 push 一個新的 world;
- 初始化這個 world 的 arena;
- 返回這個新創建并完成配置的 world 實例。
這樣做的好處是:
- 更符合創建型函數的語義;
- 減少外部調用者的負擔,不再需要自己先手動分配結構體;
- 避免未初始化就使用的潛在風險;
- 邏輯上更清晰,內聚性更強。
在完成重構后,我們編譯時遇到一個小問題:create_world
識別不了,發現是函數名修改后忘記同步調用處的名稱,改正后一切恢復正常。
繼續調試過程中,我們發現:在調用 create_world
后,內部子 arena 請求分配資源時提示 無法分配(can’t fit)。這提示我們:
- 子 arena 可能容量不足;
- 父 arena 剩余空間不夠;
- 或者分配邏輯出錯。
下一步需要重點排查 arena 的容量分配邏輯以及實際分配的內存情況,確保 world 初始化的內存需求可以被滿足,避免越界和分配失敗。
總結當前進展:
- 明確了初始化 world 前必須先分配;
- 重構了 world 創建流程,封裝為
create_world
; - 實現了更清晰的資源分配邏輯;
- 開始排查 arena 內存不足的分配異常;
- 進一步推進系統調試流程,朝穩定結構靠近。
修復世界游戲模式立即退出并返回開場動畫
我們現在進一步調試時發現,當前的運行邏輯仍然存在嚴重問題。比如在游戲中按下空格鍵后,屏幕上什么都沒有,甚至還會錯誤地重新開始播放引導動畫(cutscene),這顯然是不符合預期的。我們意識到需要對其進行深入排查。
首先分析更新和渲染邏輯時發現:
- 在調用
update_and_render
時,并沒有如預期地創建英雄角色(hero),這是主要的問題之一; - 接著嘗試查看
ground chunk
的更新是否恢復正常,結果仍然表現為混亂的內存狀態; - 懷疑是因為一進入世界模式(world mode)后馬上就退出了,導致所有的
fill_ground_chunk
調用都訪問了已釋放的內存區域,于是程序崩潰; - 驗證這一點時發現
heroes_exist
被錯誤地設為了 0,而不是 1;
繼續調查后發現:
- 這是因為輸入檢測邏輯存在不一致,
was_pressed
的判斷邏輯和動畫那邊用的ended_down
不一致,導致根本就沒有檢測到玩家的按鍵動作; - 正確的輸入檢測應該用統一方式進行判斷,兩個邏輯應該一致,才能讓輸入被正確處理,進而創建英雄角色并進入世界模式;
- 當前只有在某個具體代碼路徑中
heroes_exist
才被設為 1,但這個路徑沒有被觸發,所以狀態一直是錯誤的; - 簡單的解決方法是將這一邏輯也覆蓋到其他輸入路徑中,從而確保在任意輸入有效時都能進入正確的流程;
總結當前的修復方向如下:
- 修復輸入判斷邏輯,統一使用
was_pressed
判斷; - 確保每次從 cutscene 切換到 world mode 時,英雄角色都被成功創建;
- 在內存分配邏輯中,防止訪問已釋放的 arena,避免
fill_ground_chunk
等線程繼續運行; - 梳理所有狀態切換的輸入路徑,確保狀態改變后不會被錯誤回退到引導動畫;
- 確保在
world mode
中啟動時,所有必要資源和數據都已初始化成功;
這樣處理之后,系統就能夠在玩家輸入時正確進入游戲世界,不會反復跳回開場動畫,且不會再觸發訪問空指針導致的奔潰。整體邏輯更加穩定,輸入處理也更統一。
運行游戲。現在可以進入游戲模式,但仍然有一些bug
目前系統終于恢復到一個相對合理的狀態了,已經能夠成功進入游戲、啟動流程,也能夠正常退出游戲并返回引導動畫(cutscene),這正是我們期望的基本行為模式。雖然看似整體流程已經通了,但仍然存在兩個明顯的 bug:
Bug 1:狀態切換流程仍不穩定
- 從初始動畫進入游戲世界再返回,再次嘗試進入時,似乎存在某些隱藏的狀態錯誤;
- 當前仍可能在某些情況下導致狀態機異常,比如重復切換時狀態未完全重置;
- 這個 bug 尚未完全定位,但從表現上看像是有未清理干凈的殘留狀態或初始化遺漏;
Bug 2:進入游戲世界后,角色無法移動
- 盡管時間是正常流逝的(可以通過陰影的抖動觀察得出),但玩家無法控制角色移動;
- 說明渲染和更新循環正在運行,但輸入并未被正確地傳遞或處理;
- 推測可能的原因包括:
- 控制器輸入并未綁定到正確的玩家對象;
- 輸入狀態在切換狀態過程中丟失或未初始化;
- 玩家角色雖已生成,但未被賦予控制權或未注冊進可控制實體列表;
- 總之當前輸入系統與實體控制系統之間未正確連接,需要排查創建角色后的綁定邏輯是否完整;
當前進度總結:
- 游戲與引導動畫之間可以來回切換;
- 世界模式的基礎邏輯逐步分離完成;
- 狀態切換仍然存在邊界條件問題;
- 玩家角色移動完全失效,說明輸入鏈未打通;
- 接下來應重點處理輸入系統與控制系統的連接邏輯,并修復狀態初始化一致性問題;
一旦這兩個問題解決,基本的游戲循環就能穩定跑通,可以繼續進入更深層的功能開發。整體看來,當前已經非常接近一個干凈的、可控的狀態管理架構。
通過重新啟用昨天被注釋掉的代碼來修復無法移動的問題
目前正在解決玩家角色無法移動和攝像機未跟隨角色的問題。經過排查,定位和修復進展如下:
問題一:角色無法移動
- 排查方式是直接搜索項目中使用了
#if 0
的地方,尋找被暫時禁用的代碼; - 發現一段與角色控制邏輯相關的代碼塊被注釋掉,導致玩家輸入根本未傳遞到角色控制邏輯;
- 這正符合之前的猜測,即為了臨時測試某部分邏輯,將控制邏輯注釋掉后忘記恢復;
- 將這段代碼重新啟用后,玩家角色可以正常移動,功能恢復。
問題二:攝像機未跟隨角色
- 移動恢復后,發現攝像機并未隨著角色一起移動;
- 懷疑是設置攝像機跟隨目標的邏輯失效;
- 跟蹤相關邏輯,確認攝像機是通過
camera_following_entity_index
來追蹤目標; - 在添加玩家時,會設置該跟隨索引,例如
camera_follow_to = LindseyLowIndex
; - 推測目前的問題可能是該索引值被設置錯誤或未被正確更新;
- 嘗試檢查玩家創建流程中是否有遺漏設置該字段的邏輯;
初步結論:
- 玩家移動問題已修復,原因是控制邏輯被注釋導致輸入未生效;
- ? 攝像機不跟隨角色問題尚在排查中,但基本邏輯鏈清晰,疑點集中在索引值設置或未更新;
- 接下來應:
- 核對添加玩家時攝像機跟隨字段是否確實設置;
- 確保玩家被添加后
camera_following_entity_index
正確指向玩家; - 檢查是否有在其他地方將該值覆蓋或清空;
總體進展:
- 基本的游戲狀態切換、輸入響應、角色控制邏輯已逐步恢復;
- 攝像機邏輯是當前的關鍵缺口;
- 修復后,即可形成完整的“切換-控制-觀察”基礎系統框架,為后續功能擴展(如多人模式、狀態保存等)打好基礎。
修復攝像機無法跟隨的問題,確保區域被零初始化
目前我們正在修復初始化內存未清零導致的各種潛在錯誤,同時也在完善整體內存分配流程,以確保所有結構體或數據對象在首次使用時狀態都是一致的、可預測的。當前的進展與思路如下:
問題現象與本質
- 當前系統中有些對象的內存沒有在分配時清零;
- 而系統設計假設所有分配的內存默認是全零的,因此未初始化會導致不確定行為,例如攝像機未跟隨角色、角色狀態出錯等;
- 所以我們必須確保所有內存對象在分配時都被清零。
解決思路與實現策略
-
改進
PushStruct
宏/函數行為:- 每次調用
PushStruct
分配新對象后,自動清零; - 實現方式是,在
PushSize
之后調用ZeroSize
; - 只清零所申請的內存大小,而不是整個 Arena 剩余空間;
- 這樣可以確保每個結構體被創建時其字段都是干凈的、符合預期的初始值。
- 每次調用
-
可擴展性考慮:
- 為了應對某些特殊情況(比如:不需要初始化大塊內存以提高性能),計劃為
PushStruct
或PushSize
添加一個標志位,用于控制是否清零; - 例如:可以通過傳遞一個參數來決定是否執行
ZeroSize
; - 目前系統中實際使用
PushStruct
的地方并不多,所以檢查起來不復雜,可以一一確認是否需要初始化。
- 為了應對某些特殊情況(比如:不需要初始化大塊內存以提高性能),計劃為
-
重用已有的
ZeroSize
工具函數:- 系統中已有封裝好的清零函數,因此只需在分配后調用它即可;
- 避免重復造輪子,代碼更加整潔。
后續步驟
- 確認現有的
PushStruct
全部按需清零; - 針對大容量非結構體數據的分配,評估是否需要添加跳過清零的標志位;
- 在
Game.h
中調整PushStruct
和PushSize
的實現邏輯,將清零操作作為默認行為; - 測試各種對象的初始化狀態是否符合預期,確保后續邏輯不再依賴未定義值。
總結
通過修改 PushStruct
的默認行為為“分配即清零”,我們大幅提升了程序初始化階段的安全性和可預測性。同時考慮到了未來可能出現的性能優化需求,設計中預留了靈活性接口,為后續系統擴展打下了堅實基礎。
再次運行游戲,修復所有bug后運行正常
目前為止,我們已經修復了一個核心問題:在內存分配時未自動清零,導致程序邏輯在初始化后的狀態異常。現在我們已經確保內存分配時默認會被清零,系統行為恢復正常。以下是詳細總結:
當前實現成果
-
修復了未初始化內存的問題:
系統期望所有新創建的數據結構在一開始就是零狀態,這樣邏輯判斷才能可靠運行。之前由于未清零,導致如角色狀態、攝像機追蹤等邏輯出現混亂,現在已經解決。 -
成功實現了游戲模式之間的切換:
能夠自由地在不同模式(如世界模式和元游戲模式)之間切換,包括:- 創建新世界;
- 進入世界中運行;
- 退出世界并返回元游戲界面。
-
模式狀態一致性良好:
模式之間切換時的狀態保存與恢復如預期工作,沒有出現內存異常訪問、線程沖突或資源未釋放等問題。
當前剩余問題
- 存在一個新問題需要處理,雖然具體細節未展開,但從上下文來看:
- 可能與資源回收、狀態保持或線程管理有關;
- 也可能是切換過程中某些系統狀態沒有完全恢復或清理;
- 具體問題需進一步排查并定位。
總結
當前系統的內存管理已經回歸到預期的穩定狀態。默認的內存清零機制保障了數據結構在創建時的正確初始狀態,使得模式切換、角色控制、攝像機追蹤等子系統恢復了正常功能。接下來,將針對最后發現的異常進一步調試,完成最終的修復閉環。整個架構正趨于穩定和可維護狀態,推進整體開發進入下一個階段。
評論之前提到的關于模式切換的潛在線程問題
目前我們面臨的一個關鍵問題是多線程環境下“地面塊填充(fill ground chunk)”任務的潛在崩潰風險,盡管它現在沒有顯性崩潰,但從架構角度來看,這是一個潛在的嚴重 Bug。以下是詳細總結:
當前發現的問題:多線程任務未安全關閉
-
多線程訪問已釋放內存風險
地面塊填充是一個在獨立線程中運行的任務,而它所訪問的數據結構(例如世界狀態)在模式切換或重置后可能被釋放或重分配。這將導致訪問“懸空指針”,盡管當前沒有崩潰,但實際是讀取了無效或過時的內存。 -
當前之所以沒崩潰是巧合
內存可能還沒被其他內容覆蓋,所以訪問時沒有立即崩潰,但這并不意味著安全 —— 在更復雜或內存更緊張的情況下,這種行為是極不穩定且不可預測的。
我們需要實現的機制:任務引用計數式的安全退出
-
每個游戲模式在退出前,必須確保:
- 自身所創建的后臺任務(如填充地面塊)全部完成或手動終止;
- 不再有任何任務訪問該模式下的資源(如世界數據);
- 模式才可以被安全銷毀或替換。
-
參考模型:
這類似于“引用計數機制”:- 模式啟動任務時,相當于將引用計數 +1;
- 任務完成或主動關閉時 -1;
- 模式在引用計數歸零前不能銷毀;
- 這是任務層面的引用計數,而非內存對象引用計數。
我們的臨時處理:
- 添加了一個重要的注釋標記
// TODO AC IMPORTANT
:- 明確指出
fill_ground_chunk
在模式切換時可能會崩潰; - 標記這是一個必須在最終版本前解決的問題;
- 為后續開發留有清晰的方向指引。
- 明確指出
總結
目前雖然功能表面正常運行,但后臺任務未管理好生命周期是一個明顯的架構漏洞。我們未來需要添加一種機制來確保每個模式退出前所有相關任務已經停止,從而避免懸空內存訪問,確保系統穩定性。這種機制在任何含有異步操作或多線程的系統中都是必須的基礎保障措施。后續開發中需優先解決此問題。
實現標題屏幕的基礎版本
目前我們開始著手處理標題畫面(title screen)系統的構建,并計劃如何使其在游戲流程中合理切換和顯示。整個目標是建立一個基本的主循環模式:片頭動畫 -> 標題畫面 -> 再次進入片頭動畫或游戲主流程。以下是詳細過程和當前實現邏輯的總結:
當前目標:實現標題畫面與過場動畫之間的切換
過場動畫完成后切換到標題畫面
- 原本判斷 cutscene 是否完成的邏輯使用了錯誤的變量名(命名是 cutscene_complete,但含義卻是 still_running),導致語義與實際含義相反,邏輯混亂。
- 現已修正為
cutscene_still_running
,使判斷條件邏輯更清晰:如果動畫仍在播放,就繼續播放;否則,跳轉到標題畫面模式。
標題畫面計時與跳轉邏輯
- 在標題畫面模式中,使用一個變量
title_screen_t
累加每幀的dt
(delta time),也就是實際經過的時間。 - 每幀會判斷是否達到 10 秒時間:
title_screen_t += input.dt_for_frame; if (title_screen_t > 10.0f) {// 切換回 intro cutscene }
- 達到時,切換回 intro cutscene,從而形成循環。
可視化驗證:調試用紅屏清屏
- 為驗證標題畫面確實被觸發,在
update_and_render_title_screen
函數中添加了清屏操作:
用紅色背景清屏作為視覺提示,確認此函數被正確調用。ClearScreenToColor(紅色);
啟動順序驗證調整
- 為便于測試標題畫面邏輯,臨時修改了初始流程,游戲啟動時直接進入標題畫面模式而不是原本的 intro cutscene,方便觀察紅屏是否生效,驗證流程控制邏輯正確。
未來工作展望
- 當前還剩下一個“重大問題”尚未處理,后續會在剩下的時間內進行展示與說明;
- 不過就目前的階段來看,我們已完成以下內容:
- 片頭動畫與標題畫面之間的自動切換;
- 標題畫面的超時跳轉;
- 標題畫面基本渲染路徑的驗證。
小結
我們已經成功搭建起基礎的流程控制框架,實現了 intro cutscene 與 title screen 之間的雙向切換機制,并驗證了標題畫面渲染邏輯的正常執行。盡管還有關鍵問題未處理,但已經朝著模塊化、流程明確的結構邁出了一大步。接下來的重點是進一步完善資源狀態管理以及最后的問題排查與修復。
測試標題屏幕代碼
發現沒有title screen 紅色
switch case 沒進來
目前我們完成了標題畫面的初步實現,并驗證了其在邏輯流程中的正確切換。以下是這一階段的具體內容和調試過程總結:
標題畫面成功顯示與自動切換
- 我們現在已經實現了**“淡出 -> 標題畫面 -> intro 片頭動畫”**的流程:
- 在過場動畫結束后,成功切換至標題畫面;
- 標題畫面保持顯示 10 秒;
- 時間到后,自動切回片頭動畫;
- 邏輯順暢,流程銜接正確。
?加速測試邏輯
- 為了驗證邏輯的完整性,同時避免每次等待過長,我們嘗試人為加速游戲內時間流逝,即調高 delta time 的值,使得 10 秒更快過去。
- 查找了處理
dt
(delta time)的相關代碼位置; - 計劃將
dt
人為增大,加速過渡; - 示例:可以將
input.dt_for_frame
乘以一個因子,如4.0f
,讓模擬時間流逝變快。
- 查找了處理
遇到異常情況
- 在加速時間之后,嘗試運行發現畫面表現異常(出現了 “whoa what happened there” 的情況):
- 可能是加速后導致某些邏輯沒有按預期運行;
- 比如動畫播放提前完成但資源未準備就緒、未正確復位狀態等;
- 有待進一步調試,排查在加速過程中具體出了什么問題。
階段性成果
- 成功實現了基礎流程控制框架;
- 標題畫面與片頭動畫之間可以正常切換;
- 時間控制機制工作正常;
- 基本調試機制(例如視覺反饋、時間調控)生效;
- 初步發現了加速邏輯下的一些潛在 bug,為后續優化提供方向。
這部分標志著我們完成了游戲模式切換機制的一個重要里程碑,下一步需要進一步排查快速切換下的異常,并逐步增加更多內容到標題畫面中(比如實際圖像、文字、菜單等)。目前來看,流程控制的架構已經趨于穩定。
快速調試并修復與模式切換相關的開場動畫崩潰
目前我們意識到當前的游戲模式切換機制存在一個結構性問題,這個問題可能在一些特殊情況下引發錯誤或不穩定行為,下面是詳細總結:
模式切換機制存在的根本問題
我們當前的實現中,每次只允許一個游戲模式(mode)存在。一旦切換模式,就會立刻銷毀原來的模式結構(如 cutscene 的狀態結構)。這會導致以下嚴重問題:
- 如果我們在當前模式中處理邏輯時,中途切換到了新模式,那么當前模式的內存結構立即被清除;
- 接下來代碼中任何對舊模式狀態(如
cutscene_t
)的訪問都會訪問無效的內存區域,造成數據錯亂、程序崩潰或難以定位的潛在 bug; - 當前遇到的異常現象(如時間加速后畫面混亂)其實已經提前暴露了這個問題。
正確做法:延遲模式切換 + 多模式并存支持
為了讓模式切換更穩健、邏輯上更合理,我們決定引入以下機制:
多模式結構并存:
- 即使我們只「激活」一個模式,其他模式的結構仍然保留在內存中;
- 切換模式時,不再立刻銷毀舊模式結構,而是讓其保持活躍直到本幀處理結束;
- 這樣即使新模式已經準備好,也可以等舊模式的處理完全完成后再切換。
延遲執行切換操作:
- 將“模式切換”變成一種延遲操作,只有在邏輯流程真正結束之后再執行;
- 例如設置一個
next_mode
變量,在主循環末尾檢測其是否存在并進行切換; - 避免中途執行切換造成的狀態混亂。
理解方式:任務/資源的引用計數模型
可以將其類比為引用計數管理:
- 每一個游戲模式就像一個帶引用計數的資源;
- 只有當沒有任何代碼再訪問它時,才可以安全釋放;
- 這類似于對「任務」或「線程」管理中確保退出前資源安全釋放的做法。
總結現狀
- 當前實現是單一模式機制,存在訪問已銷毀數據的風險;
- 我們決定升級為支持多模式并存 + 延遲切換機制;
- 這樣能提高系統健壯性、避免潛在 bug,同時也便于擴展復雜的游戲邏輯(如后臺加載、過渡動畫等);
- 這也是下一階段開發中的一個關鍵性目標。
接下來我們將實現這個改動,重構相關的模式切換邏輯,使其更加穩定、健壯和易于維護。
游戲運行正常,三個游戲模式都按預期工作
我們目前已經完成了模式切換的基本流程測試,并驗證了之前的問題是否存在。以下是本階段的詳細總結:
驗證模式切換與加速播放的穩定性
- 以 10倍速運行過場動畫(cutscene),用作測試加速模式下是否會引發潛在的邏輯錯誤;
- 動畫順利播放完畢后,成功切換回標題畫面,說明基本的狀態管理與時間推進邏輯在高倍速下依然穩定;
- 接著成功從標題畫面進入游戲場景,然后又成功退出回元模式界面;
- 整個過程中,模式狀態切換正確、流程流暢,沒有崩潰或卡頓現象,初步驗證之前的問題已經得到了控制。
標題畫面尚未完成但已占位
- 當前只是使用占位的紅色背景作為臨時標題界面;
- 后續需要正式設計和繪制標題畫面,內容可能包括:
- 游戲名稱或 LOGO;
- 背景動畫或靜態畫;
- 菜單選項(開始游戲 / 設置 / 退出等);
- 一旦圖像資源準備好,可以直接接入現有流程中,無需重構切換邏輯。
游戲流程基本架構已具雛形
目前已實現以下基本結構:
- 啟動時播放過場動畫;
- 動畫結束后自動跳轉到標題畫面;
- 標題畫面停留固定時間后,重新播放過場動畫(循環演示模式);
- 支持從標題進入游戲,再退出回主界面;
- 支持退出程序。
這些邏輯構建了一個初步可交互的“完整體驗流程”,為后續游戲正式內容的擴展打下了基礎。
當前進度與階段性成果
- 已完成:多模式并存邏輯、延遲切換機制、狀態保持與銷毀管理;
- 正在進行:標題畫面設計、美術資源接入;
- 已驗證:高速運行下流程穩定性、模式切換正確性;
- 下一步目標:完善標題畫面后,進入游戲主體功能的構建階段。
總的來說,我們已經從一個原始的啟動動畫過渡到了一個具備完整流程的基礎游戲框架。雖然功能還不豐富,但骨架已基本成型,接下來就可以圍繞這個流程不斷豐富細節和內容了。
能否在嘗試實時調整開場動畫的值時利用調試代碼,而不是重新編譯?
我們其實可以在調試中直接利用調試工具來查找過場動畫(cutscene)與實時運行(real time)之間合適的時間值,而不是每次都重新編譯來測試。但目前我們還沒有完全完成調試系統的開發,所以暫時還無法真正派上用場。
調試功能還需要繼續完善,等到調試界面和參數可視化控制做好之后,就可以在運行時動態修改和觀察數值變化,從而更高效地調整動畫時長、速度等參數,而無需頻繁地手動修改代碼并重新編譯。
總結如下:
- 調試工具理論上可以用于快速調整參數,例如 cutscene 時長等;
- 當前調試系統尚未完成,暫時不能實際使用;
- 后續將繼續開發調試模塊,使其支持實時調節、數值追蹤等;
- 已有初步的片尾/title信息展示邏輯,可能用于標記階段性完成或作為演示用途。
這個部分雖然簡短,但也說明未來開發中會更多依賴調試工具,來提升開發效率與測試準確性。
如何在結束時終止或結束每個線程?
在結束每個線程時,是否指的是在整個程序執行完畢之后?即在游戲關閉時,所有的線程都需要被正確關閉嗎?
這一問題涉及到程序在退出時如何正確清理資源和終止各個線程。通常,在游戲或者應用程序結束時,所有的后臺線程和任務需要被終止,以防止在程序關閉后,仍然有線程在后臺占用資源或發生錯誤。
我們會重新實現性能分析器嗎?
會重新實現性能分析器嗎?是的,當我們達到想要的調試狀態時,可能不會太遠,我們會完成調試代碼部分,以便能夠查看并實現性能監控功能。
可執行文件的結束
當可執行文件退出時,其實不需要手動關閉線程。當退出時,程序會跳出主循環,執行return 0
,這時會進入C運行時庫的外部代碼,調用exit process
,這會終止所有線程,包括我們的線程。所以不需要特別去關閉線程,它們會自動結束。
能否重新解釋一下為什么在開場動畫之后無法移動英雄?
之所以在過場動畫之后無法移動角色,是因為相關的控制代碼被注釋掉了。原因是當時還沒有完成相應的代碼遷移,這導致了角色無法移動。
如果有人想以不同于原生分辨率的全屏模式運行游戲,應該怎么更改?你之前說過不喜歡菜單,那么會用啟動器來提供這些選項嗎?
關于如何在不同分辨率下全屏運行游戲,如果需要改變分辨率的設置,最好將這些選項放在游戲啟動器里,而不是游戲內的菜單中。這是因為,游戲啟動時如果分辨率設置不當,可能會導致畫面無法顯示,從而無法訪問游戲內的設置菜單進行修改。因此,最理想的方式是將這些設置放在游戲啟動前就可以調整的地方,比如 Steam 啟動器中,用戶可以通過右鍵點擊游戲,設置命令行參數來修改分辨率。
這樣做的好處是,普通用戶不需要關注這些技術性設置,游戲可以自動選擇最佳分辨率,確保大多數玩家無需手動調整,像看電影一樣,用戶只需點擊播放,系統會自動選擇最佳的畫質。只有那些對技術比較精通的玩家,才會需要或者想要修改這些設置,而這些高級設置應該放在一個完全獨立的技術性區域,普通用戶在啟動游戲時永遠不需要看到這些內容。
啟動時是否可以做一些分辨率檢測,避免啟動時出現破壞性分辨率?
關于分辨率檢測和啟動時避免使用不適合的分辨率,最安全的做法是始終使用桌面分辨率啟動游戲。即使操作系統報告顯示器支持當前分辨率,實際上可能存在顯示器不兼容的情況,導致用戶看不到任何畫面。因此,為了確保游戲在啟動時能夠顯示,最好根據用戶當前的桌面分辨率啟動游戲,因為用戶必須已經能夠正常使用該分辨率。
如果某些用戶希望擁有更高的自定義控制權限,那么他們可以通過編輯配置文件來設置分辨率等參數,但需要明確告知用戶編輯配置文件時要小心,游戲不會對因修改配置文件所帶來的任何問題負責。這樣的方式可以讓那些有技術需求的用戶自行調整,而普通用戶則不需要擔心這些設置,始終能夠順利啟動游戲。
你說“普通人”,好像說技術人員是件很糟糕的事。
在討論“普通人”時,并不是貶低那些懂技術的人,而是指那些不關心技術細節的用戶。如今,很多人可能根本不知道自己的分辨率是多少,尤其是智能手機用戶。以前,玩電腦游戲的人往往了解分辨率是什么,但現在很多人甚至不關心這個問題。當一個普通人玩游戲時,他們可能連分辨率都不清楚,特別是如果他們是手機用戶,或者他們在購買電視時才知道分辨率的高低。因此,現代游戲的目標是讓大多數人不需要了解技術細節,游戲應該能自動適應,盡量讓一切都“正常工作”。
這意味著對于大多數用戶來說,游戲應該自動選擇合適的分辨率和設置,而不需要用戶進行任何操作。然而,對于那些技術感興趣、希望調整游戲設置的用戶,可以通過啟動文件或命令行參數來修改一些高級設置,如強制特定的分辨率或幀率等。這些設置不應該出現在普通用戶看到的菜單中,因為大多數人并不關心這些內容,他們只希望游戲能順利運行。
因此,理想的情況是,游戲能“自動工作”,不讓普通用戶擔心技術細節。如果有技術需求的用戶需要調整,他們應該能夠在一個特定的配置文件或參數中修改,而不是通過游戲菜單進行操作。
進一步討論分辨率/4K
如今,大多數人對分辨率的了解其實非常有限,通常只是知道“1080p”或者“4K”這些名詞,而對具體的技術細節并不清楚。例如,很多人可能會問“這是1080p的顯示器嗎?”但他們并不真正理解1080p代表什么,而4K的概念也常常讓人感到困惑。4K實際上并不是指某一個特定的分辨率,而是一個包含多個分辨率的范圍,通常這些分辨率至少是1080p的兩倍。更復雜的是,不同的顯示器可能會被稱為“4K”,但它們的分辨率其實不同,有些可能是多個1080p分辨率拼接在一起,或者是更高的分辨率,如5000×某個值,比4個1920×1080的屏幕還要高。
總的來說,大多數普通用戶并不關心這些細節,他們只是知道“4K”是更高質量的顯示標準,但并不理解不同的4K顯示器之間的差異。
通常在開發游戲時,你會先做開場動畫代碼還是游戲玩法代碼?
在開發游戲時,是否先做劇情動畫代碼還是先做游戲玩法代碼并沒有固定的規則。通常會根據項目的需求來決定。比如,如果劇情動畫的藝術制作非常耗時,并且需要與游戲的開發有較大重疊,那么可能會提前編寫劇情動畫代碼,以便藝術團隊可以在開發過程中有所準備,避免出現意外情況。但如果劇情動畫的制作不需要太多與游戲玩法的交互或影響,那就可以將它推遲到最后再做。
作為程序員,應該根據項目的依賴關系來安排開發時間,確保技術開發與藝術團隊的工作能夠盡可能順利地銜接。這意味著有時候需要先做劇情動畫的代碼,有時則可以在游戲開發后期再做,這完全取決于項目的具體需求。
對于這個項目,劇情動畫代碼之所以提前做,是因為它可以有效利用渲染器,并且不會過多依賴游戲的其他部分。這樣,藝術團隊可以在不完全依賴游戲玩法的情況下,先行制作動畫部分,而不必等到某些玩法元素完全確定后才開始。
在項目中,程序員的開發進度相對較慢,而藝術進度通常會更快。因此,開發順序不僅取決于技術需求,還要考慮如何在直播過程中更高效地學習和展示。這個順序可能會與傳統的開發方式有所不同,因為直播的特點要求程序員調整開發順序,以便觀眾能夠更容易理解和跟隨開發過程。
我們是否已經接近需要實現mixins的階段?
目前,是否需要實現混合功能(mix-ins)取決于是否決定繼續推進游戲玩法代碼的開發。如果決定直接進入游戲玩法代碼的實現,那么可能會涉及到混合功能的實現。然而,如果之后決定回過頭來完成一些其他的工作,那么就不一定需要立刻實現混合功能。具體情況尚不明確。
C++17模塊能解決#includes依賴問題嗎?
C++17模塊是否能解決包含依賴問題的問題沒有明確的答案,因為即使是C++委員會的新特性也很少能有效解決實際問題。在過去的經驗中,新增的特性常常會出現不符合預期的情況,即使看起來是簡單的功能,通常也需要開發者付出很多額外的工作才能使其正常運作。這種現象在C++中已經變得很常見,尤其是當引入像“decltype”這樣的新特性時,就發生了預期之外的問題。例如,在嘗試使用“decltype”來獲取某個類型的大小時,原本簡單的任務變得異常復雜,甚至需要創建模板來強制映射類型,這顯得非常不合理。
這種問題的出現源于C++委員會在設計語言特性時,往往沒有考慮到開發者的實際需求和使用場景,導致新增的功能不僅不直觀,而且使用起來非常繁瑣。因此,盡管C++模塊被提出來作為一種可能的解決方案,但對于其是否能真正解決包含依賴問題,仍然持懷疑態度。總的來說,C++的語言發展方向似乎經常導致開發者面對的是一系列復雜而不必要的解決方案,尤其是對于那些本來可以通過簡單方法完成的任務。