[Lua游戏AI开发指南] 笔记零 - 框架搭建
一、图书详情
《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年,“沙箱”本身的构建也因为运行环境的变动而出现了各种编译错误。
本节记录一些环境搭建过程中碰到的构建错误,主要是书本第一章的内容。
三、运行环境
- Windows 10
- 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,可以从解决方案资源管理器看到整体的项目结构。
生成解决方案,提示各种编译错误:

(一)编译器错误 C2220
右键属性 - 配置属性 - C/C++ - 常规 - "将警告视为错误"

但教学解决方案中包含了十几个项目文件,不可能一个一个修改,所以要修改的是前面提到的构建配置清单:premake/premake.lua
注释掉 premake.lua 中的 “FatalWarnings”,运行 vs2019.bat 重新生成解决方案,编译错误数量从 321 -> 161。
(二)编译器错误 C2440
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 这个库
具体说明可参考:
- https://www.cnblogs.com/cnxkey/articles/8319812.html
- 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 为启动项目,菜单选择调试 - 执行。

运行成功!
七、后记
说来惭愧,单这些构建错误就花了整一天才处理完毕,对目前阶段的自己来说确实琐碎难解,曾一度望着错误列表想放弃本书。甚至在撰写本文的过程中一度忘记昨日是如何处理的某个错误。
好在最终也算运行成功,赶忙记录,以作备忘。
后续学习中也许会尝试做的事情:
- 将教学项目的 Lua5.1 替换为 Lua5.4
- 使用 Vscode 替代 Decoda 调试 Lua 代码
- 替换 ogre,ogred3d9 为最新的 dx12 版本
- 替换 opensteer,Recast 等第三方库为最新版本
[Lua游戏AI开发指南] 笔记零 - 框架搭建的更多相关文章
- Django Web开发指南笔记
Django Web开发指南笔记 语句VS表达式 python代码由表达式和语句组成,由解释器负责执行. 主要区别:表达式是一个值,它的结果一定是一个python对象:如:12,1+2,int('12 ...
- SpringMVC笔记——SSM框架搭建简单实例
落叶枫桥 博客园 首页 新随笔 联系 订阅 管理 SpringMVC笔记——SSM框架搭建简单实例 简介 Spring+SpringMVC+MyBatis框架(SSM)是比较热门的中小型企业级项目开发 ...
- plain framework 1(简约框架)一款主要用于网络(游戏)开发的C/C++框架 即将开源发布
在我们的日常开发中,我们往往会遇到这种情况,当我们换了一个开发环境时很可能会重新利用一套新的框架进行开发.由于不同框架有着不同的接口,所以我们不得不花时间再次熟悉这些接口,这将造成开发时间上的重复,而 ...
- 趣说游戏AI开发:对状态机的褒扬和批判
0x00 前言 因为临近年关工作繁忙,已经有一段时间没有更新博客了.到了元旦终于有时间来写点东西,既是积累也是分享.如题目所示,本文要来聊一聊在游戏开发中经常会涉及到的话题--游戏AI.设计游戏AI的 ...
- 趣说游戏AI开发:曼哈顿街角的A*算法
0x00 前言 请叫我标题党!请叫我标题党!请叫我标题党!因为下面的文字既不发生在美国曼哈顿,也不是一个讲述美国梦的故事.相反,这可能只是一篇没有那么枯燥的关于算法的文章.A星算法,这个在游戏寻路开发 ...
- onvif开发实战2--总结框架搭建
完成框架搭建后,编写自己的主函数起onvif服务 编写makefile objs = onvif.o onvif_func.o duration.o soapC.o soapServer.o stds ...
- Libgdx 开发指南(1) 应用框架
应用框架 模块 Libgdx包含五个核心接口与操作系统交互,各自实现了如下接口: Application:运行应用,向client通知应用层事件,例如窗口大小的改变(window resizing). ...
- Nodejs开发指南-笔记
第三章 异步式I/O与事件编程3.1 npm install -g supervisor supervisor app.js 当后台修改代码后,服务器自动重启,生效修改的代码,不用手动停止/启动3.2 ...
- Node.js 开发指南笔记
第一章:node简介 介绍了node是什么:node.js是一个让javascript运行在服务器端的开发平台, node能做些什么:[书上的] 具有复杂逻辑的网站 基于社交网络的大规模Web应用 W ...
随机推荐
- JMM之Java线程间通讯——等待通知机制及其经典范式
在并发编程中,实际处理涉及两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体). 通信是指线程之间以何种机制来交换信息.在共享内存的并发模型里,线程之间共享程序的公共状 ...
- Linux 内存分析工具的命令大全介绍
在Linux系统经常被用作服务器系统.当服务器内存吃紧的时候,free命令是我们最常使用的内存分析工具. free使用介绍# free命令可以显示Linux系统中空闲的.已用的物理内存及swap内存, ...
- 当gitlab的数据库坏了,或者其他的组件坏了,修复教程。
一般企业的gitlab都承载着多个项目的源码和提交记录 如果gitlab的数据库 PostgreSQL 坏掉了,基本很难修复,那这是不是意味着源码丢失了呢. 本文章只针对 gitlab传统存储方式的修 ...
- [自动化]基于kolla-ceph的自动化部署ceph集群
kolla-ceph来源: 项目中的部分代码来自于kolla和kolla-ansible kolla-ceph的介绍: 1.镜像的构建很方便, 基于容器的方式部署,创建.删除方便 2.kolla-ce ...
- Burp suite基本配置介绍
实验目的 利用Burp Spider功能探测目标网站的目录结构. 实验原理 1)Burp Suite是Web应用程序测试的最佳工具之一,其多种功能可以帮我们执行各种任务.请求的拦截和修改,扫描web应 ...
- 实例演示:Excel实现数据更新获取,并根据公式计算后展示
我们数据库中有一些明细数据,希望我们可以使用Excel的公式,对报表数据进行,最后展示在自定义的行列固定报表中. 如下图:从左侧表中获取大类名称为饮料.海鲜.日用品,从2016/11/11到201 ...
- window 消息传递机制【复杂版本】
一.消息概述 众人周知,window系统是一个消息驱动的系统, windows操作系统本身有自己的消息队列称做系统消息队列(操作系统队列),消息循环,它捕捉键盘,鼠标的动作生成消息,并将这个消 ...
- selenium+python自动化104-如何获取隐藏元素text文本
前言 首先 selenium 是可以定位到隐藏元素的,但是 selenium 不能跟隐藏元素交互,也就是隐藏元素element不能使用element.click()方法. 隐藏元素element.te ...
- 01_c语言再学习_基础部分(1)
目录: 1.编译基础 2.c语言关键字 3.c语言数据类型 4.二进制/8进制/16进制 5.计算机内存数值存储方式:sizeof/原码/反码/补码 6.c语言中的字符和字符串 7.c语言中的数组和字 ...
- 开机弹出一下Visual Studio Just-In-Time对话框的问题
开机弹出一下Visual Studio Just-In-Time对话框 开机弹出一下Visual studio just-in-time对话框,出现一下问题,且点击确定后又弹出第二个对话框, 解决方法 ...