为什么 lua 在游戏开发中应用普遍？
因为 QuickJS 这样的东西没有早出来几年，否则根本没有 Lua 什么事情，归根揭底，Lua 并不是一门好语言： 明明是 90 年代才发明的语言，浑身透着一股 60-70 年代的味道。 那么使用 QuickJS 代替 lua 的有哪些好处呢？ 事实上周边一些中型引擎最近两年都完成了 QuickJS 的集成，用它逐步替代 Lua，架不住 js 的人好招聘，技术生态好，架不住 js 还可以有 ts 的加持。 所以说，QuickJS 要是早出来几年，根本没 Lua 什么事情了，老项目选 Lua 是没办法，新项目可以多看看，多比较下，没必要看着继续在 Lua 上面继续浪费时间。  -- 没有对比就没有伤害，TypeScript 写个最简单的程序，定义个类： 多清爽，简单直白，程序不就应该这样写吗？使用也是直接： Lua 里所谓 less is more，就是不给你提供个 class，告诉你可以用 table + setmetatable 模拟： 你摸着良心说说你想写哪种代码？Lua 这种类定义，一眼看过去真的是一团乱麻，这还不算最恶心的，等你开始写继承的时候才恶心，还有那个 : 符号和主流语言格格不入。 这种程序写大了是很容易一团乱麻的，容易写飞，你忘记写一行 Person.__index = Person 你可能怎么死的都不知道，很多新技术最初的目标都在于简化现有技术，但是最终却以增加了更多额外的复杂性收场，其他语言直接定义个 class 这么简单基础的事情，在 lua 里都那么恶心。 有的项目为了简化这件事情，实现了叫做 class 的函数，让你可以这么定义一个类： 好看么？不好看，但它帮你处理好了 setmetatable，继承等等琐事，避免遗漏，可这个项目实现的 class 和别的项目实现的 class 又不兼容，互相不能继承不说，就连实例化都可以有 n 种方法： 项目 1 和项目 2 的实例化函数（构造）名字用的不一样，项目3 自己实现了 class，直接调用类名，第一个项目实现的类，按第二个项目的方法无法调用。 没有标准就无法协同，就连外面的 Editor/IDE 都很难得知你定义了个什么类，或者类里有些什么成员，因此无法在开发时给予你更多的帮助和支持。 写多了你会问自己，为什么要在 class 定义兼容性这种莫名其妙的事情上浪费这么多时间呢？为什么不能像 ts/js 一样所有项目统一用 new 实例化，用 class 关键字声明呢？ 这时候 Lua 会告诉你：“这叫做 Less is more 原则，你不懂”，是不是听了很想砸键盘？ 正是由于 Lua 的残缺，导致了语言碎片化，每个项目都要在一些很根本的东西上自己搞一套，导致项目之间代码很难复用，导致知识无法积累，大部分 lua 代码很难脱离所在项目，独立存在，知识积累不起来的后果就是 Lua 虽比 TypeScript 早 21 年，开源项目却不到 TypeScript 的 1/10 。 翻过去看看前面的 TypeScript 对比下，谁美谁丑？谁好谁坏？程序写大了谁的更容易维护？一目了然的事情；TypeScript 还能在编译期就帮你在 Editor 里把错误标出来： vscode 里都不需要编译，边写边实时标注错误，用 Lua 的话，非要运行到那里，你才能得知出错了。这就是 Lua 的 "Less is more" ，不告诉你错哪里了，让你自己运行时自己踩地雷去，最终你花费了更多（more）的时间为它的残缺（less）买单。 所以说 Lua 不适合写大程序，程序大了 Lua 代码容易写散，容易失去维护性。 Lua 有个很迷惑人的话术，叫做：“Lua 的定位从来就是小而精，不是 Python/Java”，你要真的只用 Lua 写一些一两百行的小代码，配置之类的，我也无话可说，但游戏开发里动辄用 Lua 写几万行的新模块，不得不面对复杂性和可维护性时，就不要再用 “小而精的定位” 当成它语法残缺的挡箭牌了。  -- 再给你们欣赏下，如果 Lua 想不依赖任何库，怎么检测一个文件是否存在： 为了保证代码的 portable，不依赖 C 模块，只使用 Lua 标准 api 写出来就是这样，全是 work-around，再来欣赏下如何求一个文件的绝对路径： 先尝试用 realpath ，不行再尝试用 perl 和 python 来求绝对路径 ，最后不行再自己根据当前目录重新计算。同时如果有 cffi 的话，会先尝试用 cffi 导出 msvcrt 的 GetFullPathName 来提供加速，都不行的话自己根据当前路径 join 计算。 爽吧？ 不建议把时间浪费在 Lua 上，你在 Lua 上积累的三年经验，将来如果不做游戏就全废了，但如果你把经验积累在 js/ts 上，不做游戏你还可以做非常多的领域。 --  -- 答疑： 1）Lua 没有 global 只有 env，说 global 不准确。 我用 global 只是个代称，具体指代 _G 还是 _ENV 看你用不用 luajit 或者 5.1，就是 “非 local ” 的意思，不用纠结，默认污染的是 global 可以理解成 “默认污染 _G 或者 _ENV”就行了。 2）Lua 的数组可以从 0 开始计数的。 看这里：韦易笑：别被忽悠了 Lua 数组真的也可以从 0 开始索引？ 3）Lua 的优势是虚拟机非常小。 QuickJS 也非常小，代码就几个文件，运行内存只要 200KB，就能跑个简单小程序。 4）JS 也没好到哪里去，对比 Lua 的话。 ES6 标准以前，JS 也许和 Lua 差不多，但 ES6 以后，JS 完善了不少，Lua 已经没法比了；再说，JS 再不好也可以用 ts 加持，QuickJS 支持到 ES2020，轻松跑 ts。 5）Less is more 前面已经说过很多了，Less 可以但不要残缺。  -- 目前已知使用 QuickJS 的项目有： 知乎里也能找到很多人再用：  -- 想在自己游戏里引入 JavaScript/TypeScript 和 QuickJS 的，不用从头弄，腾讯开源项目 PureTS 已经帮你们做好了，同时为 unity 和 unreal 增加 TypeScript/JavaScript 支持，并且底层可以随意切换 QuickJS 或者 v8： GitHub - Tencent/puerts: 普洱TS！Write your game with TypeScript in UE or Unity. PuerTS can be pronounced as pu-erh TS 根本无需自己从头搞，可直接用 PureTS 或者参考它自己实现。看这势头，或许不出几年 JS/TS 将逐渐成为游戏项目的标配。  -- 扩展阅读：   --  。