编写牌堆
编写牌堆
概览
海豹核心目前支持 toml
(新) json
yaml
格式的牌堆。
如果对其中某种格式的语法有了解,建议选择熟悉的格式。如果都不了解,建议选择使用适用性最广的 json
格式。
当然,如果你的海豹版本较新,我们也非常推荐你尝试 toml
格式的牌堆编写。toml
格式诞生较晚,语法支持更多现代特性,海豹为这种格式的牌堆支持了更多功能。
牌堆文件的编码
永远使用「UTF-8 编码」来编写牌堆。
语法快速入门
我们将简单介绍 toml
json
yaml
的语法,仅说明牌堆编写中会用到的部分,帮助你快速了解它们。
务必注意使用半角符号!
下面的语法中涉及到的符号都是半角符号,如果你出现了奇怪的问题,记得检查是否在输入法的中文输入状态,导致输入了错误的符号。
比如应该为 ,
却使用了 ,
,应该为 ""
却使用了 “”
。
使用专业的编辑器能帮助你检查这些问题。
TOML 注释
注释以 #
开头,用来记录相关说明性内容。
# 这是注释
key = "value" # 注释也可以放在行尾
TOML 键值对
「键值对」是 TOML 文档最基本的元素。
key = "value"
键名在等号的左边而值在右边,键、等号和值必须在同一行(有些值可以跨多行),不允许没有值。
值需要是下述类型之一:
- 字符串:以
""
''
或""" """
包裹起来的一串文字 - 整数、浮点数(即小数)
- 布尔值:
true
和false
- 日期或时刻:采用 RFC 3339 格式,如
1919-08-10
1919-08-10 11:45:14
- 数组:
[]
包裹的一系列值 - 内联表:表的一种紧凑表示法,
{}
包裹的一系列键值对
键值对后必须换行(或结束文件)。
TOML 键名
键名可以是裸键名,也可以是用 ""
引起来的字符串,都将被看作是字符串(哪怕裸键是 1234
也是这样)。
- 裸键只能包含 ASCII 字母,ASCII 数字,下划线和短横线(即只有
A-Za-z0-9_-
)。 - 引号键则允许包含任何 Unicode 字符(如中文),支持转义;
裸键名不支持中文
使用中文作为键名时,必须用引号包裹。
TOML 字符串
使用 ""
或者 ''
包裹的内容作为字符串。任何 Unicode 字符都可以使用,支持转义(如换行 \n
、反斜杠 \
)。
如果字符串有很多行,可以使用多行字符串语法:
key = """
这是多行字符串的语法,它支持你直接使用换行。
不用再拼接 \n 来换行了,好耶!
但是这样写在最前面会多出换行,因为第一行的空换行也直接读取了。
"""
key2 = """\
这样写就没有开头的空行问题了。
"""
多行换行符中,如果一行的最后一个非空白字符是未被转义的 \
时,它会连同它后面的所有空白(包括换行)一起被去除,直到下一个非空白字符或结束引号为止。
TOML 表
表(哈希表、字典、对象,含义相同)是键值对的集合。「表头」为一个单独的 []
包裹的行作为表名,后面的行都是该表的内容。
["海豹核心"]
"简介" = "一个简单易用的跑团骰子系统"
"状态" = "持续开发中"
["狐狸核心"]
"简介" = "一个更加简单易用的跑团骰子系统(什"
"状态" = "根本不存在"
以上结构相当于 JSON 中的:
{
"海豹核心": {
"简介": "一个简单易用的跑团骰子系统",
"状态": "持续开发中"
},
"狐狸核心": {
"简介": "一个更加简单易用的跑团骰子系统(什",
"状态": "根本不存在"
}
}
表还有一种更紧凑的内联表示法,必须在同一行内,且不支持尾逗号:
"海豹核心" = { "简介" = "一个简单易用的跑团骰子系统", "状态" = "持续开发中" }
TOML 数组
数组是用 []
包裹的一系列值,子元素由 ,
分隔。
TRPG = [
{ name = "CoC", version = "7" },
{ name = "D&D", version = "5e" }, # 多出一个逗号也是可以的
]
标准 JSON 而不是 JSON5
海豹支持的 JSON 牌堆是「标准 JSON」格式,诸如注释,尾逗号等语法不属于 JSON 语法,而是 JSON5 这个扩展标准的语法,出错时请严格检查。
目前暂不考虑支持 JSON5 标准,如果对注释等有需要可以尝试其它格式的牌堆。
JSON 键值
JSON 键值对以 "key": value
的形式表达,需要包裹在 {}
或 []
中。
{
"key": "value"
}
其中键名必须用 ""
包裹,值可以是如下类型:
- 整数、浮点数(即小数)
- 字符串(由
""
包裹,不可以是''
) - 布尔值(
true
或false
) - 数组:由
[]
包裹的一组值 - 对象:由
{}
包裹的一组键值对 null
:空
JSON 数组
由 []
包裹的一组值,使用 ,
分割。
[
"CoC",
"D&D"
]
最后一个元素后不可以有逗号。
JSON 对象
由 []
包裹的一组键值对,使用 ,
分割。
{
"海豹核心": {
"简介": "一个简单易用的跑团骰子系统",
"状态": "持续开发中"
},
"狐狸核心": {
"简介": "一个更加简单易用的跑团骰子系统(什",
"状态": "根本不存在"
}
}
最后一个键值对后不可以有逗号。
YAML 注释
注释以 #
开头。
YAML 键值
YAML 键值对使用冒号结构表示 key: value
,冒号后面要加一个空格。
值可以是如下类型:
- 字符串:
- 直接表示:
这是一段字符串
- 可以使用
""
或者''
包裹,双引号不会对特殊字符转义:'Hello world'
- 直接表示:
- 布尔值:
true
false
- 整数、浮点数(即小数)
- Null:用
~
表示 - 时间、日期:采用 ISO8601 格式
YAML 对象
可以使用行内语法表示对象:
海豹核心: { 简介: 一个简单易用的跑团骰子系统, 状态: 持续开发中 }
狐狸核心: { 简介: 一个更加简单易用的跑团骰子系统(什, 状态: 根本不存在 }
也可以使用缩进层级表示对象关系(推荐):
海豹核心:
简介: 一个简单易用的跑团骰子系统
状态: 持续开发中
狐狸核心:
简介: 一个更加简单易用的跑团骰子系统(什
状态: 根本不存在
缩进是有含义的
在 YAML 中,缩进是有含义的,缩进的长度表示了层级。
缩进不允许 tab,只允许使用空格。缩进的空格数并不重要,但相同层级的元素必须左对齐。
当你在复制粘贴 YAML 文本时,请务必注意这一点,格式错乱会无法识别。
YAML 数组
YAML 可以使用行内语法表示数组:
[ A, B, C ]
也可以使用以 -
开头的行表示构成一个数组:
- A
- B
- C
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格:
TRPG:
- name: CoC
version: '7'
- name: D&D
version: 5e
复杂的 YAML
YAML 的语法极其灵活,同一种形式在 YAML 中可以有多种等价表示方法,这里只列出了常见的。
如果你在阅读其它人的 YAML 牌堆时遇上了看不懂的内容,建议通过更系统的教程学习。
基础牌堆编写
海豹的抽取指令为 .draw <key>
,而牌堆就是可以提供一些 key 作为牌组的文件。
我们从编写一个最简单的牌堆开始,我们希望:
- 这个牌堆有
快端上来罢
和数字论证
两个牌组;.draw 快端上来罢
可以抽取出哼哼哼啊啊啊啊啊
你是一个一个一个牌堆结果
这两个结果;.draw 数字论证
可以抽取出114514
1919810
这两个结果。
- 填写一些信息(如作者),便于分享。
这个牌堆编写如下,你可以选择以下任意一种格式来学习:
# 元信息表
[meta]
title = "野兽牌堆"
author = "田所浩二"
# 有多个作者时可以使用,两者仅需保留一行
authors = ["田所浩二"]
version = "1.0"
license = "CC-BY-NC-SA 4.0"
date = 1919-08-10
update_date = 1919-08-10
desc = "这个示例牌堆怎么这么臭(恼)"
# 牌组表
[decks]
"快端上来罢" = [
"哼哼哼啊啊啊啊啊",
"你是一个一个一个牌堆结果"
]
"数字论证" = [
"114514",
"1919810"
]
一个 TOML 牌堆的最基本格式如上。其中 meta
表中的信息不是必须的,但我们非常建议你保留并填写这些项,它们能在分享时说明更多信息:
title
:牌堆的标题;author
/authors
:牌堆作者;date
:牌堆创建日期;updateDate
:牌堆更新日期;desc
:牌堆简介;version
:牌堆版本;license
:牌堆协议。
可以将上述内容保存名为 野兽牌堆.toml
(名称任意,但必须是以 .toml
为后缀扩展名)的文件进行测试。
{
"_title": [ "野兽牌堆" ],
"_author": [ "田所浩二" ],
"_date": [ "1919-08-10" ],
"_updateDate": [ "1919-08-10" ],
"_brief": [ "这个示例牌堆怎么这么臭(恼)" ],
"_version": [ "1.0" ],
"_license": [ "CC-BY-NC-SA 4.0" ],
"快端上来罢": [
"哼哼哼啊啊啊啊啊",
"你是一个一个一个牌堆结果"
],
"数字论证": [
"114514",
"1919810"
]
}
一个 JSON 牌堆的最基本格式如上。其中以 _
开头的项不是必须的,但是我们非常建议你保留并填写这些项,它们能在分享时说明更多信息:
_title
:牌堆的标题;_author
:牌堆作者;_date
:牌堆创建日期;_updateDate
:牌堆更新日期;_brief
:牌堆简介;_version
:牌堆版本;_license
:牌堆协议。
可以将上述内容保存名为 野兽牌堆.json
(名称任意,但必须是以 .json
为后缀扩展名)的文件进行测试。
name: 野兽牌堆
author: 田所浩二
version: '1.0'
license: CC-BY-NC-SA 4.0
desc: 这个示例牌堆怎么这么臭(恼)
command:
快端上来罢:
- 哼哼哼啊啊啊啊啊
- 你是一个一个一个牌堆结果
数字论证:
- '114514'
- '1919810'
一个 YAML 牌堆的最基本格式如上。其中上半部分的一些项不是必须的,但是我们非常建议你保留并填写这些项,它们能在分享时说明更多信息:
name
:牌堆的标题;author
:牌堆作者;version
:牌堆版本;license
:牌堆协议;desc
:牌堆简介。
可以将上述内容保存名为 野兽牌堆.yaml
(名称任意,但必须是以 .yaml
或 .yml
为后缀扩展名)的文件进行测试。
牌堆文件扩展名正确吗?
保存文件时务必确认开启了操作系统的扩展名显示,避免出现看上去保存了 xxx.json
文件,但实际上的文件名是 xxx.json.txt
。
牌堆语法
一个项中抽取其他项
牌堆抽取结果字符串中,可以实现抽取其他项,将内容拼接进该结果。
{key}
表示不放回抽取;{%key}
表示放回抽取。
[decks]
"时间点" = [
"早上",
"中午",
"晚上",
]
"追尾了" = [
"在{%时间点}追尾了一辆高级黑色轿车",
]
{
"时间点": [
"早上",
"中午",
"晚上"
],
"追尾了": [
"在{%时间点}追尾了一辆高级黑色轿车"
]
}
YAML 的放回表示
YAML 牌堆中的表示正好相反:
{key}
表示放回抽取;{%key}
表示不放回抽取。
时间点:
- 早上
- 中午
- 晚上
追尾了:
- 在{时间点}追尾了一辆高级黑色轿车
放回与不放回
放回抽取表示每次抽取该项后,下次抽取还是从同样的结果中抽取。
不放回抽取表示抽取一次后,下一次会在剩余结果中抽取,直到抽完所有结果后再重新开始。
插入掷骰表达式
抽取结果字符串中的 [exp]
,会先执行其中的掷骰表达式 exp
,再组合到原字符串里。
如:抽取 企鹅早该爆金币辣!v我[1d10]个金币
的结果可能是 企鹅早该爆金币辣!v我1个金币
。
旧的实现
研究旧牌堆,可能会发现有牌堆通过下面这样的写法来实现这个功能,现在请不要这么做了。
{
"数字": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"爆金币": "企鹅早该爆金币辣!v我{%数字}个金币"
}
权重
抽取结果字符串中最前面的 ::value::
表示该项的权重,可以理解为该项重复了几次。
权重可以是随机的:::[1d10]::
示例:有 1/10 的几率出现闪光海豹
[decks]
"捕捉海豹" = [
"::9::海豹",
"✨闪光海豹✨"
]
{
"捕捉海豹": [
"::9::海豹",
"✨闪光海豹✨"
]
}
捕捉海豹:
- ::9::海豹
- ✨闪光海豹✨
旧的实现
研究旧牌堆,可能会发现有牌堆通过下面这样的写法来实现这个功能,现在请不要这么做了。
{
"捕捉海豹": [
"海豹", "海豹", "海豹", "海豹", "海豹", "海豹", "海豹", "海豹", "海豹",
"✨闪光海豹✨"
]
}
发送图片等
抽取结果字符串中可以插入 CQ 码和海豹码,比如 [图:data/images/sealdice.png]
。
牌组的隐藏和导出控制
.draw keys
指令会列出所有允许抽取的牌组,但在牌堆编写过程中,经常会需要用到辅助的牌组,这些辅助项是不希望暴露给用户的。我们可以通过一定方式来隐藏这些项。
在 TOML 牌堆中,当牌组的名称以 _
开头,那么这个牌组将不会暴露在 .draw keys
中。
[decks]
"_时间点" = [
"早上",
"中午",
"晚上",
]
"追尾了" = [
"在{%_时间点}追尾了一辆高级黑色轿车",
]
这样在 .draw keys
中就不会展示 _时间点
这一牌组。
在 JSON 牌堆中,可以通过配置牌堆文件的 _keys
指定所有显示的牌组,未指定在列表中的牌组将不会暴露在 .draw keys
中。
{
"_keys": [ "追尾了" ],
"时间点": [
"早上",
"中午",
"晚上"
],
"追尾了": [
"在{%时间点}追尾了一辆高级黑色轿车"
]
}
这样在 .draw keys
中就不会展示 时间点
这一牌组。
被隐藏的项不会在 .draw keys
中展示,但依然可以通过指定 .draw <key>
的方法抽取。如果你希望某些牌组彻底隐藏,只能在牌堆内部调用,可以通过配置它们的导出来实现:
在 TOML 牌堆中,当牌组的名称以 __
(双下划线)开头,那么这个牌组将不导出,即无法使用 .draw <key>
进行抽取,更不会显示在列表中。
[decks]
"__时间点" = [
"早上",
"中午",
"晚上",
]
"追尾了" = [
"在{%__时间点}追尾了一辆高级黑色轿车",
]
在 JSON 牌堆中,当牌组的名称以 _
开头,那么这个牌组将不导出,即无法使用 .draw <key>
进行抽取,更不会显示在列表中。
{
"_时间点": [
"早上",
"中午",
"晚上"
],
"追尾了": [
"在{%_时间点}追尾了一辆高级黑色轿车"
]
}
这样 _时间点
这一牌组无法再用 .draw _时间点
抽取了。
此外,通过配置牌堆文件的 _export
/ _exports
可以指定所有的导出项。未指定在列表中的牌组将无法使用 .draw <key>
进行抽取,更不会显示在列表中。
{
"_exports": [ "追尾了" ],
"时间点": [
"早上",
"中午",
"晚上"
],
"追尾了": [
"在{%时间点}追尾了一辆高级黑色轿车"
]
}
UI 中识别隐藏的牌组
你可以通过查看牌堆管理界面中的「牌堆列表」来识别牌组是否隐藏。

灰色的牌组是隐藏的,即不展示在列表中,但能够被 .draw <key>
抽取。
未导出(不展示也不能抽取)的牌组不展示在该列表中。
配置牌堆更新
很多时候,牌堆内容不是一成不变的。而使用牌堆的用户需要手动去获取最新的牌堆,才能获得作者们提供的最新内容。
我们为牌堆提供了配置更新链接的机制,方便骰主快速获取牌堆更新。有能力的牌堆作者可以配置更新链接,便于分享最新的牌堆内容。
配置牌堆文件的 updateUrls
以指定对应的更新链接:
[meta]
title = "野兽牌堆"
updateUrls = [
"https://updateurl.com" # 此处填写你的更新链接
]
# 牌组表
[decks]
"快端上来罢" = [
"哼哼哼啊啊啊啊啊",
"你是一个一个一个牌堆结果"
]
"数字论证" = [
"114514",
"1919810"
]
配置牌堆文件的 _updateUrls
以指定对应的更新链接:
{
"_title": [ "野兽牌堆" ],
"_updateUrls": [ "https://updateurl.com" ],
"快端上来罢": [
"哼哼哼啊啊啊啊啊",
"你是一个一个一个牌堆结果"
],
"数字论证": [
"114514",
"1919810"
]
}
配置牌堆文件的 update_urls
以指定对应的更新链接:
name: 野兽牌堆
update_urls:
- 'https://updateurl.com'
快端上来罢:
- 哼哼哼啊啊啊啊啊
- 你是一个一个一个牌堆结果
数字论证:
- '114514'
- '1919810'
有多个更新链接时,海豹将依次从上往下检查更新。
TOML 牌堆的更多功能
更多牌组设置
TOML 牌堆中,你可以以表的形式来创建更复杂的牌组,这允许你更精细的控制每个牌组的选项。
复杂牌组和普通牌组在使用上没有什么区别,仅仅是提供了配置选项的能力。
[meta]
title = "野兽牌堆"
updateUrls = [
"https://updateurl.com" # 此处填写你的更新链接
]
# 简单牌组表
[decks]
"快端上来罢" = [
"哼哼哼啊啊啊啊啊",
"你是一个一个一个牌堆结果"
]
# 复杂牌组
["数字论证"]
export = true
visible = true
aliases = [ "恶臭论证" ]
options = [
"114514",
"1919810",
]
表名将作为这个牌组的名称,复杂牌组提供以下选项:
export
:是否导出该牌组;visible
:该牌组是否可见,不可见的将不展示在.draw keys
列表中;aliases
:牌组的别名,可以使用别名抽取改牌组,如上述示例中可以使用.draw 数字论证
或.draw 恶臭论证
来抽取;options
:该牌组的项。
云端内容
施工中……
面向有经验用户的快速指南
施工中……