LuaDB

LuaDB

LuaDB - KCD2 Lua持久化模块 本模块为KCD2模组开发者提供基于SQLite的Lua数据持久化功能

实用程序

注意: 这是一个面向模组作者的资源/工具。普通模组用户仅在其他模组要求时才下载。单独安装此模组不会产生任何效果。

安装要求

  1. 需要 Ultimate ASI Loader(已包含在下载文件中)。
  2. 将此模组的 .asi 文件和 ASI 加载器(即 .dll 文件)放入游戏根目录(即包含 KingdomCome.exe 的文件夹,位于 KingdomComeDeliverance2\Bin\Win64MasterMasterSteamPGO)。

Linux 用户: Proton/Wine:在你的 Steam 启动选项中添加:

WINEDLLOVERRIDES="dinput8=n,b" %command% (感谢 extract95 的测试!更多详情请参阅 Proton/Wine 设置指南。)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

LuaDB - KCD2 Lua 持久化模块

这是什么?

这是 LuaDB,一个为 KCD2 模组作者设计的 Lua 持久化模块。它将 Lua 数据(包括表、布尔值、数字和字符串)存储在 SQLite 数据库中,并提供两种保存模式:

  1. 全局 – 数据在所有游戏存档中持久化(独立于游戏存档)。
  2. 本地 – 绑定到游戏存档,数据与特定游戏存档文件关联:
    • 保存游戏时自动保存
    • 加载该存档时自动加载

为什么?

在此模组之前,KCD2 中没有简单且安全的方法来持久化存储 Lua 数据。模组作者不得不依赖变通方法(如实体属性),但这些方法不可靠或有限。此模组通过提供以下功能解决了这个问题:

  • 永久存储(即使在游戏重启后)
  • 易于使用的 Lua API(包括简单的 Set/Get 和新的面向对象 DB.Create 接口)
  • 安全性 存储是外部的(保存在 kcd2db.db 文件中),最大限度地降低了数据损坏的风险。在最坏的情况下,模组可能在更新后无法使用,这可以通过移除它以及任何依赖它的模组来解决。
  • 两种存储模式(全局或存档特定)
  • Lua 对象支持(任何可由 json.lua 编码的 Lua 对象)

面向谁?

  • 模组作者:对于需要持久化数据的模组至关重要。
  • 普通玩家:仅在某个模组需要时使用(单独使用无效)。

有什么用?

  1. 存储 Lua 数据
    • 使用 DB.Create("ModName") 为你的模组创建一个数据库对象。
    • 使用数据库对象的 Set 方法存储数据。数据会自动转换为 JSON 进行存储,并在检索时转换回 Lua 对象。
    • 示例:local myDB = DB.Create("MyAwesomeMod"); myDB.Set("player_health", 85.6)
  2. 检索数据
    • 使用数据库对象的 Get 方法检索数据。
    • 示例:local health = myDB.Get("player_health")
  3. 调试工具
    • LuaDB.Dump() – 将所有存储的数据打印到控制台
    • 日志文件(kcd2db.log)和 SQLite 数据库文件(kcd2db.db
  4. 用例
    • 保存模组设置(例如,按键绑定,配置)
    • 存储玩家进度(例如,自定义任务状态)
    • 持久化库存/装备数据(例如,已保存的套装)
    • 存储复杂数据结构,如表和数组。
  5. 示例代码
YourMod = YourMod or (function()
-- 让 LuaDB 成为模组的增强功能,允许用户选择 LuaDB 来实现持久化。
local db = LuaDB and DB and select(2, pcall(DB.Create,"YourMod"))
return {
version = "__VERSION__",
localData = db and db.L or {},
globalData = db and db.G or {}
}
end)()

function YourMod:Init()
local settingA = YourMod.localData.settingA
local settingB = YourMod.globalData.settingB
-- 对设置进行操作
end

function YourMod:Save()
YourMod.localData.settingA = "valueA"
YourMod.globalData.settingB = { a = 1, b = 2 }
-- 保存设置
end

function YourMod:DoSomething()
local settingA = YourMod.localData.settingA
local settingB = YourMod.globalData.settingB
-- 对设置进行操作

-- 如果有变化则更新设置
YourMod.localData.settingA = settingA
YourMod.globalData.settingB = settingB
end

YourMod:Init()

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

介绍

此模块为《天国:拯救 II》模组开发者提供基于 SQLite 的 Lua 数据持久化支持,支持两种存储模式:

  • 全局存储:数据跨游戏存档持久化(API 以 "G" 结尾),支持自动保存/加载
  • 存档关联存储:数据绑定到游戏存档槽,支持自动保存/加载同步

源代码位于 Github-kcd2db

API 文档

DB API 文档

-- 创建一个数据库实例(推荐用于大多数情况)
local myDB = DB.Create("MyModNamespace")  -- 使用你的模组名称或唯一标识符

-- 存储 Lua 对象(包括嵌套表)
myDB.Set("player_health", 85.6)
myDB:Set("has_dragon_sword", true)  -- myDB 同时支持 .call 和 :call 语法

-- 复杂对象示例
local config = {
difficulty = "hard",
weapons = {
sword = true,
bow = false
},
greeting = "hello world"
}
myDB.Set("player_config", config)

-- 检索数据(自动转换回 Lua 对象)
local health = myDB.Get("player_health")
local config = myDB.Get("player_config")

-- 全局 API(跨存档)
myDB.SetG("settings", {volume = 0.8, fullscreen = true})
local settings = myDB.GetG("settings") -- 返回表 {volume = 0.8, fullscreen = true}

方法

  • DB.Create("Your MOD") - 创建一个具有相同 API 的命名空间实例,自动为所有键添加前缀以减少键冲突的可能性。应始终优先使用此方法。

  • DB.Get(key) - 获取本地键值

  • DB.Set(key, value) - 设置本地键值

  • DB.Del(key) - 删除本地键值

  • DB.Exi(key) - 检查本地键是否存在

  • DB.All() - 获取所有本地键值

  • DB.GetG(key) - 获取全局键值

  • DB.SetG(key, value) - 设置全局键值

  • DB.DelG(key) - 删除全局键值

  • DB.ExiG(key) - 检查全局键是否存在

  • DB.AllG() - 获取所有全局键值

  • DB.Dump() - 打印所有数据

所有方法都同时支持 .call:call 语法,可根据个人偏好选择。

快捷访问

  • DB("Your MOD") - 等同于 DB.Create("Your MOD")
  • DB.key / DB["key"] - 访问本地键值(如果与现有方法同名,会导致冲突,返回函数而非数据)
  • DB.L.key / DB.L["key"] - 访问本地键值,无冲突
  • DB.G.key / DB.G["key"] - 访问全局键值,无冲突

注意

  1. 命名空间名称不能包含冒号,"namespace:" 将在数据库中用作键前缀,以隔离不同模组的数据。
  2. 当键名与现有方法相同时,直接访问将调用方法而非键值,请改用 .L.G
  3. 所有值将自动进行 JSON 编码/解码(游戏内置了 json.lua V0.1.1)。
  4. 单个对象的 JSON 字符串大小不应超过 10 亿字节(约 953MB),否则 Sqlite 会报错 "string or blob too big",导致无法存储。
  5. 使用 Dump() 时,字符串中的 $0~9 将被控制台解析为颜色代码。游戏内控制台无法显示非 ASCII 字符,DEBUG 日志数据将被截断以防止卡顿。

原始 API

-- 存储数据(自动绑定到当前存档)
LuaDB.Set(key, value)

-- 检索数据
local value = LuaDB.Get(key)

-- 删除数据
LuaDB.Del(key)

-- 检查键是否存在
local exists = LuaDB.Exi(key)

-- 存储全局数据
LuaDB.SetG(key, value)

-- 检索全局数据
local value = LuaDB.GetG(key)

-- 删除全局数据
LuaDB.DelG(key)

-- 检查全局键是否存在
local exists = LuaDB.ExiG(key)

调试命令

-- 在控制台查看所有存储的数据
LuaDB.Dump()

支持的数据类型

  • :在 LuaDB API 中必须是字符串。如果使用 DB API,任何可由 json.lua 编码的 Lua 对象均可接受。
  • :在 LuaDB API 中,值必须是布尔值、数字或字符串。如果使用 DB API,值可以是任何可由 json.lua 编码的 Lua 对象(布尔值、数字、字符串、表)。

使用示例

-- 使用新的 OOP 接口(推荐)
local modDB = DB.Create("MyAwesomeMod")
modDB.Set("player_stats", {
health = 100,
stamina = 85.5,
inventory = {"sword", "shield", "potion"}
})

-- 原始 API 示例
LuaDB.Set("player_health", 85.6)
LuaDB.SetG("global_kill_count", 42)

-- 在控制台查看数据
LuaDB.Dump()

调试

  • 使用游戏根目录下名为 kcd2db.db 的 SQLite3 数据库
  • 操作日志存储在游戏根目录下的 kcd2db.log
  • 启动诊断现在包括模块检测和数据库路径信息
  • 如果使用 -console 启动,默认情况下 INFO/WARN/ERROR 日志也会显示在控制台中
  • DEBUG 日志保留在 kcd2db.log 中,以避免控制台被刷屏
  • 可以通过以下方式更改控制台日志级别:
    -kcd2dbConsoleLog=debug|info|warn|error|off
    

如果模组无法加载或启动时崩溃,请在报告问题时附上 kcd2db.log

重要说明

此模组大量使用了逆向工程获得的游戏内部结构,可能会受到游戏更新的影响。如果在游戏更新后遇到崩溃,请尝试移除模组文件(或将 .asi 扩展名重命名以禁用)。