2.0.1 JSON的标准格式

下面给出了一个示例牌堆,这个牌堆你可以直接保存为一个名为 奶茶.json 的文件使用:

{
    "咖啡": ["美式咖啡", "可可拿铁咖啡", "拿铁咖啡", "青稞拿铁咖啡", "珍珠拿铁咖啡", "香草拿铁咖啡", "法式奶霜咖啡", "焦糖玛奇朵", "香草拿铁", "荔枝气泡水咖啡", "焦糖茶拿铁", "摩卡", "抹茶拿铁", "榛果拿铁", "香草馥芮白", "豆奶拿铁"], 
    "想不到啥分类": ["香草星冰乐", "榛果风味摩卡星冰乐", "鲜百香双响炮", "鲜百香绿茶", "金桔柠檬汁", "鲜柠檬绿茶", "柠檬椰果养乐多", "芒果养乐多", "柠檬红茶", "清香乌龙茶", "百香三重奏", "冰淇淋红茶", "红茶玛奇朵", "阿萨姆红茶", "百香绿", "翡翠柠檬", "蜂蜜绿", "葡萄柚绿", "养乐多绿", "黑糖红茶", "抹茶", "柠檬椰果养乐多", "杨枝甘露", "芝士奶盖鲜红茶", "芝士奶盖鲜绿茶", "凤梨四季春", "巧克力星冰乐", "抹茶豆奶星冰乐", "摩卡星冰乐", "浓缩咖啡星冰乐", "冰摇桃桃乌龙茶", "冰摇芒果花草茶", "冰摇柠檬茶", "冰摇红梅黑加仑", "金萱乌龙茶", "伯爵红茶", "英式红茶", "甜冰茶"], 
    "大小": ["大杯", "中杯", "小杯", "特大杯"], 
    "咖啡甜度": ["少糖", "去糖"], 
    "冰度": ["热", "去冰", "冰", "少冰", "多冰", "温"], 
    "甜度": ["全糖", "七分甜", "三分甜", "半糖", "无糖"], 
    "奶茶种类": ["红茶拿铁", "绿茶拿铁", "奶茶三兄弟", "青稞奶茶", "鲜芋茶拿铁", "大红袍珍珠茶拿铁", "芒果欧蕾", "焦糖奶茶", "鲜芋奶茶", "法式奶霜大红袍", "法式奶霜绿茶", "抹茶拿铁", "四季奶青", "咖啡冻奶茶", "鲜芋牛奶", "黑糖奶绿", "茉莉奶绿", "四季奶茶", "奶茶", "奶绿", "乌龙奶茶", "抹茶奶绿", "可可奶茶", "布丁奶茶", "红豆奶茶", "珍珠奶茶", "波霸奶茶", "布丁奶绿", "珍珠奶绿", "波霸奶绿", "红豆奶绿"], 
    "奶茶配料": ["加珍珠", "加波霸", "加椰果", "加红豆", "加布丁", "加奶霜", "无配料"], 
    "奶": ["鲜芋青稞牛奶", "青稞红豆牛奶", "青稞可可牛奶", "双拼可可牛奶", "珍珠可可牛奶", "布丁可可牛奶", "鲜芋牛奶", "经典巧克力"], 
    "甜点菜单": ["荔枝玫瑰风味蛋糕", "风车流心金沙酥", "栗香蓝莓蛋糕", "草莓甜心蛋糕", "金玉满满奶香酥", "风华正茂千层酥", "抹茶黑芝麻蛋糕", "芝士咸蛋黄蛋糕", "大大大巧克力脆酥圈", "蜂蜜提子司康", "培根可颂堡", "慢炖牛肉鲜蔬握不住大卷", "葡式咖喱鸡肉握不住", "经典凯撒鸡肉握不住", "亚洲风味鸡排锦绣面沙拉", "大蘑菇头型奇亚籽坚果麦芬", "培根鸡肉俱乐部大嘴三明治", "芝香薄切火腿片大嘴三明治", "牛排蘑菇三明治", "海盐香草风味鸡肉恰巴特", "法式薄切火腿芝士恰巴特", "坚果派对风味酸奶慕斯蛋糕", "法式秘制烤鸭腿配番茄意面沙拉轻星食", "烟熏鸡胸肉配白汁管面沙拉轻星食", "大蘑菇头形清新蓝莓麦芬", "大蘑菇头形香浓巧克力麦芬", "纽约浓郁重芝士蛋糕", "浓醇三重黑巧克力蛋糕", "提拉米苏蛋糕"], 
    "奶茶菜单": [
        "咖啡:{%咖啡}\n大小:{%大小}\n热度:{%冰度}\n甜度:{%咖啡甜度}", 
        "奶茶:{%奶茶种类}\n配料:{%奶茶配料}\n大小:{%大小}\n热度:{%冰度}\n甜度:{%甜度}", 
        "牛奶:{%奶}\n大小:{%大小}\n热度:{%冰度}\n甜度:{%甜度}", 
        "饮品:{%想不到啥分类}\n大小:{%大小}\n热度:{%冰度}"
    ], 
    "奶茶生成": [
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单}\n恭喜你成为云喝奶茶幸运用户,额外获得一份\n{%奶茶菜单}", 
        "你走进一家奶茶店,点了一份:\n{%奶茶菜单},\n以及{%甜点菜单}"
    ], 
    "奶茶":["{奶茶生成}"]
}

你可以看到这个牌堆有两个看似相同实则略有差别的格式:

{
	"大小": ["大杯", "中杯", "小杯", "特大杯"]
}
{
    "奶茶生成": [
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}\n恭喜你成为云喝奶茶幸运用户,额外获得一份\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单},\n以及{%甜点菜单}"
    ],
}

它们的区别在于,中括号 [] 的内容是否分行。前者未分行,而后者每行仅有一个。

我们建议使用后者的格式,这与它是 json 文档的标准格式无关,更多的是因为容易检查和阅读。

2.0.2 是不是放回抽取?

你可能会发现,在使用 draw 命令的时候,有的牌堆是放回抽取,有的是不放回抽取。那么如何控制是否放回?

如果你观察过很多牌堆,会发现在引用牌堆时有两种情况,以 奶茶.json 已有的词条为例,为节省空间仅仅给出部分:

{
	"奶茶生成":[
	"你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
    "你走进一家奶茶店,点了一份:\n{奶茶菜单}", 
	]
}

可以看到,有两种引用方式:{%奶茶菜单}{奶茶菜单} ,唯一的区别在于有没有 % 作为起始。在牌堆文件中,含有 % 将采取放回抽取,否则为不放回抽取。

2.0.3 权重不同怎么办?(版本限定)

2.4.0beta3(563) 之前,本节部分内容不可用。

在理论上,不放回抽取并且设定不同权重的牌堆是可以实现模拟氪金抽卡游戏的。这一点很容易实现。仍然以 奶茶.json 为例:

{
    "奶茶生成": [
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单}\n恭喜你成为云喝奶茶幸运用户,额外获得一份\n{%奶茶菜单}", 
         "你走进一家奶茶店,点了一份:\n{%奶茶菜单},\n以及{%甜点菜单}"
    ],
}

可以看到, "你走进一家奶茶店,点了一份:\n{%奶茶菜单}" 重复了很多次,在当前版本的牌堆文件中,只需多次重复内容即可设定权重。重复次数越多权重越大。


如果你使用了 2.4.0beta3(563) 及之后的版本,你可以使用更简单的方法设定不同牌数。

  1. 牌堆权重使用方法: 条目前增加 ::权重::, 即 ::牌数::牌堆内容
  2. 牌数必须为正整数,且小于999999

牌数则相当于牌堆中有牌数个此项目

示例:

{
    "抽卡": [
        "::500::1星",
        "::400::2星",
        "::80::3星",
        "::15::4星",
        "::5::5星"
    ]
}

以上牌堆则有 50% 抽到 1 星,40% 2 星,8% 3 星,1.5% 4 星,0.5% 5 星

关于牌数的一个有趣的实现,请参见仑质的有多长 - 有关牌堆概率实现的试验性牌堆

2.0.4 我想生成随机数字怎么办?

一些牌堆中可能需要生成随机数,如随机生成一个 COC 7th 规则的 NPC 的属性和其他内容。尽管直接使用 .coc7 以及其他对应条目是可取的,但是仍然不方便。

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

例如:

{
    "人偶作成": [
        "【享年】:[1d10+7]\n【暗示】:{人偶暗示}\n【宝物】:{人偶宝物}\n【职位】:{人偶职位}\n{职阶分项}\n【记忆碎片】:\n{人偶记忆碎片}\n{人偶记忆碎片}"
    ],
}

人偶享年之后的 [1d10+7] 即等同于 .r1d10+7

2.0.5 可以发送图片吗?(CoolQ Pro 版本限定)

答案是可以的,但是有前提条件,你的 CoolQ 版本必须为 Pro 版本,也就是需要前往官网进行氪金。

该功能的实现依赖于 CQ 码,具体的定义我们不做赘述,想要进行更深入了解可以前往官网查看,在此我们只介绍需要用到的知识。

在 CoolQ 中,图片的 CQ 码的格式类似于 [CQ:image,file=/Shadowscapes/Ace_of_Cups.jpg] .

  • CQ:image 表明本处加载了图片文件
  • file=/Shadowscapes/Ace_of_Cups.jpg 指出了文件位置,本处说明文件位置位于 CoolQ 根目录/data/image/Shasowscapes 文件夹,文件名为 Ace_of_Cups.jpg

由于大部分 Dice! 插件使用了 CoolQ Air 版本,因此本处不赘述图片牌堆的问题,仅仅给出一段示例:

{
    "花影塔罗": [
        "[CQ:image,file=/Shadowscapes/Ace_of_Cups.jpg]\nAce of Cups  圣杯首牌\n爱意初临、万物和谐的音律、只觉得刺痛、未来的悲伤、情怀和智慧之光、情感的律动",
        "[CQ:image,file=/Shadowscapes/Ace_of_Pentacles.jpg]\nAce of Pentacles  星币首牌\n实现财富、保障生活的机会、辛勤工作带来的繁荣、健康和富贵、走出迷幻和梦境、进入现实的世界",
        "[CQ:image,file=/Shadowscapes/Ace_of_Swords.jpg]\nAce of Swords  宝剑首牌\n绝对的正义、斩断阻碍真理的荆棘、智慧和公正、傲慢和狂躁"
        "[CQ:image,file=/Shadowscapes/Ace_of_Wands.jpg]\nAce of Wands  权杖首牌\n创造力带来的无限可能、兴奋、激动、探险、带着勇气和信心开始冒险"
    ]
}

2.1 引例

想要实现更多的功能自然需要更为复杂的牌堆文件,以 .draw 韵律源点 为例,在 Tencent QQ 中得到的返回结果如下:

AzusaFracture 9:55:46 PM
	@Hikari(Fracture) .draw 韵律源点

Hikari(Fracture) 9:55:47 PM
    这位摘星人,你随机到的曲目是
    [图片]
    Memory Forest
    Binary Enfold曲目
    曲师:ETIA.
    曲目:Memory Forest [FTR]
    难度:9
    Note数:978
    谱师:Kurorak
    Memory FarLost.jpg
    速度:2

这个牌堆的工作量相对来说并不小,为防止占用过多篇幅,这里给出牌堆内容截图:

如此巨大的工程手动录入显然是不现实的,首先 json 文件的各种标点要求就已经使犯错概率极大提高了,那么我们有什么简化方案呢?

2.2 用YAML格式编写牌堆(以 Visual Studio Code 为例)

我们介绍一种代码格式,即 YAML 格式,它的示例如下:

目标1:
  - 参数1
  - 参数2
  - 参数n

其对应的 json 牌堆的内容如下:

{
	"目标1": [
		"参数1",
		"参数2",
		"参数n"
	]
}

可以看到 YAML 格式相对于 json 格式明显更适合阅读,但是,当前版本的 Dice! 并无法直接读取 YAML 牌堆(如果你自行魔改了请无视,不过你既然能魔改源码还需要看这份文档吗)

该问题的解决方案很简单,在 Visual Studio Code 中有一个第三方的加载项 json2yaml ,利用该加载项即可快速实现 json 文件和 yaml 文件的格式转换。

下面介绍 Visual Studio Code 中 json2yaml 加载项的安装方法,如你对 Visual Studio Code十分了解,可以略去这一部分。

json2yaml 加载项的安装

在软件界面最左侧找到加载项,输入 json2yaml ,点击对应的插件右下方的 install 按钮进行安装。

安装结束后,你可以打开任意一个 json 文件。并使用键盘上的 F1 键打开操作,如没有问题,你应当看到这个工具的菜单(可能同时提供了其他的工具的菜单)。如果没有看到,尝试在此处输入 jsonyaml ,成功安装后会出现这两个菜单。

利用如上操作,你可以快速进行 jsonyaml 的文件转换,该转换方案不受文件的拓展名(即后缀)决定,仅仅取决于你是否使用了正确的代码格式。

YAML 格式说明

YAML 格式文件的后缀名为 .yml ,示例格式如下:

韵律源点:
    - |-
        这位摘星人,你随机到的曲目是
        {韵律源点改后数据}
        速度:{速度}
速度:
    - 1
    - 1
    - 2
    - 2
    - 2
韵律源点改后数据:
    - "{PST}"
    - "{PRS}"
    - "{PRS}"
    - "{PRS}"
PST:
    - |-
        [CQ:image,file=/Arcaea/auxesia.jpg]
        Auxesia
        Memory Archive曲目
        曲师:ginkiha
        曲目:Auxesia [PST]
        难度:3
        Note数:385
        封面的光酱好可爱。
    - |-
        [CQ:image,file=/Arcaea/crosssoul.jpg]
        CROSS✝︎SOUL
        Memory Archive曲目
        曲师:HyuN
        曲目:CROSS✝︎SOUL [PST]
        难度:4
        Note数:606
        魔能蛇曲

yaml 格式中,

  • 缩进被视为格式的一部分(这一点在 json 格式中不做要求),为 4 个半角空格或一个 TAB 键;
  • 多行内容前用 |- 声明多行,并直接换行后在内容前空 8 个空格或两个 TAB 键;
  • 不得在 - 后直接以 [] 开头;

以及一些不做强制的格式,如引用其他词条时单独的花括号 {} 不必须以半角双引号 "" 包裹。如你的代码格式存在问题,可以在底部看到错误提示。

简化的 YAML 处理方案

尽管 YAML 格式已经对于 JSON 格式进行了大幅度的简化,但对于编程基础稍弱的作者来说仍然容易出错。在此做出如下建议:

  1. 如软件不报错,则不需在直接单独引用其他词条而无其他内容时以 "" 包裹内容:即

       韵律源点改后数据:
           - {PST}

    而非

       韵律源点改后数据:
           - "{PST}"
  2. 在处理换行时,仍然采用 JSON 文件的 \n 进行描述:

       PST:
           - \n[CQ:image,file=/Arcaea/auxesia.jpg]\nAuxesia\nMemory Archive曲目\n曲师:ginkiha\n曲目:Auxesia [PST]\n难度:3\nNote数:385\n封面的光酱好可爱。

    但是这样处理后,使用 json2yaml 插件转换为 JSON 格式会将全部的 \n 转换为 \\n ,因此还需要使用“替换”功能将全部的 \\n 替换为原本的 \n

    在 Visual Studio Code 中,替换功能的快捷键为 Ctrl+H

通过如上操作,你可以使用更为简洁的 YAML 格式编写牌堆并转换为可用的 JSON 牌堆。

2.3 用 Excel 编写牌堆

在一些牌堆中,存在大量的相同格式,如上述名为 PST 的词条,其内容完全为如下格式:

曲绘  [CQ:image,file=/Arcaea/crosssoul.jpg]
曲名  CROSS✝︎SOUL
曲包  Memory Archive曲目
曲师  曲师:HyuN
曲目  曲目:CROSS✝︎SOUL [PST]
难度  难度:4
物量  Note数:606
描述  魔能蛇曲

在这种情况下,笔者建议使用 Excel 进行编写。

花影塔罗 的牌堆为例,原始数据经过整理变成了如下的 Excel 表格(为节省篇幅仅仅给出部分内容)

我们只需将单元格内的文字连接成我们希望在 JSON 文件中所写的内容,这一点利用 Excel 的函数十分容易实现:

Excel 连接两个单元格内容或单元格与一段文字的连接

在 Excel 中,可以使用 & 进行两个单元格内容的连接,如连接上图中 A1B1 单元格并在 D1 单元格中输出结果,只需在 D1 单元格中输入:

=A1&B1

所得结果为:

Ace of Cups圣杯首牌

但是我们想要在中英文之间添加一个破折号,尽管可以通过在一个新的单元格中输入并按照上述方法连接,但如果需要添加多次,那创建太多列也不是好的选择。而 Excel 中,连接纯文本并非难事。为了使实现上述操作,我们可以改变一下公式:

=A1&"——"&B1

可以看到我们使用了 "——" 来添加了一个破折号。在 Excel 中,连接纯文本只需要使用 &"" 进行连接。

仍然需要注意的是,这里面的双引号也为半角字符,请注意切换你的输入法状态。

连接的字符有双引号怎么办?

由于 "" 被作为了函数的一部分,直接使用 """ 会导致 Excel 无法识别,因此我们需要对其进行转义, Excel 公式中用两个引号代表一个引号,如:

="abc""abc"

会得到 abc"abc

=""""&"abc"&""""

会得到字符串"abc"

如对示例表格中的数据进行连接得到如下 JSON 牌堆:

{
    "花影塔罗(部分)": [
        "Ace of Cups  圣杯首牌\n爱意初临、万物和谐的音律、只觉得刺痛、未来的悲伤、情怀和智慧之光、情感的律动",
        "Ace of Pentacles  星币首牌\n实现财富、保障生活的机会、辛勤工作带来的繁荣、健康和富贵、走出迷幻和梦境、进入现实的世界",
        "Ace of Swords  宝剑首牌\n绝对的正义、斩断阻碍真理的荆棘、智慧和公正、傲慢和狂躁",
        "Ace of Wands  权杖首牌\n创造力带来的无限可能、兴奋、激动、探险、带着勇气和信心开始冒险"
    ]
}

以第一行为例,我们需要在 Excel 中输入如下内容以转换为 json 格式

=""""&A1&"  "&B1&"\n"&C1&""","

再使用填充柄进行填充即可得到 JSON 格式的输出。请注意,这种方法需要注意删除最后一行的 , ,否则牌堆将会报错。

结语

当你看到这里,恭喜你,你已经是一个编写 JSON 牌堆的专业人士了,尽情为你的骰娘编写属于自己的牌堆吧!

本教程或许还有一些纰漏和未尽事宜,但如果你认真看完了,你大可以推测出我们没有想到并写在这份文档里面的内容。

感谢看到这里的你,也感谢所有为这份文档提供帮助的人w

15 天 后

最近在看json牌堆,有个问题想问一下。
如果我做了很多引用用的子牌堆(比如文中奶茶.json中的大小、甜度之类的),那么我的.help draw会变得非常冗长,而且用户可以绕过主牌堆直接抽子牌堆,有没有什么办法能让dice只显示主牌堆吗?
另外,我之前在master手册里看到

牌堆名以 “_” 开头时,无法直接使用 draw 命令抽取。

但是我实际试了一下,在牌堆名前加上"_ “后(”_甜度")还是会被显示在.help draw中并可以被直接抽取,是使用方法有问题还是这个功能本身不可用了呢?

    twfx1207
    关于概率实现问题:如果想要尽可能缩减牌堆体积并且保留概率实现,请尽快使用 563 及以上版本,其中添加了单独的概率实现方法。
    关于不可见牌堆问题:请确认你的版本(当然同样建议升级)

      Hikari Sakurai 我现在的版本是2.3.8Express10(556),由于563有一些文字编码问题就一直没升级。想问下不可见牌堆的正确写法是怎样的呢

        twfx1207 这么说还是不好确定,请附上你的具体版本,如 Dice! by 溯洄 Shiki.Ver 2.3.8Express10(556)[May 16 2020 12:54:18]

          Hikari Sakurai 我找到问题了,修改牌堆以后只用.system load不会重置缓存,需要重载插件。重载完以后牌堆就会正常隐藏了。