床战

床战

适用于Hytale的经典BedWars团队PvP——保护你们的床,袭击资源生成器,在商店升级,并比所有其他队伍坚持得更久

小游戏

BedWars

一个面向 Hytale 的全功能 BedWars 小游戏插件。保卫你的床,突袭敌方岛屿,成为最后一个存活的队伍。基于 Hytale 平台从零构建,支持多队竞技场、地图投票、可配置商店、AI 机器人、持久化玩家统计数据和丰富的集成功能。


特性

核心玩法

  • 经典床战规则 — 摧毁敌方床以阻止其重生,消灭他们队伍中的其余成员,最后存活的队伍获胜。
  • 可配置队伍规模 — 单人、双人、三人、四人小队,或任何自定义规模,上限为竞技场容量。
  • 地图投票 — 玩家在每场比赛前从候选地图的随机子集中投票。平局和超时则随机选择。
  • 手动或自动队伍选择 — 玩家可以在队伍选择阶段手动选择队伍,未选择的玩家将自动平衡。
  • 快速开局 — 当竞技场人数超过可配置的阈值时,开局倒计时会自动缩短。
  • 旁观模式 — 被淘汰的玩家变为旁观者;在启用时,后来的玩家也可以旁观进行中的比赛。
  • 每队资源生成器 — 青铜、铁、金(或任何自定义掉落物)在可配置的位置和间隔生成。
  • 每竞技场大厅 — 每个竞技场都有独立的等待大厅,包含投票、队伍选择和离开物品。
  • 方块保护 — 只有玩家放置的方块可以被破坏;地图地形会自动保留。
  • 友军保护 — 队友之间不能互相伤害。
  • 虚空死亡处理 — 掉落出世界边界视为正常死亡。
  • 每竞技场世界实例化 — 每个竞技场加载自己的世界模板副本,允许多个游戏并行运行而互不干扰。

商店系统

  • 分层分类商店 — 顶级标签页(方块、武器、盔甲、工具等),每个分类下有物品列表。
  • 多货币交易 — 定义需要任意游戏内物品组合(例如 4 个青铜 + 1 个铁)作为花费的购买项。
  • Shift 快速购买 — Shift 点击任何交易项以购买一整组或尽可能多的数量。
  • 自定义显示名称和图标 — 每个交易项和分类都支持自定义标签和图标物品。
  • 每竞技场商店选择 — 将每个竞技场指向一个命名的商店配置。
  • 可取消的购买事件 — 第三方插件可以通过 ArenaShopPurchaseEvent 拦截或修改购买。

AI 机器人(实验性)

此插件包含一个实验性的机器人系统,可以填补空队伍席位或与真实玩家一起游戏。机器人可以收集资源、建造、战斗和攻击床,并具有可选的难度配置文件(EASYMEDIUMHARD)。

机器人基于 Hytale 的核心实体和 NPC 机制构建,而这些机制本身仍处于早期阶段且包含错误。这些底层系统中的任何限制或故障也会在机器人的行为中表现出来。机器人系统及其基础都将在未来的更新中持续改进。

可选的移动补丁(Mixin 混合)。 Hytale 的 NPC 转向存在一个死锁问题:静止的机器人无法引导自身的速度,从而卡在原地。一个可选伴生模组 — BedWars-Mixins — 应用了运行时 Sponge Mixin 补丁(由 Hyxin mixin 框架加载)来解决该问题,从而使机器人的移动更加可靠。它不是必需的 —— 不安装它机器人也能运行 —— 但安装它(与 Hyxin 加载器一起)可以显著改善机器人的移动。

持久化玩家统计数据

  • 追踪的数据:击杀、死亡、获胜、失败、摧毁床数、放置方块数、破坏方块数、命中次数、游戏场数
  • 玩家可以使用 /bw stats 命令查看自己的数据。
  • 统计数据通过 PlaceholderAPI 向其他插件开放。
  • 可选的 MySQL 存储,使用 HikariCP 连接池和异步写入。

经济与奖励

  • 可选的基于统计数据的奖励发放 — 通过击杀、获胜、破坏床等行为赚取货币。每个奖励值均可独立配置。
  • 内置对 Ecotale 作为经济后端(后台系统)的支持。
  • 提供可插拔的经济提供程序 API,用于自定义后端。

国际化

  • 内置语言:英语 (en-US)捷克语 (cs-CZ)
  • 消息使用 Hytale 原生的 .lang 资产系统 — 放入翻译好的文件即可添加新语言。

要求

  • 安装了 Kytale 框架的 Hytale 服务器

必需依赖

插件 版本
Kytale (AmoAster:Kytale) >= 1.4
PlaceholderAPI (CreeperFace:PlaceholderAPI) 任意
UiManager (CreeperFace:UiManager) >= 1.0

可选依赖

插件 用途
Ecotale 基于统计奖励的经济后端
BedWarsConfigurator 用于编辑竞技场、地图和商店的游戏内 UI
BedWars-DebugMixins 修复 NPC 转向死锁的 Mixin 补丁 — 使机器人移动更顺畅(需要 Hyxin 加载器)

安装

  1. BedWars 插件文件放入服务器 mods 目录。
  2. 将上面列出的必需依赖插件安装到同一个 mods 目录。
  3. (可选)安装 BedWarsConfigurator 以获取游戏内设置界面。
  4. (可选)如果你想使用基于经济的奖励,请安装 Ecotale
  5. 启动服务器。默认的 config.jsoneconomy.jsongame.jsonbot.json 文件会在首次运行时自动生成。

首次启动后,放入现成的演示设置(见下文)或配置你自己的竞技场、地图和商店(参见设置),然后使用 /bw join 加入游戏。


立即尝试 — 演示设置

想要一个无需手动配置就能运行的游戏?下载 演示设置包 — 一个完整的、开箱即用的包,包含了所有内容:所有必需的模组、预配置的竞技场、地图和商店,以及游戏世界。无需单独安装依赖,无需编辑 JSON。

该包包含了两个顶级目录,镜像了你的 Hytale 服务器布局:

mods/      所有必需模组 (BedWars, Kytale, PlaceholderAPI, UiManager, ...) 以及演示
           BedWars 配置文件 — 竞技场、地图和商店 — 位于 mods/CreeperFace_BedWars/ 下
worlds/    演示游戏世界
  1. 从项目的资源/下载页面下载演示包。
  2. 将其解压到你的 Hytale 服务器目录,将包中的 mods/worlds/ 文件夹合并到你的服务器中。
  3. 启动服务器。
  4. 使用 /bw join 加入游戏并开始游玩。

由于该包包含了所有必需的模组,为了快速体验,你可以跳过下面的安装和设置步骤。它也可以作为你自己构建竞技场、地图和商店时的实用参考。


设置工作流程

推荐的工作流程是使用 BedWarsConfigurator 伴生插件,它为所有以下内容提供了游戏内 UI。如果你更喜欢手动编辑 JSON,所有相同的文件都位于插件数据目录中。

插件数据布局

BedWars 的数据文件夹位于 mods/CreeperFace_BedWars/(Hytale 从 manifest.json 中插件的组和名称衍生出文件夹名):

mods/CreeperFace_BedWars/
├── config.json              全局插件设置
├── economy.json             经济提供程序和奖励值
├── game.json                聊天格式和游戏机制
├── bot.json                 机器人系统设置
├── arenas/
│   └── <ArenaName>.json     竞技场定义
├── maps/
│   └── <MapName>/
│       ├── config.json      地图(队伍、床、生成点、生成器)
│       ├── preview.png      投票界面中显示的地图预览
│       └── world/           每场游戏复制的世界模板
└── shops/
    └── <ShopName>.json      商店窗口/分类/交易项定义

构建你的第一个竞技场

  1. 构建(或导入)一个地图世界,并将其放置在 maps/<MapName>/world/ 下。
  2. 添加一个可选的 preview.png(显示在投票界面中)。
  3. 创建 maps/<MapName>/config.json,定义每个队伍的重生点、床位置、商店 NPC 位置和资源生成器。
  4. 创建 arenas/<ArenaName>.json,包含大厅位置、玩家人数、时间限制以及控制哪些地图符合资格的 map_filter
  5. (可选)创建一个 shops/<ShopName>.json,并在竞技场中引用它。
  6. 重启服务器(或使用配置器的重新加载功能)。

使用配置器进行设置

BedWarsConfigurator 插件提供了一个可视化设置工具,它可以为你处理所有 JSON 文件的编辑工作 — 竞技场创建、包含队伍位置的地图注册、商店构建以及实时预览。强烈推荐用于生产环境设置。


配置参考

config.json — 全局设置

{
  "general": {
    "auto_join": false
  },
  "data": {
    "enable": false,
    "data_provider": "none",
    "store_configs": false,
    "mysql": {
      "host": "127.0.0.1",
      "port": 3306,
      "user": "root",
      "password": "mysql",
      "database": "default"
    }
  }
}
字段 默认值 描述
general.auto_join false 连接时自动将玩家加入可用竞技场
data.enable false 启用持久化数据存储
data.data_provider "none" nonemysql(可通过 API 扩展)
data.store_configs false 从数据库加载竞技场/地图/商店配置,而非文件
data.mysql.* data_provider = "mysql" 时使用的连接设置

economy.json — 经济与奖励

{
  "economy_provider": "none",
  "rewards": {
    "enabled": false,
    "values": {
      "kills": 10.0,
      "deaths": 0.0,
      "wins": 100.0,
      "losses": 0.0,
      "beds": 50.0,
      "place": 0.0,
      "break": 0.0,
      "hits": 0.0,
      "games": 5.0
    }
  }
}
字段 默认值 描述
economy_provider "none" noneecotale(可通过 API 扩展)
rewards.enabled false 在记录统计数据时向玩家支付奖励
rewards.values.* 多种 每个统计事件奖励的货币数量

竞技场配置 (arenas/<Name>.json)

字段 描述
name 竞技场标识符
max_players 竞技场容量的硬上限
start_players 开始倒计时所需达到的玩家人数
team_players 每队玩家人数
start_time 队伍选择倒计时秒数
ending_time 竞技场重置前结束画面显示的秒数
respawn_delay 玩家重生前等待的秒数(床未被破坏时)
fast_start / fast_start_players / fast_start_time 当竞技场人数超过阈值时缩短倒计时
time_limit 比赛最大持续时间(秒)
lobby_positionlobby_world 玩家等待时生成的位置
voting.enablevoting.max_optionsvoting.countdown 地图投票设置
map_filter.enable.team_count.include.exclude 符合资格地图的白名单/黑名单
shop 要使用的商店配置名称
lobby_items 用于投票/队伍选择/离开物品的自定义物品 ID 和槽位

地图配置 (maps/<Name>/config.json)

字段 描述
name 地图标识符
teams[] 队伍列表:namecolor(十六进制)、spawnbedvillager 位置
resources[] 资源生成器:nameitem_iddrop_frequency(掉落间隔 tick 数)、positions 列表
extensions 用于第三方插件扩展的自由格式 JSON

商店配置 (shops/<Name>.json)

一个商店是一个 windows(分类标签页)列表。每个窗口包含 children — 各个交易项。每个交易项都有一个 purchase_item(玩家收到的物品)和一个 cost 数组(所需的任何物品组合)。

{
  "windows": [
    {
      "type": "menu",
      "name": "方块",
      "icon": {
        "item_id": "Cloth_Roof_Green_Flap"
      },
      "children": [
        {
          "type": "offer",
          "name": "绿色羊毛",
          "purchase_item": {
            "item_id": "Cloth_Roof_Green_Flap",
            "item_count": 16
          },
          "cost": [
            {
              "item_id": "Bronze_Coin",
              "item_count": 4,
              "item_name": "青铜"
            }
          ]
        }
      ]
    }
  ]
}

机器人配置 (bot.json)

字段 默认值 描述
enabled false 激活机器人系统
bots_per_team 0 自动为每队生成此数量的机器人
fill_teams true 队伍选择后,用机器人填补空余队伍槽位
difficulty "MEDIUM" EASYMEDIUMHARD
role_asset "BedWars_Bot" 用于生成机器人的 NPC 角色资源
name_prefix "[BOT] " 显示名称前缀(空字符串则禁用)
eval_interval 10 目标重新评估之间的 tick 间隔(越低越灵敏)

游戏机制与聊天 (game.json)

game.json 分为 general 部分和 chat 部分:

{
  "general": {
    "allow_spectators": true
  },
  "chat": {
    "enable_all_chat": true,
    "all_prefix": "!",
    "lobby_format": "...",
    "team_format": "...",
    "all_format": "...",
    "spectator_format": "..."
  }
}
字段 默认值 描述
general.allow_spectators true 允许被淘汰的玩家(以及后来的加入者)旁观进行中的游戏
chat.enable_all_chat true 完全切换跨队全聊天功能
chat.all_prefix "!" 消息前缀,可将队伍消息切换为全聊天
chat.lobby_format 大厅中使用的聊天格式
chat.team_format 游戏中队伍聊天格式
chat.all_format 游戏中全聊天格式
chat.spectator_format 旁观者聊天格式

*_format 字符串使用 PlaceholderAPI 占位符(参见下表) — 例如 %player_display_name%%message%%team_color%


命令

所有命令都在 /bw 根命令下。

命令 描述
/bw 显示命令帮助
/bw join [arena] 加入指定的竞技场,或任何一个可用的竞技场
/bw leave 离开当前竞技场
/bw vote 打开地图投票界面(投票阶段)
/bw team 打开队伍选择界面(队伍选择阶段)
/bw start 强制推进开始倒计时
/bw stop 强制停止当前游戏
/bw stats 查看你的个人统计数据
/bw shop 打开商店界面(测试/调试用)
/bw bot [team] 为指定队伍生成一个机器人(测试用)

占位符

此插件具有完全的 PlaceholderAPI 支持。所有 BedWars 占位符都以 bw_ 为前缀。

竞技场占位符(全局,通过竞技场名称参数化)

用法为 %bw_arena_<property><ArenaName>%

占位符 描述
bw_arena_player_count 当前玩家人数
bw_arena_max_players 配置的最大人数
bw_arena_team_size 每队玩家人数
bw_arena_state waitingvotingteamSelectgame
bw_arena_time 当前游戏已进行的秒数
bw_arena_time_formatted 已进行时间,格式为 M:SS
bw_arena_time_remaining 距离时间限制剩余秒数
bw_arena_time_remaining_formatted 剩余时间,格式为 M:SS
bw_arena_timeLimit 配置的时间限制(秒)
bw_arena_team_count 活跃游戏中的队伍数量
bw_arena_alive_teams 仍在游戏中的队伍
bw_arena_winner 获胜队伍的名称(游戏结束后)
bw_arena_map 当前加载的地图名称
bw_arena_spectators 旁观者数量
bw_arena_ending 当结束画面正在显示时为 true

队伍占位符(限定于队伍上下文中)

占位符 描述
bw_team_name 队伍显示名称
team_color 队伍颜色(若无队伍作用域,如大厅聊天,则解析为空)
bw_team_players 当前成员数量

竞技场占位符(限定于竞技场上下文中)

占位符 描述
bw_arena_name 竞技场名称
bw_arena_players 当前玩家人数

颜色占位符

颜色通过 PlaceholderAPI 内置的帮助程序应用 — 无需额外的注册步骤:

  • %color<name,shade>% — Tailwind 调色板,例如 %color<zinc,400>%%color<cyan,500>%。默认色度为 500。
  • %color_rgb<r,g,b>% — 明确的 RGB,例如 %color_rgb<255,255,255>%
  • %color_hex<rrggbb>% — 明确的十六进制,例如 %color_hex<ff5555>%
  • %team_color% — 活跃队伍的颜色,当没有队伍作用域时解析为空字符串。

插件 API

BedWars 暴露了一个公共的 BedWarsAPI 接口,其他插件可以使用:

  • 查找竞技场、获取玩家当前所在的竞技场、加入随机竞技场。
  • 通过 registerDataProvider 注册自定义的数据提供程序(存储后端)。
  • 通过 registerEconomyProvider 注册自定义的经济提供程序
  • 监听竞技场生命周期事件:
    • ArenaPlayerJoinEventArenaPlayerLeaveEvent
    • ArenaStartEventArenaStopEventArenaStateChangeEvent
    • ArenaPlayerEliminateEventArenaPlayerRespawnEventArenaTeamEliminateEvent
    • ArenaKillEventArenaBedDestroyEvent(可取消)
    • ArenaShopPurchaseEventArenaResourceDropEvent(两者均可取消)
  • 通过 ConfigExtensionRegistry 使用自定义部分扩展竞技场/地图/商店配置。

将 BedWars API 模块作为编译时依赖项添加即可使用。完整的 API 文档 — 用法、事件和自定义示例 — 位于公共 API 仓库中: Creeperface01/BedWars-API(在此处作为 api/ git 子模块引入)。


游戏流程

等待 → 投票 → 队伍选择 → 游戏 → (重置至等待)
  1. 等待 — 玩家在竞技场大厅中。当达到 startPlayers 时,竞技场推进。
  2. 投票 — 玩家对候选地图的随机子集进行投票。获胜地图(或随机后备)被加载。
  3. 队伍选择 — 玩家通过界面选择队伍。倒计时结束时,未选择的玩家会被自动平衡。
  4. 游戏 — 比赛运行,直到只剩一个队伍存活、时间耗尽或管理员停止游戏。床未被破坏时死亡的玩家会重生;床被破坏后死亡的玩家成为永久旁观者。
  5. 重置 — 世界副本被清除,玩家返回大厅,竞技场等待下一场比赛。

语言

内置翻译:

  • 英语(en-US
  • 捷克语(cs-CZ

要添加语言,请将翻译好的 .lang 文件放入相应 Server/Languages/<locale>/ 资产路径下。


鸣谢

  • 作者: CreeperFace

支持

请在 BedWars-API 问题追踪器 上报告问题和功能请求。欢迎贡献和翻译。