[Lua遊戲AI開發指南] 筆記零 - 框架搭建

野生西瓜發表於2022-03-29

一、圖書詳情

《Lua遊戲AI開發指南》,原作名: Learning Game AI Programming with Lua。

豆瓣:https://book.douban.com/subject/30268009/

出版社圖書詳情:https://www.ptpress.com.cn/shopping/buy?bookId=23e4c970-5ad8-4dfa-a850-8da889927e89

二、前言

本文為此書的學習筆記,筆記順序不與書籍內容一一對應。大概是記錄碰到的問題及衍生的學習資料,以作備忘。

各種第三方模組的編譯和整合是一件很繁瑣的事情,作者為了便於教學,預先組裝了一個相對容易構建的“沙箱”,以使讀者能夠專注於遊戲AI開發。但書籍出版於2014年,“沙箱”本身的構建也因為執行環境的變動而出現了各種編譯錯誤。

本節記錄一些環境搭建過程中碰到的構建錯誤,主要是書本第一章的內容。

三、執行環境

  1. Windows 10
  2. Visual Studio 2019

四、生成 Visual Studio 解決方案

(一)隨書程式碼獲取

從“出版社圖書詳情”連結可下載隨書程式碼資源,解壓後目錄結構如下:

├── bin
├── decoda
├── media
├── premake
├── src
├── tools
├── CHANGES.txt
├── LICENSE.txt
├── README.txt
├── vs2008.bat
├── vs2010.bat
├── vs2012.bat
└── vs2013.bat

(二)premake 替換

執行 vs20xx.bat 檔案會呼叫的主要命令列如下,4個bat檔案的區別只是 premake 的引數不同:

// vs2013.bat
...
// 呼叫 premake5 程式
// 使用 premake/premake.lua 作為構建配置清單,生成 vs2013 專案
tools\premake\premake5 --os=windows --file=premake/premake.lua vs2013 %ARGUMENTS%
...

要生成 vs2019 的解決方案,需要從 premake 官網 下載最新的 premake5,替換掉 tools\premake\premake5。

然後拷貝建立一份 vs2019.bat 檔案:

// vs2019.bat
...
tools\premake\premake5 --os=windows --file=premake/premake.lua vs2019 %ARGUMENTS%
...

執行 vs2019.bat,將在 build 目錄下生成 Learning Game AI Programming.sln 及一系列專案檔案。

五、各種編譯錯誤解決

使用 vs2019 開啟 Learning Game AI Programming.sln,可以從解決方案資源管理器看到整體的專案結構。

生成解決方案,提示各種編譯錯誤:
圖片1

(一)編譯器錯誤 C2220

C2220 - 警告被視為錯誤

右鍵屬性 - 配置屬性 - C/C++ - 常規 - "將警告視為錯誤"

圖片2

但教學解決方案中包含了十幾個專案檔案,不可能一個一個修改,所以要修改的是前面提到的構建配置清單:premake/premake.lua

註釋掉 premake.lua 中的 “FatalWarnings”,執行 vs2019.bat 重新生成解決方案,編譯錯誤數量從 321 -> 161。

(二)編譯器錯誤 C2440

C2440 無法從"type1"轉換為"type2"

Unicode 字元問題,同樣在專案右鍵屬性 - 配置屬性 - 高階 - "字符集",可進行修改,從 Unicode 改為 多位元組字符集

對應到 premake.lua 中,新增 characterset 配置:

...
solution( "Learning Game AI Programming" )
	location( "../build/" )
	configurations( { "Debug", "Release" } )
	platforms( { "x32", "x64" } )
	characterset ("MBCS")
-- configuration shared between all projects
	language( "C++" )
	includedirs( { "../src/%{prj.name}/include/" } )
    warnings( "Extra" )
	flags( {
--		"FatalWarnings",
...

執行 vs2019.bat,重新生成解決方案

(三)Cannot open include file "d3dx9.h"

Windows 10 不包含D3D9相關的工具庫,最新的 D3D12 則似乎是與 Windows Kit一起安裝在 Program Files (x86)\Windows Kits\10\。

參考:https://stackoverflow.com/questions/63287230/how-to-find-directx-loctation-for-d3dx9-h-error

https://www.microsoft.com/en-us/download/details.aspx?id=6812 下載安裝 DirectX SDK,通常會安裝在 Program Files (x86)\Microsoft DirectX SDK (June 2010),安裝程式會自動設定 $(DXSDK_DIR) 環境變數

(四)#error: Macro definition of snprintf conflicts with Standard Library function declaration

#error 是自丟擲的錯誤,按照錯誤提示,大意是重複定義了 snprintf 巨集,因為在 VS2015 以上版本已經對 snprintf 提供了官方支援。

所以全文搜尋 define snprintf _snprintf 進行註釋,大約有4處。

(五)LNK2019: 無法解析的外部符號 __vsnprintf

修改完錯誤(四)後大概會報這個錯誤,大意是找不到 __vsnprintf 這個函式,因為我們剛把巨集定義註釋了,而這些靜態庫又找不到官方支援的行內函數(?),所以我們需要引用依賴 legacy_stdio_definitions.lib 這個庫

具體說明可參考:

  1. https://www.cnblogs.com/cnxkey/articles/8319812.html
  2. https://stackoverflow.com/questions/31053670/unresolved-external-symbol-vsnprintf-in-dxerr-lib

如果你是使用 Visual Studio Installer 安裝的 VS2019,那麼這個庫的位置是在“Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\”,這是每個專案會自動搜尋的路徑,所以不需要填寫依賴的絕對路徑,只需新增庫名字即可。

在專案右鍵屬性 - 配置屬性 - 連結器 - 輸入 - "附加依賴項" 中新增 “legacy_stdio_definitions.lib”。

可以看到附加依賴項中已經有許多被依賴的庫了,你可能會意識到這些是在 premake.lua 中配置的,新增一行即可:

	configuration( { "windows" } )
	buildoptions( { "/I \"$(DXSDK_DIR)/Include/\"" } )
    links( {
        "d3d9",
        "dinput8",
        "dxguid",
        "d3dx9",
        "DxErr",
-- 新增 legacy_stdio_definitions 依賴
        "legacy_stdio_definitions.lib"
    } )

執行 vs2019.bat,重新生成解決方案

(六)LNK2019: 無法解析的外部符號 _WinMain

原因參考:https://www.cnblogs.com/imzhstar/p/4110870.html

_WinMain 是 Windows 程式的入口函式,而教學程式碼裡的只有 main(),說明其實是個控制檯程式。

檢查專案右鍵屬性 - 配置屬性 - 連結器 - 系統 - "子系統",從 "/SUBSYSTEM:WINDOWS" 改成 "SUBSYSTEM:CONSOLE"

修改 premake.lua 的 kind 配置,從 kind( "WindowedApp" ) 改為 kind( "ConsoleApp" )

執行 vs2019.bat,重新生成解決方案

(七)其他

期間有少量函式引數數量不相符的問題,直接簡單粗暴地傳0或者去掉某個引數進行修復,總之先跑起來再說。

六、執行專案

編譯無報錯後,設定 chapter_1_introduction 為啟動專案,選單選擇除錯 - 執行。

圖片2

執行成功!

七、後記

說來慚愧,單這些構建錯誤就花了整一天才處理完畢,對目前階段的自己來說確實瑣碎難解,曾一度望著錯誤列表想放棄本書。甚至在撰寫本文的過程中一度忘記昨日是如何處理的某個錯誤。

好在最終也算執行成功,趕忙記錄,以作備忘。

後續學習中也許會嘗試做的事情:

  1. 將教學專案的 Lua5.1 替換為 Lua5.4
  2. 使用 Vscode 替代 Decoda 除錯 Lua 程式碼
  3. 替換 ogre,ogred3d9 為最新的 dx12 版本
  4. 替換 opensteer,Recast 等第三方庫為最新版本

相關文章