動態(tài)網(wǎng)站做優(yōu)化搭建網(wǎng)站需要什么技術(shù)
玩過《哈迪斯》(英文名:Hades)嗎?最近在研究怎么給這款游戲做MOD,想把它的振動體驗(yàn)升級到更高品質(zhì)的RichTap。N站下載了一些別人做的MOD,發(fā)現(xiàn)很多都基于相同的格式,均是對游戲.sjon文件或.lua文件的修改。我們也可以在游戲的安裝目錄 {installation_path}\Content下看到,Game子目錄里有很多.sjon文件,Scripts子目錄里有很多.lua文件。很顯然,這款游戲支持Lua腳本。如果我要給游戲擴(kuò)展功能,勢必也要寫Lua腳本代碼。Lua有很多歷史版本,需要考慮新寫代碼的兼容性。那么,《哈迪斯》自帶的Lua解釋器到底是哪個版本呢?這便是本文標(biāo)題的由來。
于是,我到Lua.org官網(wǎng)查看了它的版本歷史,發(fā)現(xiàn)Lua 最近幾個版本的發(fā)布時間分別是:
- Lua 5.4:2020年6月。最新版5.4.6發(fā)布于2023年5月。
- Lua 5.3:2015年1月。
- Lua 5.2:2011年12月。
- Lua 5.1:2006年2月。
- Lua 5.0:2003年4月。
而《哈迪斯》最早是在2018年12月發(fā)布的。猜測它用的Lua不是5.3就是5.2吧。我需要再去驗(yàn)證一下。
我在N站下載了一個叫“Multiplier Config”的MOD,它能在戰(zhàn)斗場景下動態(tài)調(diào)整給主角或敵人帶來的傷害數(shù)值。按照網(wǎng)站上的指示安裝好MOD。然后,我需要修改其中的MultiplierConfig.lua。我本想加一行print(_VERSION)來打印Lua的版本號。問題是,我到哪里能看到這個打印信息呢?
我有個想法。因?yàn)镽ichTap Windows SDK是以DLL的形式提供的,我在Lua代碼里識別游戲場景后是需要調(diào)用這個DLL來觸發(fā)高品質(zhì)振動的。我何不在這個DLL里實(shí)現(xiàn)一個ShowMsg函數(shù),讓它把收到的內(nèi)容以Windows MessageBox的方式彈出來呢。經(jīng)過一番研究,發(fā)現(xiàn)能被Lua代碼調(diào)用的DLL是需要特殊定制的,那我就重新開發(fā)一個最簡單的“轉(zhuǎn)發(fā)器”DLL吧,這篇文章介紹了關(guān)鍵點(diǎn),美中不足的是作者沒有提供拿來即用的源代碼工程。于是我在GitHub找了一個,是一個叫swerg的俄羅斯哥們開發(fā)的。swerg維護(hù)了QUIK工具包,他的simple-lua-c-dll工程也依賴那個工具環(huán)境,具體來說是他自己編譯的Lua解釋器qlua.dll。通過Dependency Walker也能確認(rèn)這一點(diǎn):
我想盡可能減少依賴!看來我還不得不自己編譯Lua源代碼呀!感謝faybull的這篇文章:“Windows下lua的編譯與環(huán)境搭建”,寫得很清晰,看完一遍就懂了!不過我下載的是Lua 5.2.4的源代碼,代碼工程上傳到GitHub了,我編譯出了自己的lua.exe、lua52.dll和lua52.lib!然后我從swerg的simple-lua-c-dll fork了一個版本出來,再把我編出來的庫文件以及相應(yīng)的頭文件用到我fork出來的simple-lua-c-dll工程,稍作修改后便順利編譯通過了。寫了最簡單的測試腳本test1.lua:
print(_VERSION)
print("Hello World")
然后在控制臺運(yùn)行:lua.exe {path}\test1.lua,順利通過!
接下來,我就要給simple-lua-c-dll實(shí)現(xiàn)ShowMsg函數(shù)了:
static int forLua_ShowMsg(lua_State* L) {const int n = lua_gettop(L);if (n > 0) {int type = lua_type(L, 1); // 只處理第一個輸入?yún)?shù)if (type == LUA_TNUMBER) {char strMsg[100] = { 0 };sprintf(strMsg, "The number is %.2f", lua_tonumber(L, 1));MessageBox(NULL, strMsg, _T("QM"), MB_OK);}else if (type == LUA_TSTRING) {const char* pStr = lua_tostring(L, 1);if (pStr) {MessageBox(NULL, pStr, _T("QM"), MB_OK);}}}return(1);
}
將編譯出來的luacdll.dll拷貝到游戲安裝目錄的{installation_path}\x86下,也即把它跟主程序Hades.exe放在一起。修改MOD的MultiplierConfig.lua腳本如下:
ModUtil.WrapBaseFunction("Damage",function(baseFunc, victim, triggerArgs)local multiplier = MultiplierConfig.Config.Multiplier-- My codes beginluacdll = require("luacdll")if luacdll ~= nil thenluacdll.ShowMsg(_VERSION)end-- My codes endif victim ~= nil thenif victim == CurrentRun.Hero thentriggerArgs.DamageAmount = triggerArgs.DamageAmount * multiplier.DamageTakenelsetriggerArgs.DamageAmount = triggerArgs.DamageAmount * multiplier.Damageendendreturn baseFunc(victim, triggerArgs)end
)
見證奇跡的時刻到了!運(yùn)行游戲。在進(jìn)入戰(zhàn)斗場景后,很快就會看到彈出這樣的消息框:
完美!!!然后……然后……我在游戲主程序所在的目錄下看到了lua52.dll😂 好吧,這不重要了。我在整個過程中學(xué)到了很多。而且,我所做的工作在未來是可復(fù)用的?