跳到正文
Gang Fights

脚本 SDK · Luau

动手打造,你自己的游戏模式。

Gang Fights 服务器运行以 Luau (在新标签页中打开)(支持可选类型的 Lua)编写的资源。从掷骰子命令到完整的角色扮演城市:只要发生在服务器上,就能用脚本实现。

状态:早期 Alpha。 在同一个主版本内,脚本 API 只增不减,所以你今天写的资源以后也能继续运行。接下来将支持自定义模型、贴图和音效。

资源

资源是服务器 recursos/ 文件夹中的一个文件夹:包含一个 resource.toml 清单及其脚本。服务器脚本在服务器上运行;客户端脚本会发送给每位玩家并在其电脑上运行。服务器自带的每个游戏模式都只是一个资源——复制一份、改个名字,想怎么改就怎么改。

文件夹结构
recursos/
  hello/
    resource.toml
    server/main.luau
    client/hud.luau        -- optional: runs on each player's PC
resource.toml
name = "hello"
version = "1.0.0"
description = "Says hello"
author = "You"
server_scripts = ["server/main.luau"]
client_scripts = []   # sent to each player and run on their PC
dependencies = []     # resources that must be running first
gamemode = false      # true: this resource runs the rounds
autostart = true

你的第一个资源

在玩家加入时打个招呼,并添加一个 /dice 命令。启动服务器后资源就会运行;修改之后,在服务器控制台输入 restart hello,即可立即重新加载。

hello/server/main.luau
on("playerJoin", function(player: number)
  players.message(player, "Hello, " .. (players.name(player) or "?") .. "!")
end)

registerCommand("dice", function(player: number)
  chat.broadcast((players.name(player) or "?") .. " rolls " .. math.random(1, 6))
end)
服务器控制台
> resources            # list what's running
> restart hello        # reload after editing — no server restart
> players
> say Round starts in 1 minute
> ban 7 60 spamming    # by player number, for 60 minutes

API 覆盖范围

服务器 API 按功能拆分为小而专一的库。每位玩家都以一个编号标识——也就是大家在玩家列表中看到的、显示在昵称旁边的那个数字。

  • 事件

    加入、离开、命中、击倒、物品、回合、涂鸦、菜单选择——以及资源之间的自定义事件。

  • 聊天与命令

    彩色聊天、带参数的 /命令、输入建议以及发给单个玩家的消息。

  • 计时器

    用 setTimeout、setInterval 和 clearTimer 处理延迟或重复执行的任务。

  • 玩家

    昵称、名字颜色与标签、管理员、踢人、限时封禁以及固定的玩家 ID。

  • 战斗者

    生命值、队伍、出生点、传送、角色、冻结、无敌和复活。

  • 警察

    让任意战斗者成为警察,戴上或解开手铐,并分发手铐钥匙。

  • 帮派与命令

    读取和下达六种帮派命令,并操作游戏中的帮派及其成员。

  • 物品

    给予、收走和丢下武器与物品,列出地上的东西,调整它们的重量。

  • NPC

    放置原地不动的角色,带名字、图标和待机动画——店主、招募者、任务发布者。

  • 维度

    同时运行多张地图,在地图之间移动战斗者,并在比赛之间轮换地图。

  • 标记与门

    悬浮标记提示玩家哪里有事发生,并可控制每张地图上的门。

  • 物体

    通过脚本或游戏内编辑器放置、移动和删除地图物体(每个服务器最多 5,000 个)。

  • 涂鸦

    创建可喷涂的墙面,锁定或重置它们,并对每一层完成做出响应。

  • 回合与模式

    开始、结束和中止回合——或者在自由模式、死斗和角色扮演中完全不用回合。

  • 屏幕界面

    文字、面板、进度条、图片、大字公告、编号菜单和文本输入框。

  • 窗口与点击

    可点击的绘制元素、标签、物品图片,以及用于自定义窗口的自由光标。

  • 图标与区域

    在每位玩家的地图上显示图标和彩色区域。

  • 存档数据

    每个资源独立的键值存储,服务器重启后依然保留。

  • 密码与封禁

    为服务器账号提供加盐且刻意放慢的密码哈希,并支持按 ID 和 IP 封禁、可设时长。

客户端脚本

客户端脚本负责每位玩家自己的东西:HUD、菜单、按键绑定、本地聊天命令、镜头和音效。每个资源都在玩家电脑上各自的沙箱中运行。

它们可以读取战斗状态,但永远不能修改——否则每台电脑看到的都会不一样,作弊也会变得轻而易举。要改变什么,客户端脚本会向服务器请求,由服务器决定。

player-hud/client/hud.luau
-- client/hud.luau
setInterval(function()
  local me = fighters.get(localPlayer.fighter() or -1)
  if me then
    ui.text("hp", "Health " .. math.floor(me.health), { position = "bottom-right" })
  end
end, 200)

on("keyDown", function(key)
  if key == "F3" then
    emitServer("askStats")   -- handled on the server with onClient("askStats", ...)
  end
end)

沙箱与限制

  • 无外部访问

    脚本无法访问文件、网络或操作系统,也无法替换 API 函数。

  • 单次运行 250 毫秒

    一次运行时间过长的脚本会被终止——死循环无法卡死服务器。

  • 每个资源 64 MB

    每个资源都有独立的内存配额。

  • 错误被隔离

    错误会连同资源名一起写入服务器日志;资源会继续运行。

编辑器支持:SDK 附带服务器和客户端 API 的类型定义。把它们添加到 luau-lsp (在新标签页中打开)(例如通过 VS Code 的 Luau 扩展),即可获得自动补全和类型检查。

内置模板

每个服务器都自带以下资源。它们对游戏来说没有任何特殊之处——你自己的资源可以做到同样甚至更多的事。

welcome
欢迎玩家,并用存档数据统计他们的访问次数。
basic-commands
/players 以及定期在聊天中显示的提示。
player-hud
客户端脚本:HUD,按 F2 隐藏,按 F3 向服务器查询你的战绩。
scoreboard
击倒排行表、大字显示的回合数以及 /stats 菜单。
fight-basics
播报击倒和回合胜者,另附 /heal 和 /where。
deathmatch
无回合模式:复活、击倒播报,率先达到 10 次者获胜。
roleplay
账号、角色、保存位置、医院,以及连接各街区的地铁。
roleplay-chat
本地聊天、/me、/do、/shout、/ooc 等。
mapvote
每场比赛结束时投票选择下一张地图。
mapping
地图物体以及游戏内摆放编辑器。
admin
管理员工具,例如在地图上自由飞行。

运行服务器

想快速开一局,就在游戏菜单中开服;或者在游戏文件夹中用 CreateServer.bat 生成专用服务器包。它会询问目标系统(Windows 或 Linux)和地图,然后创建一个包含服务器程序、数据、你的资源、servidor.cfg 和 SDK 文档的文件夹。

  • Linux:Ubuntu 24.04+ 或 Debian 12+,64 位,并安装 ALSA 和 udev 库。
  • 端口:游戏使用 UDP 27015,服务器搜索使用 UDP 27016(或你配置的端口及其下一个端口)。
  • 更新:有新版本时,服务器会在启动时提醒你。更新游戏、重新生成服务器包,并替换程序和数据——你的配置和资源会保留。
  • 私有数据:服务器包中的 data/ 文件夹由你自己的原版游戏生成。切勿公开分享。

了解更多开服信息

完整参考

完整的 API 参考——每个函数、事件和选项——都随每个服务器包附带在 sdk/README.md 中,编辑器类型定义则位于 sdk/types/。它始终与你正在运行的版本一致。