在游戏开发中,数值是必不可少的,数值一般由策划设计导出,然后开发再将数值应用于游戏代码中。但是策划的需求是经常会变的,这就导致数值会频道的修正,如果没次都去更新代码来导入这会给开发带来很多不必要的麻烦,所以设计一套配表系统和自动读取导入的小工具就显得很有必要。
下面这套小工具是基于公司的一套lua手游服务端开发的配表工具。配表采用csv文件来实现,csv可以用excel打开,方便策划们直观的配置游戏数据。同时csv文件是逗号分隔文件,程序方面也很容易进行解析。先贴上一段lua解析csv文件的代码(暂时没有实现读取子文件夹内文件的功能,可以自行添加)
for file in lfs.dir(csv_file_path) do
if file ~= "." and file ~= ".." then
local real_file = csv_file_path .."/".. file
--获取标题和内容
local parsed_csv_titles,parsed_csv_table = parse_csv:load_csv_file(real_file)
end
end
local M = {}
local log = require("log"):new("parse_csv")
function split(str, reps)
local resultStrsList = {};
string.gsub(str, '[^' .. reps ..']+', function(w) table.insert(resultStrsList, w) end );
return resultStrsList;
end
--一行一行取用数据
local function get_row_content(file)
local content;
local check = false
local count = 0
while true do
local t = file:read()
if not t then
if count == 0 then
check = true
end
break
end
if not content then
content = t
else
content = content..t
end
local i = 1
while true do
local index = string.find(t, "\"", i)
if not index then break end
i = index + 1
count = count + 1
end
if count % 2 == 0 then
check = true
break
end
end
if not check then
assert(1~=1)
end
--返回去掉空格的一行数据,还有方法没看明白,以后再修改
return content and (string.gsub(content, " ", ""))
end
function M:load_csv_file(filePath)
-- 读取文件
local alls = {}
local file = io.open(filePath, "r")
while true do
local line = get_row_content(file)
if not line then
break
end
table.insert(alls, line)
end
--[[ 从第3行开始保存(第一行是中文注释,第二行是标题,后面的行才是内容) 用二维数组保存:arr[ID][属性标题字符串] ]]
local titles = split(alls[2], ",")
local ID = 1
local arrs = {}
for i = 3, #alls, 1 do
-- 一行中,每一列的内容,第一位为ID
local content = split(alls[i], ",")
ID = tonumber(content[1])
--保存ID,以便遍历取用,原来遍历可以使用in pairs来执行,所以这个不需要了
--table.insert(arrs, i-1, ID)
arrs[ID] = {}
-- 以标题作为索引,保存每一列的内容,取值的时候这样取:arrs[1].Title
for j = 1, #titles, 1 do
arrs[ID][titles[j]] = content[j]
end
end
--[[
for l = 1, #titles, 1 do
log:info("title = " ..titles[l])
end
for k = 1, #arrs,1 do
log:info("key = " ..arrs[k].card_id .. " value = " ..arrs[k].card_type)
end
--]]
--返回标题和内容
return titles,arrs
end
return M
对于解析出来的数据,我们还需要导入到数据库,这里我采用的是mongodb数据库,每次更新完配表,策划只需要点击客户端工具上面的“更新数据库”按钮即可完成服务端的自动更新。客户端工具仅仅是发送一个rpc请求给服务器,让服务器完成配表的读取与导入,客户端实现很简单就不贴代码了。服务端更新数据库代码如下:
for l = 1, #parsed_csv_titles, 1 do
log:info("title = " ..parsed_csv_titles[l])
end
for i = 1, #parsed_csv_table,1 do
--循环构造出插入的子语句
local state = {}
for j = 1, #parsed_csv_titles, 1 do
local key = parsed_csv_titles[j]
local value = parsed_csv_table[i][key]
state[key] = value
-- log:info(parsed_csv_titles[j] .. "=" ..parsed_csv_table[i][parsed_csv_titles[j]] .. " ")
end
--先查询该条目是否存在,如果存在则更新,否则插入
card_index = parsed_csv_table[i].card_index
mdb:update(db, collection, {card_index = card_index},state)
end
实现效果:
客户端exe工具:
https://pan.baidu.com/s/1dFrEDl3

游戏开发中,数值策划与开发间的配合通过一套配表系统和自动读取导入工具得以优化。该系统使用CSV文件,便于策划用Excel配置,并通过lua代码解析。解析后的数据将自动导入mongodb数据库,只需策划点击工具的“更新数据库”按钮,服务器就会通过RPC请求完成配表更新。
8110

被折叠的 条评论
为什么被折叠?



