290 likes | 445 Views
【 开心 】 下架脚本内容 规范. 邱博威. 一、 Lua 介绍. Lua 的定义 Lua 程序设计语言是一个简单 的、轻量级的、可扩展的脚本语言。 Lua 的用途 Lua 的目标是成为一个很容易嵌入 其它语言中使用的语言。很多应用程序使用 LUA 作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。这其中包括著名游戏魔兽世界,以及大话 2 ,大话 3 等。. 一、 Lua 介绍. 除了 Lua 外,还有很多类似的脚本语言,例如: Ruby, Python; 虽然其他语言在些方面与 Lua 有着共同的特色,但下面这些特征是 Lua 特有:
E N D
【开心】下架脚本内容规范 邱博威
一、Lua介绍 • Lua的定义 Lua程序设计语言是一个简单 的、轻量级的、可扩展的脚本语言。 • Lua的用途 Lua的目标是成为一个很容易嵌入 其它语言中使用的语言。很多应用程序使用LUA作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。这其中包括著名游戏魔兽世界,以及大话2,大话3等。
一、 Lua介绍 除了Lua外,还有很多类似的脚本语言,例如: Ruby, Python;虽然其他语言在些方面与Lua有着共同的特色,但下面这些特征是Lua特有: • 可扩展性:Lua被设计为易于扩展的,可以通过Lua代码或者c代码扩展,Lua的很多功能都是通过外部库来扩展的。Lua很容易与c/c++,等其他语言接口。 • 简单:Lua本身简单,小巧;内容少但功能强大,这使得Lua易于学习,很容易实现一些小的应用。 • 高效率:Lua有很高的执行效率,统计表明Lua是目前平均效率最高的脚本语言。 • 与平台无关:Lua几乎可以运行在所有听过的系统上,PlayStationII , Mac OS-9 and OS X, MS-DOS, 及所有的windows和Unix。
一、 Lua介绍 Lua的优点 • Lua在这三种语言中是运行时速度最快而且占内在最少的。 • 集成Lua只会增加极少的内存占用率。 • Lua的C API有着完备着文档和很好的例子,可以容易地通过C集成在软件里。 Lua的不足 • 尽管Lua的文档已经增进不少,但仍然有所不足。三种语言中,Lua可能是文档最少的,因为代码中极少注释,这也增加了学习的难度。另外,对Lua的本质也没有什么介绍。 • Lua内建的功能很少,并没有对创建大型的复杂应用程序提供足够支持。 • Lua应该使用更好的垃圾收集机制,Lua现在的GC仍然使用非常简单而且传统的“标记和清除”方式。
二、Action与Lua的区别 Lua • 以文件形式存放在游戏服务器端文件夹下。 • 脚本程序语言,类似C语言的编写风格,支持构造函数等。 • 根据程序服务端导出的函数,调用函数功能。 • 可灵活使用函数,变量,判断,通过函数带参解决重复性任务及代码复用。 • 灵活性高,可读性好,可以更合理的安排脚本逻辑。 Action • 以数据格式存放在游戏数据库中。 • 类似于过程化语言,逐行编写,根据ID顺延跳转。 • 根据程序服务端提供的Action Type来实现不同的功能。 • 变量寄存器使用局限,无法通过变量参数等实现代码的复用。 • 相对较简单,只需要考虑逻辑方面的流程。可读性较差。
三、Lua的使用 • 考虑到目前公司多款游戏均使用Action做为游戏脚本的支持,我们公司新使用的Lua也兼容Action ,并且是在Action的基础上导出使用的。 程序部 Lua API ProcessAction GetInt/GetStr 特殊处理函数 根据程序部提供的API改装成自己内部使用的,方便记忆的函数。 任务部 Lua脚本
三、Lua的使用 • Lua脚本的存放 Lua脚本全部存放在服务器目录底下的lua文件夹中。文件夹的分类和文件存放均可自定义。根据lua文件夹中的lua.ini索引。
三、Lua的使用 Lua.ini //公用函数段1-9999 //系统功能段10000-19999 //常规任务段20000-29999 //节日任务段30000-39999 //测试脚本段90000-99999 [MOD] 00001 = 公用函数\GetAttribute.lua 00002 = 公用函数\ProcessAction.lua 10000 = 系统功能\071015[开心][系统功能]主城任务npc对白\[开心][系统功能]主城任务npc对白.lua 20000 = 常规任务\071019[开心][常规任务]新手任务\[开心][常规任务]新手任务.lua 20001 = 常规任务\071019[开心][常规任务]师门任务\[开心][常规任务]师门任务.lua 20002 = 常规任务\071026[开心][常规任务]随机任务\[开心][常规任务]随机任务.lua 90000 = 测试脚本\test.lua
三、Lua的使用 • 调用ProcessAction函数 使用ProcessAction函数可以调用Action中所有type的使用,格式如下: ProcessAction(type,data,”param”) 如果ProcessAction函数返回值为true表示函数成功执行,如果函数返回值为false,则表示执行失败。 例子:判断玩家的等级是否到达40级,是提示yes,否提示no。 local nLevel = GetUserInt(1006,0) if nLevel < 40 then ProcessAction(128,0,”no”) else ProcessAction(128,0,”yes”) end
三、Lua的使用 • 其他函数 由于一些特殊的action,其中的param带的参数中含有action id或task id,例如102type对白的选项,1086触发战斗的成功与失败执行的ID,于是需要程序导出一些特殊使用的函数接口。 • MenuText(“对白内容”) • MenuLink(“选项 main 2 3”) • MenuPic(“10 10 104”) • MenuCreate() • MenuButton(“确定 main 2 3”) • Timer(10012,0,“60 </F>main </S>aaa </N>123”) • OpenDialog(15,1)—商店编号15,商店ID 1 • CreateBattle(“5000 win lose 1”)—5000:mapzoom id,win胜利执行的函数,lose失败执行的函数,1为处理对象
三、Lua的使用 刚才的例子:判断玩家的等级是否到达40级,是提示yes,否提示no。 local nLevel = GetPlayerLev(0) if nLevel < 40 then SysMsgBox(”no”) else SysMsgBox(”yes”) end --SysMsgBox函数的定义(保存在公用函数文件中) function SysMsgBox(sContent) ProcessAction(128,0,sContent) end
物品如何触发 (1)itemtype表里的id_action是使用物品时触发的actionid (2)并不是所有的id段都可以触发物品,在开心中只有2001000-2019999才能触发. INSERT INTO itemtype VALUES (2011884,'小米的谢礼',0,0,0,87,0,0,5001007,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0); INSERT INTO action VALUES (5001007,0,0,10001,0,'_2011884Item');
陷阱如何触发 • 当玩家踩中陷阱时,调用对应action • Insert into trap values • (13853,5001012,1,1,0,11231,269,534); • INSERT INTO action VALUES • (5001012,0,0,10001,0,‘Trap_tip'),
Npc如何触发 • 点击npc时,触发task0对应的action • 具体如下 • INSERT INTO npc VALUES • (5183,0,0,'小娴姐姐',2,14357,-1,9000,290,240,5000996,0000,0000,0000,0000,0000,0000,0000,0,0,0,0,'无',0000,00,00,0000,00,0000,0), • INSERT INTO task VALUES • (5000996,5000996,0000,'','',0,0,999,-100000,100000,0999,0000,0,-1,0); • INSERT INTO action VALUES • (5000996,0,0,10001,0,'Feast_Childermas_Sister'),
调用的actiontype • Actiontype=10001 调用时不传参数 • Actiontype=10002 调用时传1个参数 • Actiontype=10003 调用时传2个参数
四、Lua任务测试及更新 • Lua任务测试注重点 • 游戏流程测试与查看代码结合。 • 查看基本语法错误。 • 检查函数及变量命名是否合理,正确。 • 是否出现变量命冲突与函数名冲突。 例如: function main() a = 10 if a = 10 SysMsgBox(yes) end
四、Lua任务测试及更新 • Lua的更新包 • 由于Lua存放在服务器端的lua文件夹下,因此提供测试或更新的文件夹必然存在lua文件的更新。 • 需要更新的内容为:lua.ini及任务文件夹。 • 公用函数如无变动则无须更新。
五、Lua文件夹 • 常规任务:包括长期性的任务,日常任务,剧情任务,片区任务,跑环任务 • 公用任务:模板逻辑,取属性值,功能执行,常用函数 • 功能任务:功能性大任务(幻化草,抓鬼) • 节日任务:节日相关(春节任务,情人节任务等) • 系统功能:与程序相关的功能任务
五、Lua文件夹 • 服务器启动后,会顺序加载lua.ini中的文件到内存中,一旦加载到哪个文件失败,服务器将无法开启 • 加载到内存里的数据,后面的执行都是在内存中执行. • 游戏的大部分数据存在内存中,只有少部分的操作是对数据库进行操作。(task_detail,user_temp_data是直接操作数据库,玩家上下线就可以将新的数据读到游戏中,不需要重启服务器.)
取属性值.lua • 取属性值.lua • 取玩家属性(id,姓名,头像编号,职业,等级….) • 取npc属性(npcid,name,所在地图,坐标) • 取地图属性(mapid,属性) • 取物品属性(ID,物品的价格) • 取某玩家TaskDetail属性 • 取某玩家UserTempData属性 • 取幻兽属性
取属性值.lua • --取玩家当前血值 • function GetPlayerHp(nPlayerId) • return GetUserInt(1015,nPlayerId) • End • --取某物品的itemtype的ID • function GetItemtypeId(nItemId) • if nItemId == nil then • return GetItemTypeId(GetEnvItemID()) • else • return GetItemTypeId(nItemId) • end • End • --取某玩家某任务的data1 • function GetTaskData1(nTaskId,nPlayerId) • if nPlayerId == nil then • nPlayerId = 0 • end • if PlayerChkTask(nTaskId,nPlayerId) then • return GetTaskDetailInt(2506,nTaskId,nPlayerId) • else • return nil • end • end
功能执行.lua • 它是由程序实现后,封装成一个数字编号接口再提供给我们使用,类似于actiontype功能编号。 • lua是在sql的基础上进行二次加工使用; • lua最大的优势就是取消了id编号;
功能执行.lua • --系统时间检测。参数(nType:检测类型0-5种;sStartTime:开始时间;sEndTime:结束时间) • --0-详细时间 "2007-10-11 17:20" • --1-某天时间"10-11 17:20" • --2-检查月某天时间"10 15:30" • --3-检查周某天时间"0 18:30" • --4-检查日时间"15:30" • --5-检查小时时间"10"(每个小时的第几分到底几分) • function SysChkTime(nType,sStartTime,sEndTime) • return ProcessAction(123,nType,sStartTime.." "..sEndTime) • end
几个重要的函数 • --函数重命名的log记录 • function DuplicateFunctionLog(sFileName,value) • local sValueName = "未知" • for i,v in pairs(_G) do • if v == value then • sValueName = i • end • end • io.output("./lua/DuplicateFunction.log") • io.write(sFileName,":",sValueName,"已被定义过") • io.close() • error("DuplicateFunction!") • end
几个重要的函数 • --增加金钱的判断,任务给金钱 • function TaskAddMoney(nMoney) • local nNowMoney = GetPlayerMoney(0) • if nNowMoney + nMoney > 4000000000 then • PlayerAttr("money","+=",4000000000-nNowMoney) • PlayerBroadcast(2005,"您的钱包已满。") • else • PlayerAttr("money","+=",nMoney) • end • End • --游戏人物最大等级 • function GetPlayerMaxLevelLimit() • return 160 • end
几个重要的函数 • 判断玩家组队时的位置 • 检测玩家在队伍中的身份,队长、队员、任务MONSTER • 函数格式 • ChkTeamPosition(0)---函数名待定 • 返回值:判断该玩家是否在组队中,如果否则返回0;如果是,返回值为具体数值,10代表队长,20代表普通队员,30代表任务怪。 • 判断队伍的人数 • 功能描述 • 检测玩家组队的人数 • Lua函数格式 • ChkTeamPlayers(0)---函数名待定 • 函数返回值:判断该玩家是否在组队中,如果否则返回0;如果是组队状态,则判断队伍中玩家的具体个数数值。
几个重要的函数 • 队伍成员同时触发一个函数 • 玩家组队时,组队的玩家触发一个函数。 • 函数格式 • TeamAction(nType,func)—函数名待定 • nType=1——仅队长触发函数 • nType=2——仅队员触发函数 • nType=3——全队触发函数:不能出现对话,可以出现提示。 • nType=4——队伍里随机一名成员触发函数(包括队长和队员) • func——所触发的函数名,可带参数,格式类似战斗触发的格式,例如”</F>win</N>50</S>aaa” • 返回值:判断该玩家是否在组队中,否则返回false;如果是则执行func。 • 取组队的玩家ID • 制作Lua函数,取玩家所在队伍的其他玩家的ID号。 • GetTeamerId(objId) • objId为玩家的id,如果0则表示当前玩家。 • 函数的返回值为1数组值指针。 • 例如:调用时 • local tTeamerId = {} • tTeamerId = GetTeamerId(objId) • tTeamerId里的值为{110000,119992,101111}
客户端 星型结构下服务器效率和单线的比较。 • 回合制战斗方式与即时制的数据量比是1:10,单线结构适合即时战斗模式,而回合制的可以使用星型。 • 一个数据库最多可以支持3000个人的共时在线,超过就会不稳定,运行速度下降 • 使用星型结构可以打破这个限制,使同一世界交互的人更多,实现跨服PK什么的。
五、Lua相关学习资料 • 中国魔兽世界开发者维基(Programming in Lua) http://wiki.cwowaddon.com/Lua • 官方站点: http://www.lua.org • 中文站点: http://www.luachina.net • Lua 5.1中文参考手册: http://www.codingnow.com/2000/download/lua_manual.html • Lua 5.1英文参考手册: http://www.lua.org/manual/5.1/