和朋友们一起玩塞尔达传说!

Neboer参加了NerChat!的线上Watch Party,和我的好朋友们一起玩塞尔达(传说)!

写在前面

塞尔达出新作了,大家都很激动。在好朋友的强烈推荐下,我也开始玩塞尔达了。这游戏真的很好玩!当然,我被推荐玩的游戏是旷野之息,不过后来也开始玩新作王国之泪了。

其实我之前很少玩主机游戏,主要还是玩得太少,不知道现在的游戏市场已经变成什么样子了。我对游戏的概念还停留在用鼠标键盘控制游戏小人横板过关的阶段——wasd控制移动,空格跳跃,鼠标用来发子弹,调整视角……这次塞尔达之旅也让我初步感受了一下用现代手段玩现代游戏是什么感觉(不就是有了手柄嘛),从总体上来说确实是相当不错的一次体验。

不过体验归体验,我们是如何解决在游戏和直播过程中遇到的各种问题的呢……

什么是Watch Party?

Watch Party是一种娱乐活动,具体内容就是,好朋友们三五成群聚在一起看电视/电影、玩游戏等等,这种活动的形式在早期一般都是朋友在物理空间里相聚,不过随着现代人生活节奏加快,这种相聚的机会实在少之又少,所以线上的Watch Party也就成为了主流。线上的派对一般发生在某个流式传输平台,比如国外的discord,或者国内的QQ、KOOK等等,一群好友打开语音加入房间,互相可以听到对方的声音,然后再辅以文字交流。同时,所有人在同时观看来自一个人的直播推流,在游戏过程中实时发表自己的想法,和线下派对无异,此之谓Watch Party是也。

选择一种合适的直播方法

国内的商业直播平台

如果是普通的朋友互相直播,那么直接选择国内的直播平台就很好了。不过这些直播平台都存在一定延迟,这个延迟形成的主要原因还是压缩画质的考虑,平台需要将流压制成多种格式便于用户观看;此外还有RTMP等协议的缺陷,这些协议并不足够实时,可能会造成延迟。此外,国内的平台的内容管制比较严格,对聊天的话题和直播内容都形成了一定限制,适合主播与弹幕之间的互动,并不适合好友互相直播。

延迟、帧率、画质

为什么我们如此在意直播的延迟呢?因为Watch Party就是一个对延迟非常敏感的活动,几百毫秒的延迟可能就会对观看者对画面内容的解读和评论造成一定影响。哦对了,这个延迟主要是画面延迟,得益于成熟的VoIP解决方案,现代网络电话的延迟相当低。可以想象,当你在吃鸡的时候,你的朋友听到了你身后的脚步声,想立即喊小心身后,等你再反应过来可能人家早就把你一枪放倒了(悲);又比如你完成了一个相当精彩的操作,在问出“怎么样”的时候,肯定是期望你朋友也恰好看完了同样的操作的。如果画面的实时性得不到保证,反馈的效果就会下降,倘若要是得到一句"我卡了",那想必更是相当的扫兴。

对帧率,当然也有同样的要求,如果帧率不够,那观看者估计也会看得相当难受,一定要让收看直播的观众也有“自己在玩游戏”的感觉才是最有体验和沉浸感的。高清自然不必说了,如果观看者看什么都一片模糊,那收看效果必然是大打折扣的。可是,在实际使用中,这三个要求往往是互相违背的——高帧率、高清画面往往意味着高码率或高压缩率,但高压缩率就会增加编码延迟,影响实时性;而高码率又往往无法达到——国内家宽运营商提供的上传带宽往往非常有限,尤其是在民用网络中基于UDP协议建立的点对点连接,最大的上传速度可能都不到1M/s,占用太高带宽的代价是巨大的,如果丢包率过高,会导致接受方的画面质量显著降低,反而可能不如低清直播。所以如何实现三者的平衡,非常考验直播推流软件的技术能力。

对声音的苛刻需求

前面已经说了直播软件的画面必须满足低延迟、高帧率、高清晰的要求,此外对于游戏直播来说,还有更加苛刻的其他需求。其中最主要的就是对直播中产生的音频的处理。我甚至觉得能否正确处理电脑的音频,是直播软件是否适合用来开Watch Party的重要评价指标。

首先,直播软件必须可以清晰的采集、传输、播放游戏声音。游戏毕竟不是办公软件,它非常强调身临其境的体验,所以游戏的声音是游戏直播中不可或缺的一环。直播软件在保持画面质量的同时,必须也要保证声音的质量。可别小看这个要求,里面的学问大着呢……

其次,直播软件必须保持视频和声音的同步。这个要求其实更加严格,因为画面和声音的不匹配可能会让观众感到困惑,非常影响观看体验。游戏的声音和画面的采集速度可能并不是同步的,另外受制于网络波动,视频和音频可能也不是同步抵达的,直播软件(或者协议)必须考虑到音画同步的问题,并且漂亮的解决它。

最后,直播软件最好考虑到一个相当有意思的问题——路由语音通话的问题,也就是“playback”问题。如果玩家在进行游戏的时候还在与其他人通话,那来自其他软件的通话的声音也会从电脑内部放出来,作为内部声音的一部分被软件采集到,和游戏声音一起路由到其他参会者的耳朵里。在观众角度听起来,就好像自己的声音又从游戏里传出来了一样,非常烦人。如果直播软件可以有选择的路由声音,只发送来自游戏内部的声音,或者屏蔽掉通话软件传出的声音的话,效果就会好很多了。

选择合适的软件

国内的实时直播,可能让人想到了QQ屏幕共享/腾讯会议之类的会议软件。可惜实际上这些软件主要还是面向办公场景比较多,虽然画面质量很好,但帧率不高,带宽并不那么足够,再加上限制使用时长及其他比较令人讨厌的原因,我们并不喜欢。如果只传递语音的话,可以直接在NerChat!里打电话,不过如果连画面一起传输,如何让别人实时看到我们的屏幕,也成了一个大难题,我们迫切需要一个低延迟高画质的直播软件满足这种需求,其实已经有很成熟的解决方案了——远程桌面。

现在提到远程桌面,一般会想到TeamViewer/ToDesk/Parsec/向日葵,当然也别忘记了Windows自带的“远程桌面连接”。但是国内市场上大多数远程桌面是用来远程操作家庭电脑的,并不是专门用来搞游戏直播的,尤其是多个用户共享屏幕这种事就更不能做太高期待了。不过并不是说就没有针对游戏优化的远程桌面软件——parsec就是很好的游戏直播软件,可以很方便的实现在低延迟、高画质、高帧率的目标。parsec在自己的技术介绍页中提到,parsec不走捷径,几乎自己完成了绝大部分底层代码的设计,最大限度把快速变化的游戏画面以最高的传输质量和最低的延迟实时发送到对方的系统中,是非常适合这个应用场景的直播软件。所以我们选择parsec作为我们Watch Patry的首选软件。

在NerChat!里畅所欲言

语音通话的解决方案千千万,免费的、好用的、自由的通话平台在哪里?

既然我们有NerChat!服务,何不直接在上面聊天交流?毕竟别忘了Element和Discord真的好像。其实我觉得现代聊天软件都有一种向类似风格化靠拢的趋势,像QQ这种传统界面真的应该好好改一改了。

我们在NerChat!的多人房间里开了会议,把每个人都拉了进来,大家一边用会议平台交流,一边看parsec直播,非常惬意。

但这一切还远远没有结束。

(说实话,其实可以用KOOK,但是KOOK在安全性上,肯定不如NerChat!的,大家肯定对自建平台更信赖一点。出于私心,我个人是很希望NerChat!也能像KOOK一样做好这种功能,所以……)

调整Parsec

Parsec说到底也是一个普通的软件,需要合适的配置才能最适合自己的使用。而且Parsec本身也有很多bug,毕竟是很新的软件,需要解决的问题可能有点多。我们在这里主要说说我们是怎么调教它的。

解决playback问题

首先,我们需要打开parsec的配置文件。我们打开“Settings”选项,在“Client”部分直接拉到底下,然后选择“edit the configuration file directly”。

前面提到了,一个优秀的Watch Party直播平台最好漂亮的解决playback问题,而Parsec正好有提供这种功能。在parsec的设置项中,用户可以在“Echo Cancelling”配置里调整为“最新”取消回音的配置,并把需要取消声音的软件名字添加到“Echo Selection”中。注意软件名只能通过配置文件修改,在这里我们填入“Element.exe”,这样一来,parsec就完全不会在直播过程中发送Element.exe中语音会议的声音了。注意这个功能只在Windows上提供,我的MacOS朋友就不行喽~

Parsec在游戏手柄上的bug

parsec是优秀的直播软件,但它有自己的问题。Parsec在我的电脑上对游戏手柄支持真的非常差。Parsec会强制占用手柄设备,并时刻准备把手柄作为远程设备发送给对面电脑。这个行为会导致每次打开CEMU的时候,都需要重新配置一下输入设备,否则将没有体感可用。而且Parsec的远程手柄也是没有体感的——在parsec能模拟的两种手柄中,Xbox手柄和PS手柄方法都无法正确在远程电脑模拟我NS手柄的体感信号,所以它这个强制占用但又不好用的手柄支持我真的讨厌极了!Parsec完全没有提供一个“关闭手柄功能”的选项,手柄总是会被自动识别并配置到parsec上,这真的让人非常绝望,所以有什么办法可以解决一下呢?

当然不会放任它不管!这个问题的妥协解决方法是:在电脑里安装一个虚拟摇杆设备,然后配置parsec默认控制这个虚拟摇杆就可以了。但是这个方法并不稳定,而且parsec还是有机会控制其他手柄的,如何彻底堵死parsec,让它只进行纯粹的直播,完全禁止它获取手柄的使用权限呢?

做得乱七八糟的HidHide

当然有方法!HidHide是ViGEm做的另一款开源软件。这款软件可以将游戏手柄对特定程序隐藏,如果隐藏好了,那么在对应程序尝试访问手柄驱动的时候,软件就会出面阻止,这样一来parsec就完全无法拿到这个手柄的控制权限,世界太平了!

我们打开HidHide,将Parsec安装目录下的所有exe程序全部添加进去(我也把steam相关的软件添加进去了,直接一并禁止steam获得权限),然后点击“反向隐藏”启动黑名单模式,在设备里将我们的NS手柄设备给隐藏起来,这样,parsec就完全无法看到我们的手柄了。在这个图里,我们禁止Steam和parsec获取手柄的访问权限。

但是HidHide的GUI真的画得“太漂亮”了。我真的很怀疑它就是“it works on my machine”的效果。这个UI里完全没有使用layout控制控件的大小和对齐,整个软件做得相当粗糙,而且文档真的只有README里的一大段原理介绍和一小段使用方法说明。这一小段使用方法说明完全无法让人搞懂所有按钮和功能选项的含义——它说的太含糊了。

经过我本人的测试,我才大概理解这个软件的逻辑是什么样的:

Applications选项卡控制软件列表,这里添加的所有软件都会被HidHide限制。如果下面的“Inverse Application Cloak”没有被勾选,那么只有选中的软件才能访问隐藏手柄,如果勾选了下面的选项,那么就会只阻止选中的软件访问隐藏手柄。而隐藏手柄是什么呢?在Devices界面里可以看到列出来了电脑上已有的手柄列表,如果一个手柄被选中了,那么它就是一个隐藏手柄。隐藏手柄可以被程序所控制的、允许访问的软件访问到,其他程序则无法访问隐藏手柄。如果把手柄左侧的复选框取消,则任何程序都可以访问到这个手柄,访问不再被限制。

塞尔达,启动!

Switch的模拟器有两个,都有开源代码公布出来。我们玩旷野之息的时候,采用的是CEMU模拟器,模拟wiiu设备。CEMU模拟器在Windows上的性能比yuzu强很多,我这个低性能笔记本也可以流畅玩塞尔达了,当然,很可惜,只能玩旷野之息,毕竟是旧的游戏机。

感谢鸭软大佬赞助的八位堂SN30 pro手柄一个,这个手柄支持体感,有震动,外观复古,便于携带,还是很不错的。实际体验来说,用了一次手柄打游戏之后,就不想用键盘鼠标了,这个东西的操作虽然需要上手适应一阵,但熟悉了操作之后,就会发现用手柄玩这种游戏非常符合直觉,比如跳跃就是最上面的X键,很好的表达了玩家想向上跳跃的欲望。这个手柄原生支持以NS模式连接,效果很好,我的评价是Very Good。

虽然Neboer的笔记本是五年前的配置了,但玩这个旷野之息还是没什么压力的,轻松上50帧,还要啥自行车!在复杂的地方奔跑的时候要略卡一些,不过40帧还是有的,画面非常流畅,很棒!非常好玩。手柄的震动简直让人觉得身临其境,这个反馈做得很有意思!体感是最神奇的一个功能,我把手柄左右倾斜就可以控制林克射箭的方向,用右摇杆粗调,然后用体感纠偏,操作感拉满。有了手柄之后,可以轻易打出在键盘上不容易按出来的复杂操作,从此盾跳盾反踩盾滑行都变得轻轻松松!(好吧Neboer的技术还是一如既往的菜)

旷野之息的直播相当的成功,所以我们理所当然的渴望玩到新作——王国之泪,去体验一下什么是左纳乌的黑科技。

可是当我们真正下载Ryujinx的时候,才发现现实没我们想象得那么简单——这台电脑的性能不足以流畅运行王国之泪。甚至我们后来换了以性能著称的yuzu模拟器都不行,最大帧率也就20-30左右,虽然对很多人来说这个帧率可能足够了,不过Neboer觉得完全没办法玩。实际上,我觉得肯定是这个散热影响了我的CPU发挥最大性能,不过我觉得我不能对这个笔记本有过高的期待,所以,我们开始寻找一个更好的解决方案。很快,一个解决方案映入了我们的脑海,那就是云游戏。

当然,这里的云游戏不是国内提供的商业云游戏服务(不过很类似),而是“直播观众操作主播电脑玩游戏”的解决方案。Parsec的画面延迟实在是太低了,低到几乎和实时画面一模一样,这就可以让我们直接以低延迟和高反馈质量来操作对方的游戏。

手柄直通

如果想要实现云游戏,我们最起码应该把手柄的信号直接发送给主播,这样才能控制主播的游戏嘛!不过我们之前说过,Parsec对手柄的模拟非常糟糕,对NS手柄的体感完全无法正确传输。那这又是为什么呢?我们又是怎么解决这个问题的呢?

没有体感的Parsec手柄驱动

在parsec的设置界面里,可以看到有两个关于手柄的配置选项:Parsec Virtual Gamepads(Beta)和Virtual Gamepad Type。第一个Parsec Virtual Gamepads指是否使用最新的parsec VUSB驱动。看到这里可能还会觉得Parsec会用Virtual USB来模拟任何物理手柄的连接,但是你看到第二个选项“Virtual Gamepad Type”的时候,你却只能找到DS4和Xbox两个选项——并不会模拟NS手柄。

ViGEm是个优秀的开源项目,它实现了一个内核态的虚拟手柄驱动,这样一来用户态程序就可以通过和内核态驱动通信来控制一个虚拟设备,发送一些不存在的操作,比如远程玩家的按键。而ViGEm——已经在它的文档里很明确的写清楚了,自己的模拟驱动的体感功能并能直接提供给CEMU等软件使用,What a pity!

关于NS手柄的模拟,在ViGEm上有一个简短的issue,截止文章定稿的时候,这个issue还是死掉的状态,不但开发者没有标记为解决,你甚至无法在下面留言评论。看来想通过Parsec自己把手柄传出去去控制云游戏 ,还是有些难度的。

所以,既然Parsec做不好NS手柄模拟,还总是想和我抢驱动,直接像上面那样把它屏蔽掉就好了。其实这有点抽象,毕竟Parsec的手柄直通就是用ViGEm实现的,反过来我又用ViGEm家族的软件HidHide阻止parsec获得手柄权限,真是讽刺笑话。

BetterJoy、MotionServer

在放弃Parsec之前,我们对虚拟手柄还是做了一点努力,希望能解决它的固有问题。

BetterJoy是我们看到的另一个开源软件,它可以将本来需要SDL API才能正确使用的手柄(如NS手柄)模拟成Xinput普通手柄(如Xbox),同时最大限度的保留原手柄的操控特性,比如可以将体感模拟成虚拟摇杆的运动,进而在只支持Xinput的游戏里顺利的使用NS手柄进行游戏。不过这个软件对我这个手柄来说意义不大,因为这个手柄本来就支持使用Xbox模式连接Windows,所以也不存在转换的问题,至于体感,只支持Xbox手柄的游戏能用什么体感()。不过在我们这个特殊的使用场景下,或许有用!既然Parsec只能传递Xbox类手柄的控制数据,我们何不在本地配置一个BetterJoy,将手柄的体感转换为其他的虚拟摇杆操作,再在远端的yuzu里配置好(yuzu对手柄控制的设置功能相当完善,可以很方便的配置使用虚拟摇杆模拟的体感),是不是就可以远程带体感畅玩塞尔达了?

我们参照这篇知乎文章来进行配置,然后在本地yuzu上测试,发现完全没有问题,虚拟摇杆完全可以正常工作。我们兴高采烈的把手柄用parsec通过去,然后在远端电脑也打开yuzu,看看这个新设备有没有收到模拟的摇杆信号。

可惜,不行。远程的yuzu模拟器压根就收不到体感虚拟摇杆的模拟信号。很可能parsec在转发Xinput的时候压根就没把虚拟摇杆数据转发过去,我只能说*****。

不过!BetterJoy还有另外一个功能,那就是MotionServer,可以把手柄的体感数据转换成JSON格式通过网络传输出去。yuzu模拟器正好可以接受MotionServer的体感数据,正好弥补了Parsec虚拟手柄没有体感的问题!不过这里需要说一下,由于MotionServer监听在本地端口,需要先用frp之类的软件将本地的端口绑定到远端服务器上,我们尝试了一下,这个方法果然可以,没有任何问题,我们顺利的把手柄连接到了远端,一边观看高性能电脑的游戏画面,一边在本地通过游戏手柄远程操作,延迟不高,体验绝佳!最重要的是,MotionServer是通过UDP传输的,真正做到了低延迟+高质量,我觉得这就已经算得上是我找到的理论的最优解决方案了。

USB/IP

MotionServer确实很好,不过由于需要Parsec传递手柄控制信息,而我们之前说过不希望这个对NS手柄支持稀烂的Parsec获得手柄的控制权限,已经把它屏蔽掉了。有没有一种更一劳永逸的方法,把本地的手柄直接传递给远端,就像USB线一样方便快捷,即插即用呢?当然是有的,它就是大名鼎鼎的USB/IP。

USB/IP是一种网络协议,用于在计算机网络上共享和传输USB设备。它允许将USB设备(如打印机、存储设备、摄像头等)连接到一台计算机上,并通过网络使其可在其他计算机上访问和使用。不过,USB/IP最早是在Linux内核中实现的,并作为Linux的一个功能模块存在,在Windows远程桌面里,RDP协议也支持USB控制流的远程传输,但这个功能似乎没有独立控制的方法,和Linux“内核层支持+用户态软件”协作的工作模式相比非常不便,这也是Windows的一大问题了。既然我们有开源的协议,就赶快看看Windows平台上有没有优秀的USB/IP协议的实现吧!很快,我们便找到了两个很好的项目——usbip-winusbipd-win

在开始安装和使用软件之前,我们先说说USB/IP协议的基础知识。首先,USB/IP协议将设备的供应方称为服务端,将设备的接受方称为客户端。服务端使用软件将自己的设备取下,听在一个端口上,然后客户端再使用客户端软件去连接这个端口,从而获得并使用设备。这个时候,服务端就不可以再使用这个设备了,看起来就像是这个设备直接接入了客户端的机器了一样。在这里,我们使用usbip-win作为服务端,usbipd-win作为客户端来传递数据。

  • usbip-win

    首先,我们需要下载这个项目的最新Release文件。不巧的是,这个项目似乎并没有Release可下,难道我们需要自己编译吗?

    其实是不用的,因为你点开Release页面之后就会发现,这个项目里全是pre-release,GitHub的Releases界面默认不会展示pre-release,感觉容易引起误会。

    我们使用usbip-win作为客户端,所以直接参考“Windows USB/IP client”部分。本来,README里说需要先安装证书才能安装这个驱动,不过看最新的Release里说,vchi驱动已经获得了微软的签名,应该可以直接安装了。直接从“Copy VHCI driver files into a folder in target machine“开始,打开一个管理员powershell,运行usbip.exe install,就可以自动完成安装。

    很好,现在我们已经装好了usbip的客户端,就等着服务端发送连接请求了。

  • usbipd-win

    虽然只有一字之差,但是它是和usbip完全不同的项目——使用C#编写的,而且还在活跃的更新,看起来是相当靠谱的项目。我们直接下载Release,它竟然还提供全自动的安装程序,那么我们直接双击安装,然后就可以运行了。先准备好一个管理员shell窗口,输入命令 & "C:\Program Files\usbipd-win\usbipd.exe" list,就可以查看出当前连接在电脑上的所有USB设备,以及他们是否可以被远端所连接的状态了。

现在,我们准备开始连接了。首先,对于没有公网IP的家宽来说,第一件事就是要把服务端的3240 tcp端口forward到一个有公网IP的服务器上去,在这里我们假设那个服务器的地址是1.2.3.4,端口是相同的。

然后在服务端执行命令,usbipd.exe bind -b 1-2,将最后的1-2替换为usbipd.exe list中确定的手柄busid。如何获取手柄的busid?其实非常简单,在手柄没连接的时候看看usbipd.exe list的结果,再和手柄连接的时候usbipd.exe list的结果比对一下,多出来的设备就是手柄咯!

这样,服务端的手柄就可以连接了。这个时候客户端只需要执行usbip attach -r 1.2.3.4 --busid 1-2即可,过几秒钟,服务端就会响起硬件断连的声音,而客户端则会显示新的硬件已连接,我们进yuzu,完全不需要任何配置,就可以直接开玩了,和本地手柄直接插在远程主机上是完全一样的效果!

需要注意:

  1. 服务端和客户端的busid必须保持一致。
  2. 服务端的手柄不能被占用,否则客户端会报连接错误:设备忙。
  3. 数据通过TCP传输,其实实时性缺乏保证,不过我们测试中并不影响实际的使用体验。

其实这个软件usbip-win还可以做服务端,不过为什么我们没有用它来做服务端呢?那大概就是因为我觉得usbipd-win更适合用来做这件事,毕竟又新又好,可惜usbipd-win只能拿来做服务端,我们还是需要依赖usbip-win来实现客户端,这个项目已经两年没更新了……

唉,开源。

更好的音视频通话体验

我们先来简单看看Matrix的客户端Element是如何解决“群语音”的问题的:

根据Element的官方文档,可以看出,当房间人数为2个时,所有的语音通话和视频通话都直接经过Matrix服务端和配置的TURN服务器传输。当房间人数超过2人时,Element便会在群组里添加一个Jitsi挂件,然后鼓励参会者使用Jitsi服务器聊天。

很好,看来我们在群里语音需要走Jitsi服务器。Element的默认Jitsi服务器是它官方提供的服务meet.element.io。这个网站在国内可以访问和正常使用。不过它有一个很严重的问题就是,它是一个境外的Jitsi服务器,如果你希望使用它打语音视频通话,那么它不但不会通过TURN服务器检查出来你们是否可以建立P2P连接,而且还会把你们连到一个非常差的节点上(一般位于法兰克福),导致NerChat!的多人会议质量一般都不是很好,(即便如此,实际的会议体验还是相当可靠的,WebRTC协议恐怖如斯)。为了改善这个问题,我们决定自己搭建Jitsi后端,并配置NerChat!使用我们自己的Jitsi服务器。

在Krusl的服务器里搭建Jitsi成了我们两个人共同的噩梦,还好最后成功了。我记得我们先是遇到了服务器启动后无法连接会议的问题,前端里配置的服务器地址无法直接访问。然后我们转向Wireguard内网里测试,遇到了第二个问题:“很抱歉,出了点问题!”然后是控制台里一堆报错,大概是XMPP连接里传回了失败的结果,无法建立连接。Jitsi的日志系统非常散乱,完全没有办法确定问题到底出在哪(我菜死了,直到最后我们才从jiconfo的syslog里找出了问题根源——我忘记关闭的Mediamtx程序占用了RTSP端口(绷不住了)。之后还有很多问题,比如服务器可以正常连接,但参会者互相看不到对方。经过我们再次排查,发现是Krusl写错了turn/stun配置,而我直接抄了他的配置忘记修改了,改好之后,这个会议服务才勉强上线。

我们把Jitsi的核心组件部署在Krusl的设备上,然后在meet.neboer.site上部署了Jitsi前端,将Jitsi服务正式上线了。然后我就需要让NerChat!去使用这个服务器。我参照官方的做法,将NerChat!前端的“preferJitsiDomain”设置成了meet.neboer.site,不行!又把Nginx里的wellknown endpoint的返回值里添加meet.neboer.site,好像还是不行!没办法,就在焦头烂额之际,这玩意又行了!太离谱了。(可能是之前Nginx配置刷新之后,Element客户端没来得及刷新Jitsi服务器的缓存导致的)

对于Nelement,就在我刚刚配好Jitsi的第二天,Element Android上游竟然更新了v1.6.2版本,这太棒了!我们管快更新(草),不过更新之后我们发现还是不行,Nelement死活连不上Jitsi,在LogCat里的报错相当简陋,只是Jitsi SDK说了两句话,大意为ID为xx的请求失败了,这完全没有debug作用好嘛?!

而且这个错误还是在SDK里抛出来的,相当难以定位。不过好在我们精通Android网络抓包(草),直接在手机上抓HTTPS流量看看到底是哪个请求失败了,结果发现原来是服务器前端没有正确配置Prosody的BOSH,我看Jitsi文档里说BOSH连接已经被废弃了,所以就给前端这行注释掉了,没想到Android端的Jitsi还是需要这个服务的。根据这个issue,似乎Jitsi Mobile早就已经弃用BOSH了,不知道Element的Jitsi SDK为什么还在使用。

经过一番折腾,Jitsi服务器终于稳定的建立起来了,并可以被NerChat!的所有端默认、正常的使用了。可喜可贺!用这个服务器两人聊天的时候,发现它的STUN确实可以检测到两个人可以进行点对点连接,进而帮助两人完成“打洞”,建立起可靠、低延迟的快速连接,真是太厉害了。

后记:当勇者的故事成为传说

悠悠旷野息,魂牵海拉鲁,梦萦王国泪。

这里没有剧透,敬请放心食用。

我认为,每个人在游戏面前都是小孩子,我们的生活需要一些朴实到幼稚的游戏来慰藉自己疲惫的灵魂。一部优质的游戏值得反复的品味,它不仅仅是生活的调味品,更是支撑我们继续前行的动力。在这些可以被“提名”的游戏中,任天堂的塞尔达传说是相当经典的IP,围绕这些特点鲜明的角色有一个又一个的故事。我还没有太深入玩《王国之泪》,不如就从我们熟悉的前作开始,以这个任天堂经典作品所带给我的感受为结尾,为这片近万字的文章画上句号。

塞尔达传说《旷野之息》这个游戏用一种相当梦幻的表现手法讲述了一个勇者斗恶龙救公主的老套故事。这个游戏最有特点的地方,我觉得就是它的独特质感。无论是希卡塔、神庙、城堡,还是村子里的古建筑,甚至这里的一草一木、断壁残垣,都传递出一种只属于海拉鲁大陆的独有魅力,它们之间都是紧密相连的,营造了整个游戏独有的氛围,带给玩家相当一致的游戏体验。游戏的整个剧情,虽然从总体上看相当老套,但每个细节都很值得推敲,而且每个人都活灵活现;游戏本身也使用到了先进技术(比如那个著名的物理引擎)来让玩家与世界的互动变得充实有趣,玩法多样,挑战有趣,有成就感。当林克在海拉鲁大陆上策马奔驰,在村庄里走街串巷,在神庙里苦思冥想,在战场上一往无前时,你会发现整个游戏所给你带来的感受如此的真实,你会随着林克一起去寻找自己珍贵的回忆,一边探索一边发掘出这个看似简单却充满细节的游戏外表下,那令人魂牵梦绕的、如泣如诉的传奇故事。

非常感谢你看到了这里。我想这里最好的结尾,莫过于我在玩了这款游戏之后最真实的感受。讲真的,和有趣的灵魂一起玩游戏,带来的体验和自己一个人孤独探索完全不同,太有意思了!尤其是当你身边的某个好友对这个游戏特别了解的时候(草),他如果是一个很好的引导者,那真是莫大的幸福。快快和朋友们一起玩游戏吧!不如就先从《旷野之息》开始,去海拉鲁大陆走上那么一遭!

其实,Neboer自己也不清楚自己到底是不是希望把这篇文章写成这个样子——纯粹的技术分享让人觉得和游戏并无多大关系,我的重点可能错了。我想,与其关注我们怎样获得更好的游戏体验,更不如关注一下我们在游戏中到底体验到了什么。现代电子游戏技术让我们仿若置身其中,越来越先进的图形技术,越来越强大的硬件设备,越来越真实的控制终端……它们都在尝试让我们获得更好、更符合直觉、更能沉浸其中的代入感,虽然说这些技术和设备是有良好游戏体验的基础,但我觉得一个真正容易被打动的灵魂才是玩家真正需要的最强游戏装备,它能让你感其所感,想其所想,在这一刻,你透过游戏与它的创作者产生了共鸣,这些写进硬盘的乱码一样的数据变换成了显示器上斑斓的光、扬声器的浅浅震动,让你仿佛置身其中,逐渐脱离自己所处的世界,让灵魂随游戏里的主角一起进入陌生的世界,尽情享受这段美妙的旅程。

谢谢大家读到这里,Neboer会继续努力,为大家带来更精彩的文章的。

鸣谢

感谢Krusl作为热心的资深塞学家,介绍给我这个超级棒的游戏,并在我游戏过程中给我的超级多的指导和帮助(他简直是个活字典),让我快速上手这个游戏成为了可能(虽然我这操作依然拉胯的一批),以及在剧情方面给了我很多提示,帮助我更好的完成这篇文章,对塞尔达全系列的世界观有了新的理解和认识。

感谢DuckSoft赞助的八位堂SN30 pro游戏手柄,让贫穷的我(卑微)也能以最沉浸的方式体验游戏的操作乐趣。当然,也感谢DuckSoft的技术支持,指导我很快的装好了游戏环境。

感谢Eibon一直以来的陪伴,以及和我一起解决手柄直通的问题,并提供高性能主机设备让我可以用云游戏的方法畅玩《王国之泪》。

再次感谢群里各位的陪伴,这篇文章的编写离不开你们的支持;感谢各位读者朋友,是你们一直以来的陪伴支持Neboer走到了今天;感谢任天堂开发了如此之棒的一款游戏,令我回味无穷。