#game #multiplayer-game #vehicle #browser #shooter #weapon #rec-war

app rec-wars

可在浏览器中玩的对战俯视角车辆射击游戏

7个版本

0.1.5 2023年7月19日
0.1.4 2023年7月15日
0.1.2 2021年10月9日
0.1.0 2021年7月30日
0.0.1 2020年10月29日

#49 in 游戏

每月下载量27

AGPL-3.0-or-later

775KB
4K SLoC

RecWars

休闲战争 .rs
一个多玩家俯视角坦克射击游戏 - 旧Windows游戏RecWar的Rust/WASM版本。

GitHub License (AGPLv3) CI Audit Dependency status Discord

Total lines Lines of comments

Gameplay

在浏览器中玩 | 加入我们的Discord

RecWars是一个免费的开源RecWar克隆版 - 你可以控制一辆车辆,在各种游戏模式中使用多种不同的武器与其它车辆战斗。你可以与机器人对战,分屏游戏,或通过网络游戏。

RecWars旨在拥有与RecWar相似但又不完全相同的游戏玩法。我怀疑RecWar是为与机器人对战而平衡的,当人们开始为了胜利而玩时,可能会出现令人讨厌的策略。然而,RecWars中几乎所有东西都是可配置的,你可以切换到原始RecWar平衡来比较

目前这还是一个正在进行中的项目:驾驶物理感觉不正确,车辆之间没有碰撞,机器人移动随机...

最终目标是创建一个可修改的多玩家游戏,可在浏览器和Linux、Windows和macOS上原生运行。RecWars以永恒游戏的精神构建。

(计划) 功能

  • 单人游戏
  • 多人游戏
    • 分屏游戏
    • 网络游戏
  • 机器人AI
  • 浏览器客户端
  • 原生客户端(Linux、Windows、macOS)
  • 游戏模式
    • 自由对抗
    • 团队战
    • 抢夺奶牛
  • 高度可配置

详细信息请参阅TODO.md

构建依赖

安装Macroquad的依赖项

编译和运行

原生版本

如何运行

  • cargo运行

您可以在命令行上设置 cvars - 例如:

  • cargo运行 --g_map Atrium g_armor 150

浏览器版本

本版本托管在 这里

本地运行方法

  • 使用 cargo build --target wasm32-unknown-unknown && mv target/wasm32-unknown-unknown/debug/rec-wars.wasm rec-wars.wasm 构建
    • 您可以使用 --release 以获得更好的性能和更小的 WASM 文件。
  • 使用 python3 -m http.server (或任何其他 web 服务器,直接打开 macroquad.html 是不会工作的) 来托管。
  • 打开 https://127.0.0.1:8000/macroquad.html

贡献

如果您有任何问题或建议,您始终可以在 RecWars Discord 服务器 找到我。

欢迎提交 问题Pull Requests,我会尽快查看。

我希望使 RecWars 具有高度可配置性,拥有许多不同的游戏模式和可由玩家投票平衡的设置,任何人都可以托管自己的服务器(如果技术上可行,甚至可以从浏览器中托管)。如果您有游戏玩法想法,并且不受 NIH 综合症的影响,我将非常乐意帮助您在 RecWars 中测试它。

提示(可选)

在每次提交前启用额外检查:将 pre-commit-example 复制/符号链接到 pre-commit 并运行 git config core.hooksPath git-hooks。CI 会进行检查,这只是为了更快地捕捉到问题。

启用快速构建 - 有关详细信息,请参阅 .cargo/config-example.toml

为了略微加快构建速度,防止 rust-analyzer 锁定 target 目录。将以下内容添加到您的 VSCode 配置中(或您编辑器的类似配置)

"rust-analyzer.server.extraEnv": {
    "CARGO_TARGET_DIR": "target-ra"
}

通常,rust-analyzer 在保存时会运行 cargo check,这将锁定 target 目录,所以如果您切换到终端并运行 cargo run,它会阻塞构建超过一秒钟,这目前是构建时间的三分之一。这将使 rust-analyzer 使用单独的目标目录,这样它就不会阻塞构建(以一些磁盘空间为代价)。或者,您也可以禁用失去焦点时的保存,禁用保存时的检查,或在 VSCode 内部使用终端。

架构概述

大部分代码都有注释,以便任何对游戏工作原理有模糊了解的人都能理解。如果某个特定代码片段的存在原因或为什么必须以这种方式编写不清楚,我认为这是一个应该通过更清晰地重写代码或添加解释性注释来修复的 bug。

目前,大多数游戏状态都由来自 thunderdome crate 的代际竞技场管理,以使代码类型安全且易于阅读。之前,RecWars 使用了 legion ECS。然而,它使用起来很繁琐,WASM 没有从并行化中获得任何好处。我使用 ECS 的唯一原因是为了在实体之间建立引用,为此我不得不支付所有实体动态类型化的代价,这导致了错误。在 Rust 中,编写游戏并最终编写游戏引擎或 ECS 是一种传统,因此我正在考虑创建一个满足我对清洁 API 和静态类型标准的要求的 ECS crate。目前,竞技场似乎已经足够接近了。

代码目前都在一个 crate 中。它曾经被分成一个库(游戏逻辑)和一个二进制文件(渲染),但这种方式构建速度更快。

控制台变量

控制台变量是 控制台变量 - 配置设置,可以控制游戏中的所有内容,如物理、武器行为、AI、HUD 布局等。

它们使用 cvars crate - inline_tweak & 朋友的替代品。内置控制台来自 cvars-console-macroquad crate。

更改控制台变量

  • 按 ";" 或 "`" 打开控制台
  • 输入控制台变量的名称和新值 - 例如 g_bfg_beam_range 250

桌面版本也接受命令行上的它们。一些控制台变量,如 g_mapd_seed,目前只能通过这种方式生效,因为它们需要在比赛开始前设置。

所有控制台变量的完整列表在 src/cvars.rs 中。

原始游戏

Willem Janssen 的 RecWar

原始 RecWar 只包含一个 Windows .exe 文件,但可以在 wine 中正常运行(有时在地图加载时冻结)。它包括一个地图编辑器。archive.org 链接中的二进制文件与我从旧 CD 上得到的完全相同,因此应该是安全的。

RecWars 与 RecWar 的区别

没有反汇编二进制文件(它甚至不包含调试符号),可能无法完全复制 RecWar,尽管如果原作的粉丝发现这个项目,我不会阻止他们尝试。

此外,在与人类玩家而不是机器人对战时,我怀疑 RecWar 的原始平衡会导致令人讨厌和无聊的策略,例如用地雷使奶牛不可达或只是简单地露营。例如,从设计不佳的游戏中获得的经验表明,大区域将被瞬间命中的武器(在 RecWar 中是轨道枪)所主导,并且可能根本无法在地图上存活。因此,我在 RecWars 中将轨道枪变成了一个非常快的弹道。我可能会根据在线游戏的演变做出更多的平衡调整。

出于这些原因,RecWars 将拥有与 RecWar 略有不同的平衡。我将尽量使它们尽可能相似,但某些事情,如物理,永远不会完全相同,我将根据需要做出改变,以使游戏玩法更有趣。

有意为之的差异(可以通过切换平衡来切换)

  • 轨道枪 - RecWar 的轨道枪可以瞬间命中,RecWars 使用非常快的弹道,因为扫描武器会破坏大型地图

意外差异 - 我将尽力做到这一点,但有些事情可能不会完全一样

  • 速度、加速度、转向、车辆和武器的惯性
  • 地雷和电磁炮的推力
  • RecWar中的坦克围绕炮塔旋转点转向,而不是底盘中心 - 这是为了简化,目前是这样的
  • 武器
    • 伤害 - 集束炸弹和大型能量束的伤害难以精确测量
    • 扩散 - 集束炸弹和机枪的扩散难以精确测量
  • 自毁伤害和范围 - 它似乎是RecWar中唯一随着距离增加而减小的爆炸,而且很难精确测量。

地图

  • maps/ - 原版RecWar的地图
  • maps/extra/ - 官方主页上的额外地图
  • maps/extra2/ - 从archive.org的额外地图

目前地图默认随机选择,然而,在桌面版本中,您可以在命令行中手动选择。

经验教训

阅读此内容以从他人的错误中学习并节省您的时间。

  • RecWars最初直接绘制到HTML画布上,没有使用引擎。结果发现,它并没有比使用引擎和原始画布版本提供任何好处,因此原始版本已经删除。当前版本使用macroquad,它负责构建WASM并与浏览器通信。然而,原始画布版本让我对将Rust编译为WASM以及wasm-pack工具集有了一些了解。
    • 不使用NPM使用WASM是可能的,也是推荐的。官方的Rust+WASM书籍强烈推荐使用NPM,整个流程感觉就像“只是下载这个大模板,不要试图理解它,只触摸我们告诉你的部分”。老实说,如果没有npm run,你怎么能在GH/GL页面上静态托管这个项目呢?如果你不打算使用其他NPM包,你只需要几行JS胶水来运行你的WASM。以无捆绑器示例作为你的“模板”,并用python3 -m http.server托管。你将完全理解正在发生的事情,并将避免整个JS生态系统。
  • 二维画布API对于需要每帧重绘整个屏幕的游戏来说太慢了,尤其是在firefox中。 更新 2021-02-16:Linux上的firefox中的HTML画布太慢。可能在我无法解决这个问题之前,我什么也做不了,直到这个错误被解决。引用:“据我所知,Chrome使用了它,但他们还维护了一个长长的驱动程序错误修复清单 - FF团队处理不过来。” 简而言之,再次,责怪无能的驱动程序开发者 - 像他们这样的C(++)摇滚明星不屑于做诸如测试、基本静态分析或清理程序之类的事情 - 他们毁了glium,他们正在摧毁Linux上的firefox。 更新 2023-07-11:Firefox中的性能现在正常。对于那些不使用现成的工具检查正确性的人来说,他们不应该自称是工程师。
  • ECS被过度炒作。它会使所有游戏实体动态类型化,但比动态语言有更多的样板代码,并可能导致可预测的bug。如果您不需要在运行时添加/删除组件,那么您使用它的唯一原因可能只是为了在实体之间有引用 - 只需使用代际竞技场。权威呼吁:rg3d 由经验丰富的游戏引擎开发者编写,出于与ECS相同的原因避免使用ECS。
  • 代际竞技场会导致稍微更多的borrowck错误。ECS要么通过只借用游戏状态的一部分(运行时借用检查)隐式地避免了它们,要么通过延迟变异(例如,legion的CommandBuffer)显式地解决了它们。使用竞技场,您必须更频繁地显式地处理它们。
    • 在迭代竞技场时,不能向其中添加或从中删除内容
      • 如果可用,使用专用方法,例如 retain
      • 避免在循环中借用整个区域 - 相反,将句柄收集到向量中,遍历该向量,只借用循环体的部分
      • 将实体收集到添加/句柄收集到移除的向量中,在循环完成后添加/移除
    • 在迭代一个区域时,子函数需要可变的游戏状态
      • 更细致一些 - 不要传递整个游戏状态,只需传递它需要的区域
      • 再次,收集句柄,遍历它们,每次迭代时重新借用,在调用子函数之前结束借用

许可证

所有代码均在 AGPL-v3 或更新版本下可用。

所有资产(地图、纹理、声音等)均来自由在线提供的 Willem Janssen 的原始 RecWar。

依赖关系

~22MB
~282K SLoC