跳转至

Json牌堆编写:从入门到入土

作者:雨岚之忆

一、写在前面

1.前言

本文档基星骰系列骰娘编写。星骰虽然使用的为json5,不过仍然兼容json的语法,因此此篇文章以json为主要内容进行讲解

2.编写建议

尽管只使用记事本既可对牌堆进行编辑。但是,大概没有人会对大面积文字能够快速理清思路,并进行持续编写/开发/二改。

因此本人建议,对于windows建议用Notepad++或visual studio code等编写软件;对于手机端,则可用MT管理器进行编写。

3.关于询问

针对任何bug或者不懂的地方,询问不失为一种不错的角度。但是,在提问时,请「务必」附上原代码图与错误图。

如何优雅且高效的进行提问可以查看上学看了都说好的提问的艺术

二、Json牌堆入门

1.牌堆组成

下面展示的为一个简单的牌堆

{
        "点心":["橙子","荔枝","巧克力","樱桃","青苹果","山楂","牛奶","葡萄酒","啤酒","白巧克力","圣代","奶茶","红茶","马卡龙","布丁","咖啡", "可乐","罗宋汤","调制酒"],
        "食物":["汉堡","面条","肉泥","牛排","猪排","羊排","奶酪","披萨","面包","香肠","方便面","热狗","火腿","三明治","蛋挞","空心粉","沙拉","烤鱼","土豆饼"],
        "今天吃什么": ["\n您 今天的伙食如下一\n早餐: [{%食物}]和[{%点心}] \n午餐: [{%食物}],[{%食物}]搭配[{%点心}] \n晚餐: [{%食物}] 搭配[{%点心}] "]
}
可以看到,牌堆的组成并不复杂,主体由牌堆和牌堆内对应的牌组成,可抽象为:
{
        "牌堆名a":[
                "牌a1",
                "牌a2",
                ...
                "牌an"
        ],
        "牌堆名b":[
                "牌b1",
                "牌b2",
                ...
                "牌bn"
        ]
}
总的来说,一个完整的json牌堆文件首先是由大括号({})圈起来的,之后可以利用上图所示进行编写。

须注意,在每个牌堆和每个牌之间,需要加入逗号(,)进行分隔(是后一个牌堆或牌后不必加逗号)

下面我们对牌堆进行分块讲解

2.牌堆名

用于触发或引出位于其中的内容,若在名字前面加入下划线(_)可阻止该牌堆进入drawhelp内(一般对非主词条进行该操作,可使得drawhelp简洁)

3.牌

即调用牌堆后随机抽取的内容。用引号("")括起来。内容中可以输入相应自符串。

(1)牌中插入牌堆

  • 利用{牌堆名}进行插入,当程序运行到此时,会寻找大括号({})内对应的牌堆继续抽取,例如:
    {
    "今天吃什么":["您今天的伙食如下[{_食物}]和[{_点心}]"],
    "_食物":["汉堡","面条","肉泥"],
    "_点心": ["橙子","荔枝","巧克力"]
    }
    
    输入->.draw 今天吃什么
    返回->您今天的伙食如下[汉堡][巧克力]
    
  • {%牌堆名}使得当次抽取后的牌不再放回该牌堆。

 {
"今天吃什么":["您今天的伙食如下[{%_食物}]和[{%_食物}]"],
"_食物":["汉堡","面条"]
}
输入->.draw 今天吃什么
返回->您今天的伙食如下[汉堡][面条]
{
"今天吃什么":["您今天的伙食如下[{_食物}]和[{_食物}]"],
"_食物":["汉堡","面条"]
}
输入->.draw 今天吃什么
返回->您今天的伙食如下[面条][面条]
需要注意,%不放回抽取只适用于单指令内的多抽取(类似图上)

".draw 今天吃什么 5"这样并不能算作单次抽取

(2)特殊字符

①牌堆内可以正常使用转义字符,常用的比如"\n"
{
        "今天吃什么":["您今天的伙食如下\n[{_食物}]和[{_点心}]"],
        "_食物":["汉堡","面条","肉泥"],
        "_点心": ["橙子","荔枝","巧克力"]
}

输入->.draw 今天吃什么

返回->
您今天的伙食如下
[汉堡][巧克力]
②针对于星骰 {user}等特殊字符也可以写入牌堆触发
{
        "今天吃什么":["{user}今天的伙食如下[{%_食物}]和[{%_食物}]"],
        "_食物":["汉堡","面条"]
}

用户(雨岚之忆)输入->.draw 今天吃什么
返回->雨岚之忆今天的伙食如下[汉堡][面条]
特殊代码 可被自动替换为
{player} 当前人物卡名称
{nick} 骰娘名称
{user} 触发者的qq昵称
{id} 触发者的qq号
{group} 触发者的群号

三、Json牌堆进阶

1.在牌堆中实现随机数

在牌堆文件中,像 .r 指令一样生成一个随机数是很方便的。你只需要在需要生成的位置添加一个 [] ,在其中类似输入 .r 的参数一样输入即可。 * 例如:

{
    "人偶作成": [
        "【享年】:[1d10+7]\n【暗示】:{人偶暗示}\n【宝物】:{人偶宝物}\n【职位】:{人偶职位}\n{职阶分项}\n【记忆碎片】:\n{人偶记忆碎片}\n{人偶记忆碎片}"
    ]
}
此段代码中的[1d10+7]即等效于发送指令.rd10+7

2.内容权重

诚然我们可以通过多次加入相同的牌进入牌堆以实现不同权重。

{
"牌堆":[
"牌1",
"牌1",
"牌2",
"牌2",
"牌2"
]
}
但是这样无疑会增加维护以及修改的难度

因此星在牌堆中提供了一种便捷的权重表示方法,在开头利用"::数字::"给予内容不同的权重

  • 例如:
    "牌堆":[
    "::2::牌1",
    "::3::牌2"
    ]
    
    同理,我们也可以用随机数来替代权重
  • 例如:
    "牌堆":[
    "::[1d3]::牌1",
    "::[1d6]::牌2"
    ]
    

3.图片与音频的插入

  • 在此部分,会介绍两种实现方式,一种为普用的CQ码,另外一种为星特有的特殊函数。
①CQ码
发送一张图片:[CQ:image,file=文件名]

文件储存在AstralDice/AstralData_骰娘qq号/pictures

发送语音文件:[CQ:record,file=文件名]

文件储存在AstralDice/AstralData_骰娘qq号/voices
②特殊函数

对于星来说,存在一种更加简单的添加图片与音频的方式

也就是下面展示的特殊函数

#{PUCTURE-文件名}
#{VOICE-文件名}
也可以实现对图片和声音的调用

声音的插入会单独显示为一条语音,无法与消息合并(尽管在牌堆里将音频与其他消息写在一起也是如此)

4.递归

因为牌堆中支持引用牌堆,因此可以用此方式进行递归等操作

{
        "递归0":["牌a1","牌a2","{递归1}"],
        "递归1":["牌b1","牌b2","{递归2}"],
        "递归2":["牌c1","牌c2","{递归0}"],
}