太吾绘卷吧 关注:257,567贴子:4,732,566

个人MOD制作中的经验与教训分享

只看楼主收藏回复

楼主一直想自己制作一个MOD,在事件编辑器上线之后就开始着手准备了。首先用Xmind编辑了事件逻辑和文案,之后绘制立绘和背景,最后进行编程。
我真傻,真的。我单知道官网有【事件编辑器技术文章库】,简直熟读并背诵全文了,但是依然有很多功能无法实现。却不知道【Mod事件相关接口文档】才是真正的工具书,里面有很多我用笨办法实现了的,但其实一行命令就能解决的指令。网址是:https://mod-doc.conchship.com.cn/
例如,我想在事件中获得随机功法,在官网看到代码是:
ItemKey bookKey=EventHelper.GetCombatSkillBook(EventArgBox.TaiwuCharacterId,123,1,pageIsDirect,3);
但官网又没公布每本书的DefKey,我是真的一个个试出来的,总结如下,希望可以帮到大家。
直到今晚,刚才,我才知道有个命令叫GetCombatSkillId,获取指定类型、门派、品级的功法。。这意味着之前我做的全部是无用功。。一口老血喷出来。。




IP属地:北京1楼2022-11-19 22:55回复
    你可能需要去gitee下载一个datadumper
    https://gitee.com/Neutron3529/MiChangSheng_Mod/releases/tag/太吾!
    Mod.7z里面有一个
    你可以试试


    IP属地:云南2楼2022-11-19 23:01
    收起回复
      2025-08-18 04:29:28
      广告
      不感兴趣
      开通SVIP免广告
      首先想请教一个与编程技术无关,但对我很重要的问题。
      各位大佬知不知道如何替换事件中右侧人物的立绘?我一开始以为立绘可以自由替换,兴冲冲的画了三个图,但之后发现好像不能用,只能缩小再缩小搁到背景里,我的心好痛。。
      而且我的MOD不知为何不显示封面,我把命名为Cover的png图片搁在Publish文件夹里了,但是没有效果,更改图片/压缩图片/备份图片至EventTextures文件夹等都试过了,始终无法显示出来。
      朋友说我的图展示不出来就浪费了,所以在楼里放一下,万一有大神指点我了呢!




      IP属地:北京3楼2022-11-19 23:02
      收起回复


        IP属地:广东4楼2022-11-19 23:06
        回复
          接下来说一些我自己编程中遇到的问题。
          1.事件触发概率问题-生成随机数
          我设计的触发类型是【地格移动触发】,优先级是500。但发布后有评论指出本事件如果和战斗事件同时触发,会产生冲突bug。所以之后我把整个事件组里所有事件的优先级都改成400了,盲猜应该能够解决问题。
          但是如果不想每次移动都触发,应该怎么操作呢?此处使用生成随机数功能。
          Random rd = new Random();
          int i = rd.Next(a,b);
          上述命令可以生成a到b-1的随机数,因此,如果需要生成1-100的随机数,命令应为int i = rd.Next(1,101);
          之后用if语句进行判定,就可以实现概率触发了。
          今晚我看到【Mod事件相关接口文档】后,发现有一个官方命令也可以实现上述功能:
          EventHelper.CheckProbability 方法
          可以生成百分比概率, 取值范围 [0, 100),返回值为true/false。
          我在网上看到,在高并发的情况下,Random类所取到的系统时钟种子接近甚至完全一样。在我个人的MOD中似乎也出现了这个问题。我起初设计的触发概率是10%,但当天晚上我玩的时候感觉触发概率有40%,第二天晚上我朋友来玩的时候触发概率只有5%。但我暂时也不知道怎么解决,总之现在把触发概率调成2%了,应该影响不大。


          IP属地:北京5楼2022-11-19 23:17
          收起回复
            大小写问题?还是放的位置问题?我Cover超大一样能显示


            IP属地:贵州6楼2022-11-19 23:19
            收起回复
              楼主加油


              IP属地:山东来自Android客户端7楼2022-11-19 23:26
              回复
                2.分支选择问题-if和switch
                if语句是我唯一会的语句,if……else if……else……三部曲,我本以为会万无一失。
                然而,我编出来还是疯狂报错,说什么没有返回值。这究竟是怎么回事呢?接下来小编就为大家解答这个疑问。
                原来,解决问题的关键就在于大括号{}
                前面提到,我编的时候,因为还没发现高级命令GetCombatSkillId,所以只能采用笨办法编程。而我又想做成随机生成,所以就需要两层嵌套if。
                需要注意的是,if命令本身只能管他后边一行,用;分号分隔后,后面的内容就不归这个if管了。
                所以正确的编法应该是:
                if (aaa=1)
                {
                if (bbb=1)
                xxx;
                else
                yyy;
                }
                else
                {
                if (bbb=1)
                xxx;
                else
                yyy;
                }
                switch命令我原来没见过,但它可以比较方便的实现等概率判定的情况,case1 case2 case3……
                我原以为这个很简单啊,绝不可能报错,结果又被现实无情打脸。
                使用switch的时候,应注意不能只编各种case,还要考虑哪种case都不符合的情况,也就是default。
                例如,我生成了1-5的随机数,然后编程case1: xxx; …… case 5: yyy;
                这个命令是错误的,应改为case1: xxx; …… case 4: zzz; default: yyy;


                IP属地:北京8楼2022-11-19 23:28
                回复
                  2025-08-18 04:23:28
                  广告
                  不感兴趣
                  开通SVIP免广告
                  3.变量赋值问题
                  依然以我愚蠢的双层if生成随机功法举例,我希望在抽卡后展示所获得的功法,查官网教程得到命令为:
                  var taiwu = ArgBox.GetCharacter(EventArgBox.RoleTaiwu);
                  ItemKey itemkey=EventHelper.AddItemToRole(taiwu,ItemType.Material,Config.Material.DefKey.WoodOuter7,1);
                  EventHelper.ShowGetItemPageForItems(new List<(ItemKey,int)>(){(itemkey,1)},展示后事件Guid,ArgBox);
                  那么如果使用if语句,按照我浅薄的编程认识,应该是每个if之后都要加大括号
                  if (aaa=1)
                  {
                  var taiwu = ArgBox.GetCharacter(EventArgBox.RoleTaiwu);
                  ItemKey itemkey=EventHelper.AddItemToRole(taiwu,ItemType.Material,Config.Material.DefKey.WoodOuter7,1);
                  EventHelper.ShowGetItemPageForItems(new List<(ItemKey,int)>(){(itemkey,1)},展示后事件Guid,ArgBox);
                  }
                  但这样编的话手按断了也编不完,说明其实不应该这样做,而应该把上述命令拆解为【1.变量定义】【2.变量赋值】【3.变量代入函数】三步,这样只需要在【2.变量赋值】这一步进行if/else判定就可以了。示例如下:
                  ItemKey itemkey
                  //以上是第一步,定义一个ItemKey类型的变量,变量名是itemkey
                  if (aaa=1)
                  itemkey=EventHelper.AddItemToRole(taiwu,ItemType.Material,Config.Material.DefKey.WoodOuter7,1);
                  //以上是第二步,为itemkey变量赋值。注意此时itemkey前面不再需要加ItemKey,因为第一步中已经定义过了。
                  EventHelper.ShowGetItemPageForItems(new List<(ItemKey,int)>(){(itemkey,1)},展示后事件Guid,ArgBox);
                  //以上是第三步,在所有if/else判定完成,itemkey变量赋值完毕后,写在if大括号的外面,就可以把第二步中的赋值代入这行命令了。


                  IP属地:北京9楼2022-11-19 23:57
                  回复
                    4.资源消耗问题-切记每行命令后面加分号;
                    这个问题其实不是问题,因为官方事件编辑器里已经把命令都给写好了:
                    OptionConsumeInfos = new[]
                    {
                    {Food,1000}, //消耗1000食物
                    };
                    但是我抄都能抄歪来,而且还把抄错的内容复制到了我MOD的各个角落,导致第一次点事件发布之后报了好几百行错。。
                    OptionConsumeInfos = new[]
                    {
                    {Food,1000}, //消耗1000食物
                    }
                    以上是我写的命令,我怎么看怎么对,完全没找到任何不同。
                    谁能想到,报错的真相竟然是——少抄了一个分号;
                    其实如果这里有错的话,会导致多出一个前大括号{。如果使用VSCode编程,那你命令里第一个大括号会变红,表示这部分代码有问题。
                    所以大家在编程的时候,可以多看看前后命令的颜色,比太吾绘卷游戏里的字要好辨认多了。
                    在推广使用命令前,也可以先跑跑试试,验证无误后再复制粘贴,否则之后想改都记不清哪些地方需要改了。


                    IP属地:北京10楼2022-11-20 00:10
                    回复
                      作者今晚进行了史诗级更新,然后出现史诗级红字。检查的时候没问题,但进入游戏会报错卡死。
                      此贴暂停,待修复错误后再进行复盘。


                      IP属地:北京11楼2022-11-20 00:33
                      回复
                        顶作者。只做过帝国时代2地图的云玩家尝试做事件,结果连第一步设置一个触发位置都晕了。来看各种教程经验分享了。


                        IP属地:湖北12楼2022-11-20 00:43
                        回复
                          5.Argbox问题【重要!】
                          先说结论,argbox只能在官网提到的位置调用,否则会出现空引用问题!

                          作者上次更新后,MOD出现重大问题,进入游戏时卡死爆红字。
                          经家属帮忙连夜排查,最终确定问题出在Argbox的错误使用上。
                          我希望实现卡池的分隔,操作方法是在进入事件时先生成随机数,存入argbox,之后多次调用。
                          低级卡池入场费低,抽到高品功法的可能性也低。这就要求实现资源的随机消耗,即第4条中写的命令。
                          OptionConsumeInfos = new[]
                          {
                          int arg0=-1;
                          ArgBox.Get("SaveArg0",ref arg0;
                          {Money,arg0}, //消耗arg0银钱
                          };
                          但如果这么编,就会报错:
                          【Object reference not set to an instance of an object.】
                          上述错误的原因是,在 OnCreate 函数中,ArgBox 和 EventHelper 等等都没有初始化,在这里使用argbox就会出现空引用。
                          总之,argbox只能用在onevententer、oneventexit之类合法的地方。我误以为官网罗列这几个位置只是为了举例子,却没想到是强制自愿。。


                          IP属地:北京13楼2022-11-22 23:23
                          回复
                            我一开始也经常参数盒子出问题,后来干脆用setmodint了


                            IP属地:福建来自Android客户端14楼2022-11-22 23:39
                            回复
                              2025-08-18 04:17:28
                              广告
                              不感兴趣
                              开通SVIP免广告


                              IP属地:广东15楼2022-12-14 14:25
                              回复