eratw吧 关注:44,625贴子:180,606

回复:DOKU式TW口上教程

只看楼主收藏回复

而不仅如此,【{数字变量名}】也是可以被PRINTFORM系命令解读为数字的(【{】和【}】是英文的花括号,按住shift点【[】和【]】来打出)


不仅是数字变量,【算式】和【以数字为返回值的式中函数】也能被解读为作为结果的数字
而看到这里,你或许也看出来我先讲初见的一个原因了——只要记住自己写的角色某个时间一定在哪里(例如起床时间一定在家),那么只要开个新档、固定时间醒来、固定时间找角色,就能使用初见函数来测试代码啦!
【测试】对于代码来说是相当重要的,为了防止【写了一堆BUG修起来神烦】的情况出现,DOKU小子建议,最好写一个功能就测试一次(使用只有自己的口上的游戏,重新启动以加载更改后的游戏文件)
(记得经常备份!)


IP属地:湖南32楼2024-01-30 00:14
回复
    【%字符串变量%】和【{数字变量}】统称为“格式字符串”,因为解读的结果是【字符串】
    是根据解读结果命名,而非是根据被解读的东西命名

    回过头来,我们的口上差不多已经有这种程度了
    虽然其实到此为止就可以满足,但为了之后讲起来能更加顺利一些,我之后也要把这个初见口上做得更复杂一些
    但是实际上!只要有这种程度!就可以被称为【完成的初见口上】了!
    卷字数什么的交给别人吧,毕竟我是摸鱼之王【DOKU小子一直摸大佐】啊。【摸】之道,就是我的忍道!Washooooi!


    IP属地:湖南33楼2024-01-30 00:27
    收起回复
      更更更更更新!这两天再次沉迷MDRG无法自拔,因为MDRG更新了
      MDRG,真心好玩!
      题外话就到这里,上次更新说要把“初见做得更复杂一些”,但实际上,这大抵的确也是有必要的——
      当一个角色通过来访(或者行动)离开自己住的区域(例如博丽神社),口上初见却还在描写角色所住区域的环境——这不是很怪异吗?
      诚然,我们能通过代码手段来让角色“不会离开自己居住的区域”,但做起来还是要稍微多考虑一些东西的,我也曾见过不少“自己以为能成、但是出了恶性bug”的事例。对于刚入门口上制作的作者,一上来就要去了解那么多的TW本身的代码,显然不是简单事
      那么在这种代码技术有所欠缺的情况下,我们该如何防备这种羊头狗肉、驴唇马嘴的情况呢?
      答案只有一个——差分!
      既然我不能让角色只出现在某一个地方、不能控制初见的情况,那我干脆穷举所有可能性、然后每一个情况写一个口上,不就行了?
      与我,相会于,差分地狱!


      IP属地:湖南34楼2024-02-04 21:57
      收起回复
        而差分地狱用到的最基本的两组命令,一个是IF,另一个是SELECTCASE

        ↑基本的样式,IF和ENDIF成对使用、SELECTCASE和ENDSELECT成对使用
        ↑IF的“条件”是非真即假的。这个概念,在十五楼提到过。

        (实际上,这种“非真即假”的量,虽然本质上不是,但习惯上也会被叫成“布尔量”)
        不过,一般的使用里,也就IF~ENDIF能以那么基本的样式去使用。而SELECTCASE~ENDSELECT,在只以基本方式使用的时候会出错。所以事实上,这两组命令的使用方式,可能会是这样的

        上图中,无论是【ELSEIF 条件2】又或者是【ELSE】,再或者是【CASE 0】【CASE 1,2】【CASE IS >3】【CASEELSE】都是可以带着它们的内容一起、单独删掉的。
        不过想必你也看出来了,除了IF本身后面跟着的内容,其他的所有内容、都是要有对应的行作为引导的。
        或者说,【IF】【ELSEIF】,都可以算作是“以自己为开头、执行从自己之后到下一个【ELSEIF】【ELSE】【ENDIF】之前的内容”的命令
        (而【ELSE】当然只能以【ENDIF】收尾了,执行到它程序就不会找它下面的同级的【ELSEIF】或者【ELSE】了)
        同样的,将【SELECTCASE】看作是“直到遇到下一个ENDSELECT之前,可以执行下面的CASE、CASE IS、CASEELSE这些命令”的命令的话
        【CASE】【CASE IS】【CASEELSE】也可以看作“执行从自己之后到下一个【CASE】【CASE IS】【CASEELSE】【ENDSELECT】之前的内容”的命令。
        (只不过由于先执行了其中一者的话,同级的其他同类命令都不会执行。所以CASEELSE也必然是拿ENDSELECT收尾)


        IP属地:湖南35楼2024-02-04 22:57
        回复
          纯文字讲解有点难以理解?那么就来看看实例

          这里的TALENT:0:2的含义,是“编号为0的角色(玩家)编号为2的TALENT(素质)”——“性别”
          那么,这段IF~ELSE~ENDIF的作用,就是“玩家是男性就叫玩家(输出)【先生】,否则就叫(输出)【桑】”了


          (对于TALENT的作用,可以在CSV文件夹下的TALENT.CSV中查看。CSV文件夹和你的启动器在同一个文件夹里。建议:不要用例如excel的表格打开.csv文件,有时候会排版混乱)


          IP属地:湖南36楼2024-02-04 23:17
          回复
            那么到这里,命令这块, 只要有IF~ENDIF、SELECTCASE~ENDSELECT、PRINTFORM系,基础的口上代码就完全没问题了
            (实际上,以脚本小子的代码水平,最多再来一个goto、一个setcolor、一个input,大多数口上里也只能见到这些,甚至未必能见全)
            最基础的口上制作,也就只是用SELECTCASE和IF检测不同的情况、然后把文本塞给PRINTFORM来触发
            但到这里,就有一个问题了:怎么去检测不同的情况?或者说,我们能看什么东西来判断“这是不同的情况”?
            例如,我要根据地点做差分,但我该如何在代码里写地点?我要根据好感度做差分,我该如何在代码里写好感度?
            为此,我们就需要稍微了解一些TW本身(或者说era本身)提供的变量(和数组)了


            IP属地:湖南37楼2024-02-07 22:08
            回复

              首先,就是era自带的、在csv文件内标注的变量了

              每一个.csv文件,都对应着一个数组。这个数组可能是一维的,也可能是二维的。
              而主要用到的数组,分别有:
              ABL(二维):包括亲密、一些能力、感觉、中毒之类。
              它的格式,是【ABL:角色编号:能力编号】,例如“玩家的战斗能力”就是【ABL:0:42】,帕露西的清扫技能就是【ABL:60:40】

              BASE(二维):包括当前体力、当前气力、当前精力、当前工作量之类。
              它的格式和ABL一样,也是【BASE:角色编号:BASE编号】,BASE编号对应的实际BASE也是在.csv文件中查看
              需要注意的是,它存储的是【当前值】。至于【上限】,是在MAXBASE数组(二维)里存储,其格式和BASE数组一样。
              CFLAG(二维):包括好感、信赖、居住地点、当前地点之类一堆杂七杂八的变量。格式同上。
              EXP(二维):一些经验。格式同上。需要注意的是,用代码改变ABL的时候一定要连着exp一起变动(改变ABL的时候不会连着exp一起改,降低exp也不会影响abl)
              TALENT(二维):我们常说的素质(冷漠啊感度啊之类的)就属于TALENT。除此之外,还包括一些技能(如钓鱼)、性别之类的。格式同上。


              IP属地:湖南38楼2024-02-07 22:29
              收起回复
                然后,除了csv里的这些,就主要是写在DIM.ERH里的变量、以及COMMON.ERB里的式中函数了。
                这些东西,刚开始写口上是不用去了解的。DIM.ERH里的大多数变量都是口上创作的时候用不到的,而COMMON.ERB两千几百多行,想全看明白的话就要去面对复杂的调用树和抽象的底层架构——
                遇到如此的困难,当即就该祭出电竞的至高神技:不管!
                与其去记忆那些复杂到基本用不到的东西,还不如去搞点实在嘞


                IP属地:湖南39楼2024-02-07 22:53
                收起回复
                  那么现在——
                  我使用
                  口上模板的右腿!
                  口上模板的左腿!
                  烈臂!
                  天道的左臂!
                  被封印的的第三条腿!
                  召唤,被封印的口上模板!


                  IP属地:湖南40楼2024-02-08 00:40
                  回复
                    诶,虽说这个口上模板里,看起来文件一大堆,一打开一看函数又一大堆,但实际上最开始要用到的吧,它真就不多
                    文件,就两个

                    一个事件系(事件相关)

                    一个日常系COMF(日常系指令相关)
                    事件系里,首先就是这四个




                    其中第一个函数(UPDATE函数),是玩家点update以后会触发到的,适合用来介绍口上、以及进行一些初始设置
                    第二个函数(FLAGSETTING,或者简称FLAGSET),在睡醒后每次界面刷新(随便点点什么,例如指令、切换目标、过滤器之类的都算)都会触发一次,适合用来锁定一些素质、防止玩家进行修改(实际上,做很多神奇的东西都是要用FLAGSET的,但现在我们暂时不管它)
                    第三个函数(COLOR),是原版用来设置口上色的,和就寝后OPTION里那个口上色开关有关。它里面只放一行【SETCOLOR 颜色】,但如果你自己在文本输出前使用SETCOLOR,那这个函数就等同于没用
                    第四个函数(BEFORETRAIN)是4.881+才有的,是点击睁开眼睛后触发的,适合用来做一些每日设置的更新、或者早起事件
                    ——以上四个函数,现阶段,可以完全没有内容,其中只有FLAGSET是必须存在的(里面可以不装东西),剩下的,你的口上里甚至可以没有
                    再加上ENCOUNTER和口上存在函数这两个讲过的


                    这一个事件系文件里的函数,咱们就已经认识十分之一了


                    IP属地:湖南41楼2024-02-08 01:03
                    回复
                      抛开这六个,然后就是讲讲大伙可能最关心的东西了——逆告白!
                      确切地说,现在要讲的,是一组被称为【SPEVENT】的函数



                      三个函数,不用我说,长得那都一个模子。同一个开头,编号1、2、3,两个参数。
                      编号为1的,是逆初吻;为2的,是逆告白;为3的,就是其他的约会回家的情况了(包括通常情况和消除反发)
                      这三个函数被规整在一起,也就是因为它们都是【约会时主动点回家的时候触发】
                      顺带,这两个参数,实际上第二个(ARG:1)是没有任何意义的,只是TW的代码比较屎山。虽然没意义,但是在你的口上里的这个函数里,这两个参数都得有,因为调用这个函数的地方有两个参数的输入。
                      而第一个参数,才是真正把信息传递进来用的参数。
                      首先,我们来看看逆初吻

                      函数里面,先CALL SPEVENT_MESSAGE_1(ARG,ARG:1),这是地文(系统文本)

                      ↑对应的是这段
                      剩下的东西,完全不用管,只管输出文本就行了。
                      所以说这个东西,实际上可以简化为

                      ——显然,对这个函数,两个参数是没有半点意义的,就只是一个形式。
                      不过这么一来,十几行行的东西,这样一收拾,就只剩四行了。这么一拆吧,这模板,是不是就显得没那么吓人了?


                      IP属地:湖南42楼2024-02-08 01:33
                      收起回复
                        然后,逆告白

                        首先,还是一个CALL SPEVENT_MESSAGE_2(ARG,ARG:1),呼出地文
                        它的第一参数(ARG)是有意义的。ARG为0、1、2的情况,分别对应告白前、告白成功后、告白失败后的文本内容。
                        那么这个函数,就可以简化成这样:


                        IP属地:湖南43楼2024-02-08 01:40
                        回复
                          最后,通常归家(包括消除反发)

                          和逆告白一样,呼出地文、然后根据第一参数(ARG)来判断是通常归家还是消除反发(以及消除的是几级反发)
                          ARG为0,通常归家;1,反发1变反发0;2,反发2变反发1;3,反发3变反发2(就是说数字代表的是被消除的反发的等级)
                          那么就也一样了,简化!


                          IP属地:湖南44楼2024-02-08 01:46
                          收起回复
                            时隔好久,再次更下
                            最近处于口上创作的一个,啊,瓶颈期,为了丰富对话、在脑内仔细构思帕露小姐的行动日程
                            既然这样的话,回过头来做一做教程或许也不错
                            ————————————————————————————————
                            到此为止,我们的口上里已经有了:
                            UPDATE
                            ENCOUNTER(初见)
                            SPEVENT系(1、2、3)
                            在这个98kb的事件系模板里

                            我们没有的,就只有
                            COLOR(建议用手动SETCOLOR和RESETCOLOR代替)

                            FLAGSETTING(之后讲进阶功能的时候它会很重要,但现在,建议只是暂且先放到口上文件里、以防止出现“口上基础设定缺失”的警告)

                            以及EVENT系的三四十个函数了

                            这些函数,尤其是EVENT系这些东西,我暂时不打算讲——哪怕在注释里都写了“这个事件大概是什么时候触发”(例如EVENT1是“部屋遭遇”,就是说遭遇时触发),由于语言的差异,如果不去详细调查这个函数的调用,那也是容易出现“诶这个东西怎么是这么触发”的困扰。
                            ——所以说,除了参数没起什么大作用的一部分函数(例如EVENT31,我称之为“睡前叨咕函数”,ARG:1没用,ARG就只是“已经有几天没有见到面”,触发时间是睡前,触发必要条件是“已经见过面”),想要用好的话,要么反复测试,要么就查对它的调用(当然也可以看别人怎么用的,但抄的答案是错的那就寄了)——对于口上创作的初期来说,太艰苦了不是吗?
                            所以,将它暂且搁置,我们转过头来、先去讲COMF系的函数(コマンド=COMF)


                            IP属地:湖南45楼2024-03-21 23:21
                            回复
                              虽然上层只截图了一个21kb的文件,但实际上一般提到COMF系文件、指的是下面这些的统称

                              看起来很多有木有?但只要了解它的运作原理,那就基本是万变不离其宗了
                              就拿地位堪比基界的基头四汗波士、或者英语中的abandon的,大多数人写COMF系时最开始写的那个指令——300会话来分析!


                              IP属地:湖南46楼2024-03-21 23:34
                              回复