« 蒙皮数据的压缩 | 返回首页 | RogueLike 原型开发工具 »

游戏数据的展示

游戏的业务逻辑到画面呈现的过程和 GUI 系统在结构上有相似之处,又有一些不同点。

在软件设计时,我们通常倾向与把数据和展示分离。在 GUI 系统中,数据通常被称为 Model ,展示被称为 View 。典型的 MVC (及其衍生品 MVP/MVVM 等)模式就是建立在此基础上。业务逻辑修改 Model ,经过展示模块,把 Model 映射到 View 中呈现给用户。

传统的面向对象设计中,很多人倾向于按对象划分,每个对象有数据部分和展示部分。对于游戏,我不喜欢这种设计。我更倾向于把数据和展示完全分离,再用 id 把同一个对象关联其数据模块和展示模块中分离的实体。这是因为,游戏尤其是虚拟世界广阔的游戏,屏幕展示的仅仅是虚拟世界很小的一部分。在同一时间,大部分的数据都不必展示。甚至数据也未必存在于本地的内存中。

我倾向于把游戏软件切分为 gameplay 和 view 两个完全分离的模块,各自有独立的数据结构和设计。gameplay 应该可以完全独立于 view 运转,而让图形引擎关心且只关心 view 部分。在制作游戏软件时,如何解决好 gameplay 的信息如何在 view 模块中展示出来,就成了必须考虑的设计点。

设计数据如何呈现,必须考虑图形引擎的对外接口是怎样的。图形引擎的使用接口通常有两种设计:立即模式(Immediate Mode)或驻留模式(Retained Mode)。所谓立即模式,就是每帧都是从空白开始,把需要渲染的对象依次提交,最终得到画面;而驻留模式则由引擎保留一个待渲染的对象集,用户可以增加或减少需要渲染的对象,并可以修改已经加入渲染集的对象的状态。在图形底层 API 中,一般都只提供立即模式,而图形引擎则会进一步封装。在 2D 引擎中,两种模式的设计都很多见;但 3D 引擎由于 3D 渲染对象的复杂度大大超过 2D 图片,几乎都是提供的驻留模式接口:即,创建一个可显示对象,并可以之后销毁。在对象存活时,可以随时修改它的各种状态,包括并不限于,材质、位置、播放动画、挂接新的对象等。

对于场景很小的游戏,view 就是完整 gameplay 的体现。每个 gameplay 中的实体都在 view 中有一个对应品。在 gameplay 中的实体状态发生改变时,我们可以对应的设置 view 中对象的状态,正确表现出来。虽然对象并不总在镜头内,但渲染引擎通常会根据摄像机的位置和角度裁剪掉不必显示的对象。

如果场景很大,或有多个场景同时运转(只显示其中一个),一股脑的把 gameplay 中所有对象交给 view 模块就不明智了。我建议再设计一个叫做 viewport 的模块,它用来表达 gameplay 中的一个需要展示出来的区域。viewport 应该是一个保留有自身状态的对象,在每个渲染帧开始时,viewport 去 gameplay 中查询该区域中应被显示出来的对象,每个对象有唯一的 id 。viewport 应和自身保留的上一次查询的对象的状态向比较,得到这次查询和上次查询的差异。例如,这次查询如果和上次查询的位置相同,当前的位置就不用表达在查询结果中。这样,能更好的配合驻留模式的引擎接口。

而 view 模块中,也不是所有的可显示对象都会在 gameplay 中有对应品。我们应该标记出那些会受 gameplay 影响的对象,方便筛选出来。例如,有些用于和用户交互的可显示对象就可能在 gameplay 中并不存在。还有一些固定的作为背景的场景、渲染气氛用的特性等等。

在每一渲染帧,遍历出所有 gameplay 对应的渲染实体,再和前面的 viewport 查询结果集相比较,就可以知道这些对象需要做那些状态修改。以及,是否有需要增加的新对象,或是某些对象应该暂时隐藏掉。这样,viewport 也代替了图形引擎做了一次更高效的裁剪。在同一时间,viewport 往往不只一个。比如,游戏的主画面和小地图就是两个独立的 viewport 。它们所关心的范围不同,关心的信息也不同。小地图关心的范围更大,但只关心需展示的实体很少的信息。

对于 gameplay 信息不完全在本地内存中的场合,例如网络游戏,这个模式依然有效。在 MMORPG 的客户端中,gameplay 的对应模块其实是完整 gameplay 数据(存在于服务器上)的一个局部映射。通过网络包逐步的把部分 gameplay 数据同步下来。我们依然可以利用这样的模式把映射下来的部分数据再筛选展示。这种场合,viewport 模块更像是一个高效的裁剪器,裁剪掉不需要用于展示的数据。和图形引擎的裁剪模块不同,它拥有更多的和图形无关的信息。例如,你在封闭的房间内,屋外的对象就不需要在渲染引擎中更新和展示。你在二楼时,用于显示的 viewport 或许也不需要关心三楼的玩家;但同时可以有另一个用于发出环境声的 viewport 可以帮你播放楼上玩家的脚步声。显然,只是基于空间位置信息的图形渲染模块很难做得更好。

一个设计良好的 viewport 模块(从 gameplay 中提取出当前需要传入 view 的信息)可以帮助游戏数据和展示有效的分离。我建议在游戏软件设计的早期就应该重点考虑它的具体设计。

Comments

实际上,法币有没有矿工呢?法币也有矿工,比如RMB,这是千千万万的农民和基层劳动者挖矿来维持这RMB的价格,就这,RMB从我出生的那个年代,80年代初到现在,价值至少贬值了1000倍,只是没有官方的人直接挑明这个问题而已,比特币至少能杜绝你随意印钱的问题。

所以,很多玩虚拟货币的技术人员开始玩金融,尤其是币安老板赵长鹏,那你交学费这是妥妥的。

Luna币的基金在去年大幅增持比特币,并且放出消息,准备储备价值100亿美元的比特币,这无疑暗中帮助推高了比特币的价格,luna币的基金当时就被指责,使用一分不值的luna币和UST来换取其他人手中的真金白银的比特币,那么USDT在跟luna币宣布脱钩以后,作为luna币,你应该释放原来储备的比特币(估计仅仅储备了大约不到20000个比特币)来拯救露娜币,然而,他们并没有,这就造成了露娜币跌的一分不值。

有人说Luna币会牵连比特币大幅下跌,这种情况是不可能的,Luna币和UST和USDT违背了比特币基本原则,那就是挖矿,显卡,交易量,这三者缺一,加密货币的价值就不存在,你别管你绑定什么,迟早是要灰飞烟灭。但是USDT可以作为美元和比特币的桥梁,一种小规模的汇兑系统,类似于国家外汇管理局这样的一个小型的交易量存在的情况下,具备一定的价值,这属于金融问题,跟加密货币的技术框架无关。
设计加密货币,首先你要吸引矿工,没有矿工,那就是死翘翘,其次,你要挖矿的设备预备一定的价值和技术含量,否则获取太容易就违背了公平性,最后,要在区块链上产生一定的交易数据,这样,整个链才能维持稳定的增长。如果没有交易量,那么,矿工会被大型的矿池代表的,这问题不细谈。

我也是最近受邀参与一款游戏的研发,然后想起这个博客过来看看,现在很多人喜欢使用json来存储数据,事实上在win95时代,win系统有一个著名的ini文件,这种文件就是简单的json,这还是1995年的技术了。

这一轮比特币大幅下跌,我认为直接的原因,这跟30系列的显卡驱动被破解,已经解锁hash计算了,测试表明,一块解锁的3060大约相当3块1070的算力,比特币不下跌才怪。

光影效果是一个写实物理世界的最优秀的表达利器,但是的游戏是二次元,魔幻世界,你可以在这个问题上投机取巧一些。
EIdos有些技术,就是投机取巧(古墓丽影的设计公司)

openGL和Dx都有关于如何使用超长指令字来加速的函数集,现在CUDA编程,你可以把矩阵计算和矢量展开直接推给GPU,可以很大程度上抛开openGL了。
展开什么模型,什么时候渲染模型和高速渲染,取决于游戏设计人员的需要。

光源追踪是早期的光影技术,这种技术还是有瑕疵,他把反射、漫射、镜像等等,都视为光源,然后开始使用流处理器去渲染,这样做的效果就是不够逼真,因为反射和漫射类光源跟发光主光源直接的衔接不够严密,所以后来出现了光线追踪技术,就是发光源直接射出矢量展开,反射和漫射使用材质反射率来精确的解决,这样做的好处就是逼真,并且也必将大大推动显卡的计算性能。

光线追踪和光源追踪,英文原称 Light source Tracer & Ray Tracer,这个技术是显卡目前最顶尖的技术,就是你说的这种算法,你打游戏,无论是第一人称和第三人称,你的视角在一个追踪周期内(大约是20毫秒~2000毫秒)是有限的,所以显卡不会傻到把屋子或者场景内所有的光线效果都计算出来,显卡只计算你眼睛视角内的东西,然后迅速的把BMP写入缓存(显存,8G显存写满,只需要最多3秒钟,显卡就是这么强大)输出到显示器。

viewport模块更像是一个抽象概念,在SLG中它就是AOI,在MMO中它就是场景或者副本。我觉得viewport早期一个很重要的设计考虑是它需要gameplay提供多少信息,往往随着viewport的变化会导致gameplay也跟随着膨胀。

rawa459 我看你就挺闲的

比特币的市值高达30000亿美金,地位已经固若金汤,3060的驱动程序也已经破解,算力已经解锁了,3060算力高达1070的3倍。

当年黑客组织的成立的(上世纪70年代末90年代初)初衷就是,美国政府,美英军方,美国的科技巨头,很多东西充满了谎言,尤其是技术问题,但是现在回过头来看,某些国家全是谎言,尤其是技术方面,比美英更甚,现在开源世界已经彻底的扭转了弱势的局面,人能够战胜巨兽和猛虎,是因为智慧,不是因为我会吹。

关于win95~winxp,我当年阅读了不少黑客泄露的源代码,加上我对于当年MFC的理解,事实上,除了win2K的操作系统内核,在高分辨率图形模式下(对照安全模式),基本上都可以使用MFC构建一个新的,比如架设在FreeBSD内核上,使用BSD的C编译器来构建一个本地的C++编译器,然后使用这个编译器来展开MFC的90%以上的基础类库,毫无问题,这也就是后来wine的由来,所以说,只要你认真研究,没有任何的技术秘密可言,尤其是linux内核,这个也是开源的,认真看源码就够了,不需要多讲。
win系统,可执行文件,分为com组件,exe模块,dll库,OCX组建,OLE库,这些是从执行权限由高到底来排列的,bat执行属于脚本解释器。
但是,你通过VC++可以把这几种执行模式互相交叉,互相替换。
注册表里面的东西,都是com组建,exe,dll库的配置文件和执行环境信息,属于环境变量的一部分。
注册表的设计原理,这才是win2k的核心机密。这个涉及到如何管理这些执行文件和win内核的问题,当然了,这些在wine的源码里都有。

我首先没时间,我的话很多人也不喜欢听,至于文章和博客,我引用三句话,叫,至人无己,神人无功,圣人无名。(出自庄子的《逍遥游》)

看云风skynet更新了jemalloc,我才发现jemalloc竟然更新了一个版本。。

每每读到 rawa459 您的话语鄙人都醍醐灌顶,强烈要求您开个博客并公布链接,鄙人一定第一时间关注并拜读,猫在别人下面太委屈您的才能了

rawa495 你要是说不完的话,干脆也写篇博客贴个链接就是了。

很多人贬低微软的winodws不值一提,其实这是错的,微软在GUI方面出现了大量的创新,在win95时代,这些技术是领先全世界的(包括很多Unix系统的GUI),很多人都知道注册表,其实注册表就是一个小型的数据库,后来linux的内核模块的设计,也是参考了注册表的设计。
在数据库方面,做的最好的是当年的DB2(IBM的产品),大多数银行的数据都是采用DB2的解决方案。

GTK和GTK2是基于C语言的,而KDE(后来发展成为QT超级函数库)是基于C++的,目前从功能的完备和复杂性上,KDE4和5基本可以和win10相当。

GUI这个东西的崛起就是win95的崛起,在win95之前,unixV系统(1986年贝尔实验室曾经吧unixV系统内核迁移到x386芯片上)和linux系统至少出现了100种基于X11服务器的窗口管理器,win95之后,窗口管理器出现接近300种之多,最简单的诸如Xfce这类,复杂的诸如gnome和KDE,窗口管理器是基于X服务的,X服务的函数库目前就是大约几类,GTK,GTK2,KDE2,3,4,5,还有HPux,AIX,Solaris,freeBSD,openBSD,这些系统都有自己的X服务函数库,窗口管理器(X-server 和 Window Manager,后者就是窗口管理器)主要是负责X生成图形和窗口对象以后,进行管理的,通过窗口管理器向操作系统内核传递指令消息,生成,销毁窗口和内部对象。
但是目前来看,窗口管理器消息层最复杂的还是winOS,各种管理的向内核和外设传递的消息超过了2000种。
最简单的窗口管理器比如xfce,也就是几百种执行,很多内核参数根本不能用xfce来传递。
游戏的UI更简单,超过100种消息的游戏UI这就不得了。
因此,游戏根本不需要这么复杂的GUI模式。这就是结论,美国软件公司也没能力把一个游戏做的跟操作系统一样复杂。

大佬你多ctrl+v多按了一次

Post a comment

非这个主题相关的留言请到:留言本