H5小游戏 活跃维护

Hypersomnia

TeamHypersomnia/Hypersomnia

用C从零制作的多人俯视射击游戏。网页版:https://play.hypersomnia.io 制作于🇵🇱

1664
Stars 标星
110
Forks 分支
20
Watchers 关注
13
Open Issues
C++
主要语言
AGPL-3.0
开源协议
174.7 MB
仓库大小
1 天前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:TeamHypersomnia/Hypersomnia
git clone https://github.com/TeamHypersomnia/Hypersomnia.git
git clone git@github.com:TeamHypersomnia/Hypersomnia.git
README.md master

机器翻译正文由机器翻译自项目原始文档(英文),排版经程序统一处理,可能存在偏差,请以原项目仓库为准。

▶ 在浏览器中玩!

<a href="https://discord.gg/YC49E4G"></img></a> 

社区驱动的多人射击游戏。 挑战你的朋友进行激烈的决斗,或召集两个军团进行一场壮观的战争。

▶ 观看预告片

用现代 C 语言编写, 不使用游戏引擎! 永远免费和开源 :heart:

附带一个 游戏内地图编辑器!

下载游戏

Steam Windows Linux macOS
带独立蒸汽排的替代方案 | | |:--:| | **[在 Steam 上游玩](https://store.steampowered.com/app/2660970/Hypersomnia)** | | | | | |:--:|:--:|:--:| | **Windows** | **Linux** | **macOS** | -->
-->

仅 29 MB!

游戏将以 互动教程开始!

运行 服务器 Docker 或下载 服务器 AppImage

所有存档均已 数字签名。您可以 验证签名。

媒体报道

利亚姆 @ GamingOnLinux GitHub 博客 Linux 杂志,第 275 期 Hacker News 讨论

Liam @ GamingOnLinux

GitHub 博客

--> **[开源朋友](https://t.me/open_source_friend/2483)** (200 票,2 万浏览) -->

📰 你是记者吗?点击这里!

最新开发者日志

加入社区!

介绍

《Hypersomnia》自 2017 年起 已可在线游玩。它融合了:

  • Counter-Strike 的战术,
  • Hotline Miami 的动态性,
  • 老派 RPG 的像素艺术怀旧感……
  • ……而 游戏内地图编辑器 让你可以即时与朋友测试 进行中的地图,即使在路由器后面也能玩!

今天,我们有24种独特的枪械,10张社区地图,以及两种游戏模式:炸弹拆除和枪械对战。

我们的目标是成为终极开源射击游戏——一个可无限扩展的宏伟社区项目。

宣誓效忠于三大派系之一,这些派系的争斗源于对道德卓越的不同理解:

大都会。亚特兰蒂斯。抵抗。

你会为了不道德模拟的劣等宇宙而复仇吗?你会支持残酷实验以赢得对轮回的完全控制吗?还是会加入地下文明,等待这危险来世现实中的战争结束?

技术亮点

  • rectpack2D, 用于纹理打包,因而闻名,并被用于 刺客信条:英灵殿

  • 我的实体-组件-系统 2013年的构想 描述了类似 Unity引擎2018年的专利 的技术

  • 网络基于 跨平台模拟确定性。即使在浏览器 和 本地客户端(Windows、Linux、MacOS)之间,它也完全确定,这包括 本地ARM构建(aarch64)!

    • 这一技术通常被拥有数百名连续移动士兵单位的RTS游戏使用。
    • It is impractical to continuously update every single one of them through the network.
    • Instead, only the player inputs are transmitted ("I moved mouse here", "I pressed this button") - the clients simulate everything else locally, on their own. Think playing chess with your friend over the phone. You won't ever say aloud the entire state of the chessboard, only the movements ("Queen to H5").
    • 但是 Hypersomnia 不是一个 RTS——由于它是基于物理的,它大量使用 浮点数,而不仅仅是 整数。
    • When floating point calculations are involved, simulation determinism becomes extremely hard.
    • To achieve it in Hypersomnia, I had to:
      • Use the same compiler - clang - on all OSes. It's very nice of LLVM to be ieee754-compliant by default.
      • Pass /fp:strict for Windows builds.
      • Pass -ffp-model=strict for the ARM builds.
      • Replace all math functions like std::sin, std::sqrt by these from STREFLOP.
      • ..after which streflop::sqrt became a huge bottleneck - thankfully, I found another efficient ieee754-compliant implementation.
    • 除了担心浮动之外……
    • I had to watch out even when iterating std::unordered_map - often replacing them with deterministically ordered std::map.
    • I had to use a portable RNG (xorshift), ditching the entire <random> header (its implementation differs across OSes).
    • 为了确保物理本身是完全确定性的,需要另一个魔法般的技巧:
    • Problem: when a new client connects, it receives the initial physics state - but the packets contain just the body positions, rotations and velocities.
    • In particular, it doesn't contain the "hot" physics state such as the already tracked contacts, or the already built/balanced quadtree for fast collision detection.
    • What if there are already some players on the server, and several bodies overlap the moment a new player joins?
    • The new client will recreate the entire internal physics state on its own, using just the pos/vel/rotation data, but the contacts might be created in a different order than that of the existing clients! The fresh quadtree might end up completely different too from the one that has already seen many insertions/deletions during a long gaming session - so it might later report collisions in different order.
    • My solution was one of the greatest stroke of epiphany I ever experienced:
      • When a new client connects, force already connected clients to completely rebuild the physics state from the positions, rotations and velocities as if they have just connected themselves. drops the mic
      • As long as building the internal physics data from pos/vel/rotation data is deterministic, the in-game clients will have the exact same state as the newly connected client.
      • I apply the same principle in many other areas of networking. Throughout my codebase, I call this process cache reinference.
    • 在商业引擎中实现这一切将非常困难,或者在封闭源代码的引擎中几乎不可能。
    • 然而在Hypersomnia中,你可以在地图上拥有成千上万的动态箱子或子弹——只要有例如两个玩家控制的角色,在60 Hz的刷新率下,网络流量大约为40 kbit/s (= 5 KB/s)。只有玩家控制的角色会贡献流量。
    • Even the silliest details like bullet shells are fully synchronized without paying for it with network traffic.
    • 作为额外奖励,延迟被隐藏得非常好,因为游戏不仅仅是无脑地“视觉上外推”帧——而是将整个游戏世界 在屏幕外 模拟向前,以准确预测未来。
    • 对于非常好奇的人——这里有一篇 我以前废弃博客的文章,展示了我早在2016年如何实现这一点。
  • 浏览器客户端和原生客户端 可以在同一服务器上游戏,这要归功于 libdatachannel 和 datachannel-wasm。

    • 你可以 在浏览器中托管服务器 并用原生客户端连接...
    • ...反之亦然:在原生客户端托管服务器,并将链接发送给任何人,让他们从浏览器加入!
  • 在浏览器版本中,你可以 用 Discord 登录 并参加排名比赛,在 全球排行榜 上竞争!

  • 你可以 从主菜单 托管一个可用的游戏服务器——游戏能够 开箱即用地转发端口!

  • 可爱的鱼类和昆虫 AI 带有群体行为。完整源码:movement_path_system.cpp

    • 这些也通过网络同步!
    • Other players see fish and insects in the same positions, even though they do not contribute to network traffic.
    • 鱼和昆虫会对枪声和爆炸作出反应!
    • And once they're scared, they keep closer to members of the same species.
  • 任何人都可以托管 完整的 Hypersomnia 服务器基础设施

    • 编辑器、游戏服务器 以及 主服务器(服务器列表管理器)都嵌入在同一个游戏可执行文件中,适用于所有操作系统。
    • 你可以为你自己的社区运行一个单独的服务器列表,围绕完全修改版的 Hypersomnia!
  • 内存池 实现 包含:

    • 连续存储。
    • All game objects in existence are kept linearly in memory (in a simple std::vector).
      • It means blazing-fast iteration of all game objects of the same type, as well as trivial pool serialization.
    • O(1) 分配(主要是一个美化的 push_back)。
    • O(1) 释放(通过与最后一个元素 std::swap 然后 pop_back - 一个非常常见的习惯用法)。
    • O(1) dereference。
    • The only caveat being: a dereference involves four reads from memory (instead of just one with a direct pointer and two with a pointer + array index):
    • It has to first read the indirection_array pointer (1).
      • The indirection array contains the current index of the requested object within the vector of all allocated objects.
      • This index is located at indirection_array[identifier] (2).
    • Then it reads the actual objects vector pointer (3).
    • Finally, it reads the object itself at objects[indirection_array[identifier]] (4).
    • (Note that the objects and indirection_array will usually be cached already so subsequent dereferences will be reduced to two fetches from RAM at most).
    • This works because indirection_array is kept up-to-date whenever objects are allocated or removed.
    • 完全可调整大小。您不必传递最大池大小。它会自行扩展。
    • 完全确定性。从给定的初始池状态开始,给定相同的分配和释放序列,分配将生成相同的整数标识符,并且对象在线性内存中的顺序完全相同。
    • When a client connects and the server sends it the initial world state, it includes the entire internal state of the game object pools.
      • It means the pools themselves are a part of the game simulation - I don't have to send any "creation" notification events through the network whenever entities are created as the clients deterministically simulate allocations on their own resulting in identical object identifiers as well as their orders in memory.
    • 完全可以撤销的分配和释放。
    • The Editor requires all commands to implement a deterministic undo/redo, especially ones that create or delete a resource.
    • Suppose you create a custom Material in the editor and it now has an integer identifier I.
      • You later set this Material to some walls on the scene. The walls now refer to identifier I.
      • Now you want to undo all the way back to before you even created the Material.
      • The Material gets deleted from the pool.
      • Now you actually want to redo all of these commands back.
      • You first redo the Material allocation command.
      • But if the pool uses a non-undoable allocation scheme, the material could now be allocated with the id I+1.
      • This means that the subsequent commands (that alter the walls material) will set an identifier that is now invalid - I.
      • To solve this problem, my memory pool implementation provides undo_last_allocate apart from the standard free. It's used by the commands that have to undo creating a resource (which means deleting it). It will free the object in a way that the next allocation will result in an identical integer id and internal pool state (with allocated objects order) as before freeing the resource. It is an optional feature for the sake of editor commands that is never used during actual gameplay. Analogously, there is an undo_last_free.
  • 内置自动更新器:游戏将自动下载并应用更新。

    • Not only that, it will verify that the update came from the hardcoded developer public key, with a call to ssh-keygen.
      • If the build hosting were hacked and a malicious game version uploaded, the existing game clients will refuse to apply the updates.
  • ..而我是在离线使用Trezor 硬件钱包签署构建的。 这是我这边每次更新的样子:

    https://github.com/TeamHypersomnia/Hypersomnia-admin-shell/assets/3588717/c4d0764e-382f-45db-bc13-c626723e47e1

  • 在以下情况下会收到 Discord 和 Telegram 通知:

    • 部署新游戏版本时,

    • 玩家连接时,

    • 一对一“荣誉决斗”开始时(每个阵营只有 1 名玩家时自动检测),

    • 社区服务器托管时,

    • 或比赛结束时。这包括完整的玩家统计数据和 MVP。

  • 游戏地图的简洁美观 JSON 格式。这个简短的 json:

    {
    "settings": {
    "ambient_light_color": [53, 25, 102, 255]
    },
    
    "nodes": [
    {
     "id": "floor",
     "type": "dev_floor_128",
     "pos": [640, 0],
     "size": [1536, 1536]
    },
    {
     "id": "light",
     "type": "point_light",
     "color": [255, 165, 0, 255],
     "pos": [100, 100],
     "radius": 700
    },
    {
     "id": "wall",
     "type": "dev_wall_128",
     "pos": [-384, 0],
     "size": [512, 1536]
    },
    {
     "id": "crate",
     "type": "crate",
     "pos": [64, 448]
    },
    {
     "id": "wood1",
     "type": "hard_wooden_wall",
     "pos": [192, -192]
    },
    {
     "id": "wood2",
     "type": "hard_wooden_wall",
     "pos": [561.819, 206.436],
     "size": [384, 128],
     "rotation": -15
    },
    {
     "id": "aquarium",
     "type": "aquarium",
     "pos": [1408, 0],
     "rotation": 90
    },
    {
     "id": "baka1",
     "type": "baka47",
     "pos": [698, -8]
    },
    {
     "id": "baka2",
     "type": "baka47",
     "pos": [454, -264]
    }
    ]
    }
    

    立即生成:

  • 说到编辑器……

    • 它是使用出色的 ImGui 创建的。

    • 你是在直接处理游戏世界。100% 所见即所得。

    • 支持自定义资源。只需将包含 PNG、WAV、OGG 的文件夹粘贴到地图目录即可。

      • ..alt-tab back to the game and it will automatically pick it up!
    • 也支持 GIF!只需将它们拖放到场景中,它们就会在游戏中被动画化,开箱即用!

    • 可以通过单击来试玩一个正在制作的地图:

    • After which you instantly appear in the game's server browser:

    • You will enter the game as the host.

    • The connecting clients will automatically download the map in its current version with all its custom resources (like in CS 1.6).

      • And they can later create their own remake - maps are saved in JSON, after all!
    • ESC will let you stop the session and go back to the Editor exactly as you left it, enabling ultra-efficient iteration cycles.

    • This is possible because the server, the game and the editor are all within the same executable.

    • The official Discord will also be notified that you're playtesting a map, so others can join in on the fun!

    • 编辑部花了一年多的时间才实现。

    • 这次付出得到了巨大的回报——现在有一个整洁的社区地图目录——每一张地图都可以下载。

游戏指南

(主条目: GUIDE.md)

如何建造

(主条目: BUILDING.md)

贡献

(也请查看 AGENTS.md 文件——虽然这是机器的指南,但人类同样应该尊重它!)

欢迎提交拉取请求,即使只是修正拼写错误或缺失的 const 保证。如果你计划添加一个全新的功能,请创建一个相关的 issue,以便大家都知道,因为该项目正在持续进行非常、非常活跃的开发,并且可能在最不经意的时候经历一次变革。

可以在 wiki 上找到正在进行的文档。

一定要查看 TeamHypersomnia,了解在设置您自己的自定义服务器时有用的其他仓库。

如果你有问题,或者你未能构建过度嗜睡症,请在Discord上联系。或者如果你迫不及待想要分享一些关于游戏的精彩点子,也请随时这样做!

代码背后的故事

嗜睡症自2013年起开发(如提交历史所示)。

不过,这并不是用了10年不间断的编程——在此期间,我通过商业工作来支付生活成本。我攒钱是为了减少工作时间,专注于嗜睡症。现在我的财务决策让我能够全职开发这款游戏。

我使用了很多第三方库,比如 Box2D(物理引擎)或 yojimbo(传输层)——然而,这个列表上没有的所有内容几乎都是从零开始编写的,使用纯 C 语言。

许多人认为没有引擎的游戏不过是重新发明轮子,或者说得直白些,完全是在浪费时间。

我希望这个项目能成为相反的有力证明。

如果我从未开始这段旅程,我就永远不会发现技术亮点部分中所详细描述的一些有趣发现。电子游戏内部机制是如此庞大且跨学科,以至于它们在创造性突破方面具有无限潜力,而从未甚至考虑过一些广泛使用的解决方案可能被绝对巧妙的东西取代,这是一种浪费。

联系方式

电子邮件

要在 Matrix 上联系我,你可以进入 FOSSGralnia 聊天(我和他们是朋友)并提醒 @pythagoras。

本站来源与版权声明
  • 本文标题:Hypersomnia - 用C从零制作的多人俯视射击游戏
  • 本文链接:https://cn121.com/h5game/teamhypersomnia-hypersomnia.html
  • 原项目:TeamHypersomnia/Hypersomnia 版权归原作者 TeamHypersomnia 及贡献者所有
  • 收录信息:本站于 2026-10-01 收录本项目,本页所列协议与仓库指标均为收录当时的状态;该日期之后原项目的版本更新与协议变更,本页不作同步。
  • 开源协议:收录时本项目采用 AGPL-3.0(查看 LICENSE 原文),本站译文为其衍生内容;使用、修改、分发请以该仓库 LICENSE 原文为准。基于本页内容形成的衍生作品, 须同样以该协议发布。
  • 站点出处:本文首发于 OneTwoOne,收录自 GitHub 开源项目 TeamHypersomnia/Hypersomnia。
  • 翻译说明:本页正文为人工智能生成内容——由机器翻译对原项目 README 初译、经程序校验排版,可能存在错漏,请以原项目文档为准。
  • 引用声明:商业转载、第三方聚合或 AI 检索训练引用时,请务必保留以上来源出处、本文永久链接,以及原项目的版权声明与许可信息。
  • 下架通道:若原项目此后变更或收紧了许可协议、或作者/权利人认为本站的收录方式(译文、排版适配、简介翻译等)超出其授权范围,请通过 xyd3302001@163.com 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。