MiniGame
概览
MiniGame 是一个统一的框架,通过 TypeWriter 条目运行多种小游戏。你在网页面板中描述一个竞技场:游戏模式、大厅和游戏出生点、玩家人数限制、队伍、装备包、回合和消息。玩家随后通过动作条目和菜单加入。扩展负责处理大厅、准备确认、倒计时、游戏本身、领奖台和清理。
每场游戏都遵循相同的阶段序列:Lobby、Countdown、Playing、Ending、Cleanup。每场运行中的游戏拥有一个上下文,用于存储其玩家、队伍、分数和状态,因此回合、队伍和计分板在每种模式中的行为都一致。物品栏会在游戏前保存,并在游戏后恢复。玩家的变更使用区域安全的调度,因此该扩展可运行于 Paper 和 Folia。
结果保存在构件中(胜场、分数、最佳时间、排名),并通过任务目标、事实、触发器和占位符提供给服务器的其他部分。曾经是独立扩展的跑酷,现在是其中一种游戏模式。该扩展的文档仅供参考,它运行于 TypeWriter 的 BTC 构建版本。
功能
- 26 种游戏模式 — PvP、跑酷与移动、生存、策略、派对和街机模式,全部通过竞技场的
gameType字段选择。 - 阶段引擎 — 大厅、倒计时、进行中、结束和清理,带有准备确认、最少人数、中途加入和旁观者。
- 队伍 —
NONE、SOLO、RED_BLUE或带有你自己名称的自定义队伍,可从大厅菜单中选择或自动平衡。 - 回合与增益道具 — 可选的回合会在回合之间复活玩家,并为基于规则的模式提供定时掉落的增益道具。
- 跑酷 — 起点、有序的检查点和终点,带有粒子、失败动作、计时器以及个人和竞技场纪录。
- 专用竞技场 — 为跑酷、Dé à Coudre 和射箭提供额外的配置条目。
- 菜单 — 游戏浏览器、竞技场选择、大厅、队伍选择、统计和结果菜单。
- 持久化 — 胜场、败场、分数、最佳时间和最佳时间榜存储在构件中,异步保存。
- 任务集成 — 一个完成目标和事实,以及用于游戏开始、结束、加入、淘汰、回合开始和纪录的触发器。
- 计分板与消息 — 可配置的计分板行,以及带有游戏占位符的加入、离开、淘汰和获胜消息。
安装
- 运行 TypeWriter 的 BTC 构建版本(BTC Core,Paper 或 Folia)。
- 安装 MiniGame 所依赖的扩展:BTC GUI 扩展(所有菜单都使用它)、Quest 和 Region。
- 将 MiniGame 的 JAR 放入
plugins/Typewriter/extensions/并重启服务器。 - 如果你想在计分板之外使用
<minigame_...>占位符,请安装 MiniPlaceholders。它们通过 BTC MiniPlaceholders 桥接发布,而不是 PlaceholderAPI。 - 在世界中搭建竞技场,在某个条目要求时创建保护区域(例如 Dé à Coudre 竞技场的水池),然后在网页面板中配置这些条目。
快速上手
本演示将设置一个带有持久化统计数据的 Spleef 竞技场。
- 在 TypeWriter 网页面板中,打开一个**清单(manifest)**页面,添加一个 Wins statistics 构件。为其设置一个
artifactId,例如spleef_wins。 - 在同一页面上添加一个 Minigame Arena 条目。将
gameType设为SPLEEF,然后使用位置选取器设置lobbySpawn、gameSpawn、spectatorSpawn和endTeleport。 - 设置
minPlayers和maxPlayers、autoStartCountdown(游戏开始前的秒数)以及maxGameDuration(秒)。 - 如果你想要多个回合,请启用
useRounds并设置maxRounds(每个回合玩家会被复活并重新放置在gameSpawn)。向kitItems中添加物品,并保持giveKit开启。 - 将
winStatArtifact链接到第 1 步中的构件。 - 打开一个**序列(sequence)**页面。添加一个 Open the minigame browser 动作,并通过 NPC 对话、物品或命令触发它。或者使用 Join a minigame,并将
arena设为你的竞技场,直接把玩家送入大厅。 - 发布,加入竞技场,在大厅菜单中点击 Ready,然后等待倒计时。游戏结束时,会宣布获胜者并保存统计数据。
只有当至少有 minPlayers 名玩家点击了 Ready 时,大厅才会开始倒计时。独自测试时,请将 minPlayers 设为 1。
工作原理
- 大厅。 玩家在
lobbySpawn等待。当标记为已准备的玩家数量达到minPlayers后,几秒钟后倒计时开始。只有在allowLateJoin开启时,才能在大厅阶段之后中途加入。 - 倒计时。 持续
autoStartCountdown秒,并带有聊天消息。如果玩家离开使人数降到最低要求以下,游戏会返回大厅。 - 进行中。 玩家被传送到
gameSpawn,其物品栏被保存,并发放装备包。该阶段最迟在maxGameDuration秒后结束。触发onGameStart。 - 结束。 宣布获胜者和前三名。该阶段持续约
maxGameDuration的六十分之一,限制在 5 到 60 秒之间。 - 清理。 恢复物品栏、游戏模式和生命值,将结果写入构件,触发
onGameEnd,玩家返回endTeleport。
当 allowSpectate 开启并设置了旁观者出生点时,被淘汰的玩家会成为旁观者,并被移动到 spectatorSpawn。
游戏模式
竞技场的 gameType 字段接受下面的 26 个值。其中三种模式有自己的代码。其余 23 种是基于规则的:它们共用一个由淘汰方式和获胜条件驱动的引擎。基于规则的模式为你提供规则、大厅、回合和计分。特定于游戏名称的内容(旗帜、怪物波次、上升的岩浆地面、TNT 方块、发射器)不会被生成:你需要在世界中自行搭建,并用装备包、区域和触发器将其连接起来。
| 模式 | 类别 | 默认人数 | 淘汰方式 | 获胜条件 |
|---|---|---|---|---|
| Sumo | PvP / 战斗 | 2-8 | 坠落 | 最后存活 |
| Gladiator | PvP / 战斗 | 2-12 | 被击杀 | 最后存活,每 20 秒出现增益道具 |
| Duels | PvP / 战斗 | 2 | 被击杀 | 最后存活 |
| KOTH | PvP / 战斗 | 2-16 | 超时 | 最先得分,增益道具 |
| Paintball | PvP / 战斗 | 2-16 | 被击杀 | 得分最高 |
| One in the Chamber | PvP / 战斗 | 2-12 | 被击杀 | 得分最高 |
| Parkour | 跑酷 / 移动 | 1 | 专用代码 | 到达终点 |
| Block Party | 跑酷 / 移动 | 2-16 | 地面消失 | 最后存活,最多 5 回合 |
| TNT Run | 跑酷 / 移动 | 2-16 | 坠落 | 最后存活 |
| Floor is Lava | 跑酷 / 移动 | 2-16 | 坠落 | 最后存活,最多 3 回合 |
| Falling Blocks | PvE / 生存 | 1-16 | 坠落 | 存活 120 秒 |
| Wave Survival | PvE / 生存 | 1-8 | 被击杀 | 存活 180 秒,增益道具 |
| Zombie Apocalypse | PvE / 生存 | 1-8 | 被击杀 | 存活 300 秒,增益道具 |
| Dodge the Arrows | PvE / 生存 | 1-16 | 被击杀 | 最后存活 |
| Defend the Core | PvE / 生存 | 1-8 | 被击杀 | 最后存活的队伍,240 秒 |
| Capture the Flag | 策略 | 4-16 | 被击杀 | 最先得分,300 秒 |
| Infection | 策略 | 2-16 | 被标记 | 最后存活 |
| Spleef | 策略 | 2-16 | 地面消失 | 最后存活,最多 5 回合 |
| Sheep Hunt | 策略 | 4-16 | 被标记 | 标记最多,180 秒 |
| TPP (Tag) | 派对 / 趣味 | 2-16 | 被标记 | 最后存活 |
| Freeze Tag | 派对 / 趣味 | 2-16 | 被标记 | 最后存活 |
| Hot Potato | 派对 / 趣味 | 2-16 | 超时 | 最后存活,60 秒 |
| Dé à Coudre | 派对 / 趣味 | 2-16 | 专用代码 | 最后存活的玩家或队伍 |
| Musical Chairs | 派对 / 趣味 | 2-16 | 超时 | 最后存活,最多 10 回合 |
| Archery | 反应 / 街机 | 1-16 | 专用代码 | 最先达到目标数,或在时限内得分最高 |
| Quake | 反应 / 街机 | 2-16 | 被击杀 | 得分最高 |
只有当竞技场的 minPlayers 不大于零时,才会使用默认的最小值。最大值始终来自竞技场的 maxPlayers。
基于规则的模式如何判定
- 被击杀:来自其他玩家的一次攻击就会淘汰受害者,无论伤害多少,并给攻击者加一分。弹射物的射击者同样计入。
- 被标记:来自其他玩家的一次攻击会淘汰受害者,并给标记者加一分。在友军伤害关闭时,队友受到保护。
- 坠落:玩家在低于
gameSpawn十格以下时被淘汰。 - 地面消失:当脚下的方块是空气时,玩家被淘汰。
- 超时:没有任何计时器会自行淘汰玩家。带有持续时间的回合会在时间到时直接结束,由分数或幸存者决定获胜者。
- 增益道具:当
powerUpEnabled开启时,每隔powerUpInterval秒(至少 5 秒)会掉落一个随机的增益道具物品。八种类型为 Speed、Jump、Invisibility、Heal、Shield、Explosive Snowball、Double Jump 和 Super Strength。 - 回合:开启
useRounds后,被淘汰的玩家会被复活,每个回合所有人都会被重新放置在gameSpawn,最多maxRounds个回合。扩展不会在回合之间重建方块:请自行修复被破坏的地面。每个回合触发onRoundStart。
跑酷
跑酷是一种带有自己配置条目的单人模式。Parkour Arena 链接到类型为 PARKOUR 的 Minigame Arena,并列出其起点、检查点和终点。玩家站在起点上开始跑酷,必须按 order 递增的顺序经过检查点,然后到达终点。
failAction决定失败时的处理:START传送回起点,LAST_CHECKPOINT传送到上一个检查点,QUIT放弃本次跑酷。timerType为NONE、GLOBAL(固定的time,单位为秒)或CHECKPOINT(time加上每个检查点的checkpointBonus秒)。时间耗尽即为失败。- 当玩家切换世界、掉落到起点以下超过 5 格,或距离上一个检查点超过 10 格时,跑酷同样会失败。
- 完成时,时间会被提交用于纪录:个人最佳、竞技场排名,以及竞技场上的
onPersonalBest和onWorldRecord触发器。随后竞技场结束,因为已经没有人在跑了。
Dé à Coudre
Dé à Coudre Arena 添加了一个水池区域、一个跳跃位置和一个出生点。mode 为 SINGLE(玩家轮流跳跃)、CONCURRENT(所有人同时跳跃)或 TEAM。玩家开始时没有备用的生命:一次失误的跳跃会淘汰该玩家,而完美的跳跃(落在四个已使用的方块之间)会赢得一条生命。lives、turn 和 queue 占位符显示其状态。
射箭
Archery Arena 列出目标位置和射击区域。mode 为 MAX_TARGET(最先命中 targetsToWin 次)或 TIME_ATTACK(在 timeLimitSeconds 内得分最高)。扩展会放置 targetBlock,在被命中时将其替换为 hitBlock,并给予 bowItem 和 arrowItem。
菜单
这些菜单是由 GUI 扩展渲染的 54 格箱子菜单。在你添加用于打开它们的动作条目之前,它们保持为空。
| 菜单 | 打开方式 | 内容 |
|---|---|---|
| 游戏浏览器 | Open the minigame browser | 一行六个类别,然后是所选类别中的游戏。只有存在该类型的竞技场时,游戏才可用。 |
| 竞技场选择 | Open arena selection 或在浏览器中点击 | 某个游戏类型的竞技场及其状态(空闲、等待中、已满、游戏中)和玩家数量。点击即可加入。 |
| 大厅 | Open the lobby menu,或在通过菜单加入后自动打开 | 竞技场描述、带有准备状态和队伍的玩家列表、Ready、Team、Start the game 和 Leave 按钮,以及你的自定义按钮。 |
| 队伍选择 | Team 按钮 | 选择一个队伍,或被随机分配一个。 |
| 统计 | Open statistics | 胜场、败场、游戏场数和前 10 名,按竞技场或跨竞技场统计。需要竞技场上的 winStatArtifact。 |
| 结果 | Open the results screen | 获胜者、持续时间、玩家数量和领奖台。请将该动作接到竞技场的 onGameEnd 触发器上。 |
Start the game 按钮只会显示给拥有 minigame.start 权限的玩家。Lobby Menu 条目可以自定义标题、隐藏菜单的某些部分,并添加 slot 为 0 到 53、带有 showCondition 的按钮。
持久化与纪录
构件在启动时加载并异步写入,因此保存永远不会阻塞游戏的 tick。存储的数据按竞技场和玩家保存。
- Wins statistics 存储胜场、败场和游戏场数,在清理时为该场游戏的每位玩家保存。
- Scores statistics 在清理时累加每位玩家的分数(当其大于零时)。
- Minigame state 在清理时写入,包含最终阶段、玩家数量和获胜者。
- Best time 和 Top times 存储个人最佳和排名;
topTimesLimit设置保留多少个时间。目前只有跑酷会产生时间。
Reset records 会清除某个竞技场对触发它的玩家(PLAYER)或对所有人(ARENA)的纪录。
任务集成
Complete minigames 目标统计已完成的计时跑酷次数。将 arena 留空以统计所有竞技场,或设置它以统计某一个。它把进度存储在你提供的事实中,并可触发 onComplete。Minigame completions 事实会分别统计玩家所在的每个竞技场的完成次数,因此一个事实可以服务于整个竞技场网络。目前两者都只对跑酷的完成作出反应。
权限
| 权限 | 授予 |
|---|---|
minigame.start | 在大厅菜单中显示并允许使用 Start the game 按钮。 |
没有命令:一切都由条目和菜单驱动。
占位符
游戏占位符有两种形式。在竞技场的消息和计分板行中,你可以使用 %name% 令牌。在服务器的其他地方,BTC MiniPlaceholders 桥接会为处于游戏中的玩家将相同的值发布为 <minigame_name>。
| 占位符 | 返回 |
|---|---|
arena 和 arena_id | 竞技场名称和条目 id。 |
game_id | 正在运行的游戏的 id。 |
phase | 当前阶段名称。 |
players 和 alive | 游戏中的玩家数和仍然存活的玩家数。 |
max_players | 竞技场的玩家人数上限。 |
winner | 获胜者名称,在尚无获胜者时为 "Personne"。 |
score | 玩家的分数。 |
alive_status | alive 或 eliminated。 |
rank | 玩家按分数的排名,或 -。 |
lives、turn 和 queue | 生命、当前跳跃者和跳跃顺序,仅用于 Dé à Coudre。在其他模式中为 -。 |
%player%(仅限消息) | 玩家名称,用于加入、离开和淘汰消息。 |
条目
24 个条目,由扩展源码生成。
动作9
- Minigame ForcestartForcer le démarrage d'un mini-jeu
- Minigame JoinRejoindre un mini-jeu
- Minigame LeaveQuitter un mini-jeu
- Minigame Open ArenasOuvrir la sélection d'arène
- Minigame Open BrowserOuvrir le navigateur de mini-jeux
- Minigame Open LobbyOuvrir le menu du lobby
- Minigame Open ResultsOuvrir les résultats de la partie
- Minigame Open StatsOuvrir les statistiques de mini-jeux
- Minigame Reset RecordsRéinitialiser les records d'une arène
目标1
- Minigame Completion ObjectiveTerminer des mini-jeux
事实1
- Minigame Completion FactCompte les complétions d'un joueur, par arène
构件5
- Minigame Best Time ArtifactStocke le meilleur temps personnel de chaque joueur par arène
- Minigame ScoresStatistiques de scores
- Minigame StateÉtat d'un mini-jeu
- Minigame Top Times ArtifactStocke le classement des meilleurs temps d'une arène
- Minigame WinsStatistiques de victoires
清单5
- Archery ArenaArène de tir à l'arc
- Deacoudre ArenaDé à Coudre Arena
- Minigame ArenaArène de mini-jeu
- Minigame Lobby MenuMenu du lobby
- Parkour ArenaArène de Parkour
定义3
- Parkour CheckpointCheckpoint du parkour
- Parkour End PointPoint d'arrivée du parkour
- Parkour Start PointPoint de départ du parkour
故障排查
菜单没有任何作用或为空。 菜单需要 GUI 扩展以及一个用于打开它们的动作条目。请检查是否存在对应 gameType 的竞技场:当没有竞技场使用某个游戏类型时,浏览器会将其标记为不可用。
游戏一直停留在大厅。 只有当至少有 minPlayers 名玩家点击了 Ready 时,倒计时才会开始,仅仅在场是不够的。请降低 minPlayers,或使用 Force start a minigame 来开始倒计时。
“Vous êtes déjà dans une partie”。 一位玩家同一时间只能处于一场游戏中。请先使用 Leave a minigame。离开、断线以及结束游戏都会释放该玩家。
在 KILL 或 TAG 模式中始终没有人被淘汰。 请在生存模式下用一位可以受到伤害的玩家进行测试:在创造模式下玩家是无敌的。这些模式中的淘汰来自其他玩家造成的伤害,包括箭矢和雪球。
统计数据、击杀数或状态构件保持为空。 竞技场只会写入它所引用的构件:请设置 winStatArtifact、scoreArtifact 和 stateArtifact,并为每个构件设置 artifactId。击杀和死亡目前的代码不会记录,显示为 0。最佳时间和最佳时间榜只由跑酷写入。
跑酷总是失败。 每个检查点必须在距上一个检查点 10 格之内,并且当玩家在起点以下 5 格时就会失败。检查点必须按 order 递增的顺序到达,并且终点只有在最后一个检查点之后才有效。当 radius 为 0 时,玩家必须站在精确的那个方块上。
玩家无法离开大厅区域。 等待期间(Lobby 和 Countdown 阶段),lobbyRadius(默认为 lobbySpawn 周围 10 格)会阻止玩家走远;它不会传送玩家,已经在范围外的玩家始终可以走回来。设为 0 表示不限制。
玩家无故被淘汰。 region 是基于规则的模式的游戏区域:游戏中离开该区域会淘汰玩家(Archery、Parkour 和 Dé à Coudre 有各自的阶段,不应用该区域)。在地面消失的模式(Spleef、Block Party)中,floorMaterial 以逗号分隔列出算作地面的 Bukkit 材质名称:玩家脚下的方块一旦不在其中,就会被淘汰。留空表示任何非空气方块都算地面,未知名称会被忽略并在控制台给出警告。地面不会根据 floorMaterial 生成,需要你自己搭建。
胜利消息与预期不符。 winMessage 会在游戏结束时公布,其中的 %winner% 会被替换为获胜者。
玩家无法加入竞技场。 当竞技场每个开放的大厅都已有 maxPlayers 名玩家时,竞技场即已满,加入会被拒绝:不会并行开启第二局游戏。此时 Join a minigame 动作会发送其 fullMessage。