什么时候开始担心netcode
When to start worrying about netcode?
我目前正在开发一款c++/SDL/OpenGL游戏。我已经制作了一些小型游戏,但都是本地游戏(没有netcode)。所以我知道如何制作引擎,但我不确定netcode。我是否可以先为分屏播放创建完整的引擎,然后再添加网络代码,还是这会让一切变得复杂?在编程基本游戏引擎时,我是否已经考虑到netcode,或者在它在一台机器上运行良好后,是否也可以将其放在游戏顶部?
这是一款2D射击类游戏。不,我不喜欢改变我对编程语言/窗口管理器/api的选择,因为我已经实现了游戏的骨架。
理论上,您所需要的只是一个足够好的设计。编写足够多的抽象类,然后!您可以弹出一个用户界面(即本地)为另一个(联网)。但我不相信这个理论。
你可以做你想做的事,但这涉及到你在处理网络游戏玩法时要考虑的所有新问题——多个用户的同步视图,当一个用户断开他们的网络连接时该怎么办(当然,如何检测一个用户何时断开他们的网络连接),接收用户输入的网络延迟,处理一边而不是另一边的延迟。网络化编程是完全不同的,其中一些方面(主要是处理同步的方面)可能会影响核心引擎本身。即使"只显示两个视图"也变得更加困难,因为现在您在两台完全不同的机器上拥有数据,并且数据不一定相同。
我的建议是做与你希望相反的事。首先用最少的图形让网络代码工作。事实上,控制台消息远比漂亮的图像重要。你已经有了制作其他游戏图像的经验——首先工作最可疑的技术。对网络代码将要求你做的所有事情有一个良好的感觉,然后专注于图形。
对于一款面向网络的游戏,你需要牢记5个概念:
- 调度员
- 呈现 模拟
。游戏引擎是一个事件软件,这意味着在游戏中每个通用对象(可以是单位,GUI等)的状态下,你执行一个动作,这意味着,你调用一个函数或什么都不做。
Dispatcher接收每个事件更改,并将该更改分派给另一个子系统。
Synchronization意味着在事件发生变化时,必须通知网络中的所有客户端将其调度器抛出该变化,这样所有玩家都可以看到其他玩家的变化,同时渲染和模拟相同的事情。
Rendering渲染读取每个对象的参数和相关状态并绘制在屏幕上。例如,如果你为每个名为life_points的单位设置属性,你可以在life_points>50时绘制一个正常单位,在life_point>0和life_point<50时绘制一个伤害单位,在life_point=0时绘制一个毁坏单位。渲染不改变对象,只绘制读取对象的内容。
Simulation读取每个对象并执行一些带有计数状态和属性的任务,例如,如果你有一个生命点,你将一个单位的状态标记为死亡(例如)或更改GUI,或者如果一个单位靠近另一个敌人团队,你将其状态从静态更改为移动,移动到靠近另一个单位。加上这个,在这里你做了单位的物理,改变位置,旋转,等等…当你通过网络同步所有对象时,每个人都将观看相同的内容。
问好。
尽快添加netcode。如果你不这么做,你可能需要在开发周期的后期对引擎进行大量修改,所以最好尽早完成。
这也取决于游戏的复杂程度,但同样的原则仍然成立。最好不要在最后一秒加上去
希望这对你有帮助!
- 我应该担心冗余声明吗?
- 在为视频游戏实施基本的二进制序列化时,请担心可移植性
- 我应该担心动态代码生成与用C++编写的其他模块不匹配吗?
- 如果两个线程调用同一个函数,但函数中的所有变量都是局部变量,我还需要担心线程之间共享数据吗?
- 如何使Palindrome代码不必担心(用户input)单词间距
- 我们是否需要担心 32 位或 64 位整数,或者我们只使用 'int'
- 我是否应该担心C 17中的Wmissing-Field-Initializer和汇总初始化
- 如果我使用 std::function 来捕获 lambda,我应该担心它被解除分配吗?
- 我可以使用Boost::Asio而不用担心网络编程问题吗?
- 为什么要担心'undefined behavior'>>签名类型?
- 在使用放置新操作符时,我真的需要担心对齐问题吗
- 当我使用带有整数的C++数学函数时,我应该担心精度吗
- 当你通过引用返回对象时,你什么时候需要担心对象会被破坏
- 我应该担心大结局,还是只是一个微不足道的方面
- 我应该担心向量中有太多级别的向量吗
- eC(Ecere)如何不用担心类的私有数据字段
- 我应该担心我的软件被反编译吗?
- 是否strand和io对象(如tcp::socket)需要担心相关联的io_service的生命周期?
- CV_8U和CV_32F之间有什么区别,在它们之间转换时我应该担心什么
- 什么时候开始担心netcode