10 月:Alpha 版本发布!

我们自豪地宣布……
……Alpha 版本更新的巨长列表!
初步想法
感谢大家在上个月给予的所有支持!我们的社区已经壮大了许多,看到它变得如此美好和友善真是太棒了 🥰!
周日的游戏测试活动非常精彩!我们得以很好地测试游戏的稳定性。可以说,我们遇到的大部分崩溃都与外部集成问题(WebUI 或虚幻引擎本身)有关,这展示了我们核心系统极高的成熟度。我想以后可以更频繁地举办这种活动,玩万圣节模式以及测试社区的游戏模式真的充满了乐趣!
从现在开始,所有更新都将开始引入版本控制(终于!),小更新/非破坏性更改将获得 PATCH 版本号,而破坏性更改将获得 MINOR 版本号。
以下更新日志包含了自上次官方宣布的 0.73.0 版本以来的所有功能。接下来的许多项目其实此前已经包含在 bleeding-edge 分支中了。
材质

现在 nanos world 支持材质资产了! 🎨
这意味着你可以在你的 Assets.toml 中配置自己的材质,并通过 Paintable 方法来引用它们!
函数 :SetDefaultMaterial() 已被替换为 :SetMaterial()。你可以在此处查看所有开箱即用的内置材质列表。
此外,现在还可以获取 WebUI 材质并将其应用到任何表面上(详情见下文)!
由于这一改动,一些现有的方法正在进行重构,例如可拾取物获得了一个新方法 :SetCrosshairMaterial(),因此你可以从材质中设置准星(而不再是通过预定义的列表),同时,所有旧的准星都已转换为材质,你可以在此处找到它们。
改进的 WebUI

WebUI 迎来了多项改进,包括运行 HTML5 音频和视频的能力! 📽
我们使用的是 Ultralight 的 Beta 版本,该版本支持音频和视频,因此必然会发生崩溃,此外音频目前仅支持 2D。 Ultralight 官方正在研究解决方案,以便我后续能实现 3D 音频。
WebUI 构造函数加入了几个新参数:is_transparent、auto_resize、width 和 height。宽和高仅在自动调整大小为 OFF 时使用,如果你想生成一个 WebUI 并将其作为材质应用到任何表面上(并且不希望它是整个屏幕的大小),这将非常有用。
此外,它还新增了以下方法::SetFreeze()、:Resize() 和 :SetAutoResize()。
引入了全新的搜索器,改进了加载 .html 文件的方式,现在会按照以下顺序进行查找:
- 相对于
current-file-path/ - 相对于
current-package/Client/ - 相对于
current-package/ - 相对于
Packages/
现在可以从 WebUI 生成材质,它会自动动态地渲染到任何表面上::SetMaterialFromWebUI()(该方法属于 Actor)。
Actor
Actor 的新内容:
- 为所有 Actor 添加了新方法::SetLifeSpan(time),它将在
time秒后自动销毁该 Actor。 - 为所有 Actor 添加了新方法::IsBeingDestroyed(),用于返回该 Actor 是否正在被销毁(非常适合在
Drop或Ungrab等其他事件内部进行检查)。 - 为所有 Actor 的 :AttachTo() 方法添加了新参数:
lifespan_when_detached,它将在 Actor 解除连接time秒后将其销毁。 - 现在事件 TakeDamage 拥有一个新参数:
causer(造成伤害的对象/Actor)。还添加了新的伤害类型:RunOverVehicle和RunOverProp。 - 现在事件 Hit 拥有新参数:
impact_force、normal_impulse、impact_location和velocity。 - 现在 :SetLocation() 将尝试寻找更好的位置传送 Actor(以避免碰撞)。
Character

Character 的新增内容:
Character 方法的新增与改进:
- 添加了若干个用于获取其属性的新 Getter。
- 添加了 :SetDamageMultiplier(),根据受损的骨骼更改伤害乘数。
- 添加了 :SetHiddenBone(),用以隐藏身体的任意部位。
- 添加了 :SetJumpZVelocity(),使角色跳得更高。
- 改进了 :PlayAnimation(),获得了新参数(混合时间、循环和播放速率),现在支持加载任何类型的动画(Montage 或 Sequence)。
- 移除了
:SetInitialLocation(),它已被替换为 :Respawn()。
Character 事件的新增与改进:
- 添加了 AttemptEnterVehicle,在角色尝试进入载具时调用,返回 false 可阻止该行为。
- 添加了 AttemptLeaveVehicle,在角色尝试离开载具时调用,返回 false 可阻止该行为。
- 添加了 AttemptReload,在角色尝试重新装填武器时调用,返回 false 可阻止该行为。
- 添加了 Interact,在角色尝试拾取可拾取物或抓取道具时调用。
- 添加了 Highlight,在角色看向可以拾取的道具或可拾取物时调用。
默认资产包中的部分 Character 动画已从 AM_ 重命名为 A_(因为它们不再是蒙太奇 Montage)。此外还添加了大量新的动画。
武器

Weapon 的新增内容:
Weapon 方法的新增与改进:
- 添加了若干个用于获取其属性的新 Getter。
- 添加了 :SetRecoil(),用以设置武器的物理后坐力大小。
- 添加了 :SetWallbangSettings(),配置子弹是否可以穿透墙壁。
- 添加了 :SetAnimationFire(),用以设置开火时武器骨骼的动画。
- 添加了 :SetSoundFireLastBullets(),用以设置弹夹中仅剩最后
N发子弹时的开火音效。 - 改进了 :SetAnimationReload(),现在包含
play_rate参数。
其他新增内容:
- 现在当角色在驾驶时,武器会被隐藏。
- 为内置的弹壳粒子添加了弹壳掉落和落地的音效(这是程序生成的、100% 精确的声音 😉)。
- 添加了拾取或丢下武器时的音效,并且在丢下武器时会将其稍微向前抛出。
手榴弹

Grenade 的所有属性均已被弃用,现在必须通过方法进行访问。
我们为手榴弹添加了一个特殊粒子 nanos-world::P_Grenade_Special,它会根据手榴弹所处的地面爆炸出不同的粒子效果。也就是说,如果手榴弹在草地表面,它会爆炸出“草地爆炸”粒子;如果在水下,则会爆炸出“水下爆炸”粒子。注: 该粒子仅对手榴弹生效。
声音

Sound 的新增内容:
现在可以在运行时加载 .ogg 声音了!你可以将它们存储在任何包或资产包中,并使用我们新的 SpecialPath 模式(assets://asset-pack-name/path.ogg 或 package://package-name/path.ogg)进行加载。
向构造函数添加了 loop_mode 参数(现在可以永久循环播放任何声音)。
此外,还可以在任何 Sound 参数中使用 SpecialPath 传入 .ogg。
Sound 方法的新增与改进:
- 添加了 :GetDuration()。
- 改进了 :FadeIn() 和 :FadeOut() 的参数。
Input

添加了新类:Input!
现在你可以用正确的方式来控制、创建和自定义按键绑定了!示例:
-- 注册绑定名称 'SpawnMenu',默认按键为 'Q'
-- 这将自动把 'SpawnMenu' 添加到用户的按键绑定设置中
Input.Register("SpawnMenu", "Q")
-- 订阅按键按下事件
Input.Bind("SpawnMenu", InputEvent.Pressed, function()
-- 打开生成菜单
end)
-- 订阅按键释放事件
Input.Bind("SpawnMenu", InputEvent.Released, function()
-- 关闭生成菜单
end)
HTTP

添加了新类:HTTP!
现在我们有了一个专门用于发送 HTTP 请求的独立类。它还支持异步 HTTP 请求(并且是线程安全的!)
性能优化

我们在 Alpha 版本更新中对性能技术进行了大量的钻研。以下是本次更新的亮点:
- 现在基础结构体 Vector 和 Rotator 在通过网络发送时会自动被压缩。在最理想的情况下,其体积最多可减少 90%!这对于网络占用来说是一个极大的利好。
- 添加了新设置
Profiling,你可以在服务器端使用--profiling或在客户端设置中启用它。这将在控制台中记录运行各项操作/脚本事件等所消耗的所有时间。 - 现在 HTTP 请求(即加入服务器时下载文件的过程)会自动进行压缩,这可以减少下载大文件时的网络占用!
- 现在,距离非常远或不在屏幕上的 Actor 的同步/更新频率将减半,以提高性能。我们后续仍计划对其进行微调,并在某些情况下使其更加激进。
- 资产加载系统经过了重做,现在速度快了许多。
- 小型 Prop(半径 < 200)将不再与玩家或动态物体发生碰撞。此外,较大的道具将默认禁用 CCD(大幅提升性能),这可以在 Prop 构造函数中开启。
- 现在语音通话使用了 Steam 系统,它提供了极高的压缩率,并且可以通过 Shift+Tab 菜单进行自定义设置。
- 针对我们的低级 Lua 代码进行了多项改进,以提升脚本编写的性能。
Server
Server 静态类的新增内容:
- 添加了新的控制台命令:
map [MAP_NAME]用以更改游戏地图,这还将重新加载所有包并重新连接所有玩家(类似于重启服务器)。 - 添加了新方法 Server.GetVersion()、Server.GetIP()、Server.GetPort()、Server.GetQueryPort() 以及若干缺失的 getter 方法。
Client
Client 静态类的新增内容:
- 已向 Client.SetCameraLocation() 和 Client.SetCameraRotation() 添加新参数,以实现在特定时间内平滑移动相机。
- 用于在 3D 世界中绘制调试形状的新方法:Client.DrawDebug...()。
- 更改了 Client.SetHighlight() 的参数,现在它接收一个枚举来定义高亮显示的方式。
- 添加了新方法 Client.SetSteamRichPresence(),用于自定义 Steam 好友列表中的信息显示。
现在加入服务器时,Windows 任务栏上会显示一个进度条,并且在加载完成后它会闪烁提示:
游戏内控制台
现在可以在游戏内直接访问服务器控制台了!
如果打开它,将显示 2 个标签页:客户端和服务器。你可以阅读所有的服务器日志,并且还能输入命令。
并非所有的日志都会显示在这里,仅显示你连接到服务器期间所输出的日志。

Timer
Timer 的新增内容:
- 添加了新方法:Timer.Bind(timer_id, actor) - 这将把计时器关联到一个 Actor,当该 Actor 被销毁时,计时器也会被销毁且不再被调用。
- 添加了新方法:Timer.IsValid(timer_id)。
命令行界面
- 现在可以使用 CLI 一次性下载多个资产/包,只需用空格隔开即可,例如:
cli assets install quaternius city-park。
Steam 成就

通过集成 Steam,我们正在尽可能地利用它所允许的每一项功能 😅!
这其中包括成就!我们得到了有才华的朋友 Esther 的支持,她正在为这些成就绘制令人惊叹的艺术画作!
我们会一步步创建更多成就并发布它们!我们同样期待你为更多成就提出想法!
脚本改进
-
向 Package.Require() 添加了新的搜索器,我们目前支持 5 个搜索器,搜索顺序如下:
- 相对于
current-file-path/ - 相对于
current-package/Client/或current-package/Server/(取决于你所在的端) - 相对于
current-package/Shared/ - 相对于
current-package/ - 相对于
Packages/
- 相对于
-
Package.Require() 现在可以在运行时和任何时候被调用。
-
Package.RequirePackage() 现在会将一个包作为库加载到当前包内部,这意味着加载的包会自动发送给客户端,且其加载的所有路径都是相对于该包本身(而非调用它的包)。
-
详细日志现在将显示当前线程的 ID。
重命名默认资源包
默认包 NanosWorldWeapons 和 NanosWorldVehicles 已重命名为 nanos-world-weapons 和 nanos-world-vehicles,以遵循包和资产名称的新标准规范。现在引入它们的方式应为 Package.RequirePackage("nanos-world-weapons"),使用方式保持不变(NanosWorldWeapons.AK47())。
常规更改
- Cable 获得了新方法:
:GetAttachedStartTo()和:GetAttachedEndTo(),用以获取其两端是否已连接。 - Player 获得了新方法:
:SetVOIPVolume()、:GetSteamID()。 - Pickables 获得了新事件:
ReleaseUse和PullUse,当角色拉动或释放其使用按键(例如武器扳机)时触发。 - 改进了 Pickables 和 Props 启用交互触发器的方式。
- Trigger 获得了新方法:
:ForceOverlapChecking(),它将在游戏线程中检查重叠并立即分发事件。 - 为 Quaternions 添加了新方法(+、-、Normalize)。
- 添加了生成随机 Rotator 的新方法:
Rotator.Random()。 - 在默认资产包中添加了大量新的声音、动画、道具和网格体。
- 添加了 Steam 登录。
- 所有 .config 文件中的
tabs均已被替换为spaces。 .GetPairs()现在仅支持pairs。- 添加了分辨率图形设置。
- 删除了游戏内菜单的“Make Day”按钮。
- 添加了道具或物体进入水中时的全新溅水效果。
:GetValue()现在包含一个额外参数:fallback,当值不存在时将返回该备用值。- 可能还有很多其他添加了但被忘掉的东西 😜。
漏洞修复
- 修复了
World.SetFogDensity()不生效的问题。 - 修复了
Client.SetCameraLocation不生效的问题。 - 修复了
Actors.RotateTo()数学计算不正确的问题。 - 修复了
StaticMesh.GetBounds()不生效的问题。 - 修复了 Cable 方法可以在客户端被调用的问题。
- 修复了若干 Character 属性未同步的问题。
- 修复了在运行时更改地图导致崩溃的问题。
- 修复了角色在重生时生命值未重置为
max_health的问题。 - 修复了死亡的布娃娃仍然在移动的问题(来自
MoveTo())。 - 修复了
LogEntry事件引发的无限递归的问题。 - 修复了 Characters 变形目标未同步的问题。
- 修复了 Discord 自定义集成有时不起作用的问题。
- 修复了当玩家没有 Steam 个人资料图片时导致崩溃的问题。
- 修复了在新游戏屏幕取消勾选 Server Announce 时复选框被禁用的问题。
- 修复了在
Interact事件内部销毁实体时发生的崩溃问题。 - 修复了海量的其他崩溃 💥。感谢各位提交的崩溃报告!
