如何設(shè)計(jì)一個(gè)多人游戲場(chǎng)景

隨著游戲行業(yè)的興起,越來越多的游戲出現(xiàn)。游戲中又分各種各樣的游戲類型,而基本上在國(guó)內(nèi)的游戲環(huán)境中,最受歡迎的還是網(wǎng)絡(luò)游戲。不知道大家有沒有好奇過,游戲中是如何實(shí)現(xiàn)你和你的朋友能一起出現(xiàn)在游戲中并一起游玩的,而這背后的機(jī)制又是怎么樣的?

首先看到這個(gè)標(biāo)題大家不要害怕,這篇文章并不想講無聊的技術(shù),不會(huì)研究游戲服務(wù)器需要多少核多少內(nèi)存,設(shè)計(jì)什么樣的架構(gòu),能承載多少人,用什么語言,什么網(wǎng)絡(luò)通信協(xié)議。而是想從一個(gè)產(chǎn)品的設(shè)計(jì)的角度,或者游戲框架的設(shè)計(jì)角度,來探討一下如何設(shè)計(jì)一個(gè)多人的游戲場(chǎng)景。

游戲服務(wù)器

如果要問一款游戲都由什么組成的,你會(huì)怎么回答?
我猜大概你的第一反應(yīng)是游戲的畫面,畫質(zhì),特效,幀率,音效?或者更深入一點(diǎn),可能會(huì)想到玩法,操作,劇情,戰(zhàn)斗?
不可否認(rèn)的是,大家玩游戲的第一感受一定是這個(gè)游戲?qū)ξ覀兊拿佬g(shù)效果的呈現(xiàn),再然后就是游戲的玩法和操作之類的互動(dòng)體驗(yàn)。而還有一部分,是非常重要的,卻經(jīng)常被大家忽略的,那就是服務(wù)器,即那個(gè)把成千上萬的玩家連接在一起的幕后“黑手”。

如果你玩的游戲是能和其他玩家一起組隊(duì)或者對(duì)戰(zhàn),那你可能意識(shí)到了,它的背后還有一個(gè)游戲服務(wù)器。甚至很多游戲,你是看不到任何其他玩家的,它的背后也有服務(wù)器的存在。

當(dāng)然了,最能讓你注意到游戲服務(wù)器的,一定是“網(wǎng)絡(luò)掉線”,“服務(wù)爆滿”,或者是網(wǎng)絡(luò)原因造成卡頓,這幾種場(chǎng)景。

今天,我想講講最常見的場(chǎng)景,即多人組隊(duì),多人同屏對(duì)戰(zhàn)的游戲服務(wù)器,也就是最常見的MMO類型的游戲,是如何跑起來的。簡(jiǎn)單來說,就是你和你的朋友們,你的網(wǎng)友們,是如何在游戲里一起愉快的玩耍的。

雖然我做了7年的游戲服務(wù)器開發(fā),但是今天,我想拋開具體的技術(shù)實(shí)現(xiàn),從一個(gè)設(shè)計(jì)者的角度,來講講如何構(gòu)建一個(gè)多人同屏的游戲服務(wù)器場(chǎng)景。

場(chǎng)景單位

首先,我們想一想,在一個(gè)大型MMO的游戲場(chǎng)景中,都有哪些要素組成呢?換成程序員的思維,即游戲場(chǎng)景中都有哪些對(duì)象呢?

我們最容易想到的,一定是玩家,怪物,寵物,坐騎,召喚物,陷阱,機(jī)關(guān),NPC等等能直接看見的對(duì)象。這一類對(duì)象,我們統(tǒng)一歸為場(chǎng)景單位對(duì)象。
除了場(chǎng)景單位以外,玩家在戰(zhàn)斗中,釋放的技能,產(chǎn)生的子彈,添加的buff,觸發(fā)的被動(dòng),均是對(duì)象。

以上所說的所有對(duì)象,通通在被包在一個(gè)叫做游戲場(chǎng)景,或者叫游戲地圖的對(duì)象中。

首先,我們讓玩家進(jìn)入游戲,玩家的對(duì)象實(shí)體,就被放在了這個(gè)游戲場(chǎng)景的不同的角落中。
好了,現(xiàn)在我們的游戲場(chǎng)景中有很多的玩家了,我們可以再讓服務(wù)器刷出來一些怪物,并把它們種在地圖上不同的位置
接下來,我們?cè)趫?chǎng)景中再放入一些機(jī)關(guān),陷阱,NPC等等。

游戲場(chǎng)景

單位行為

現(xiàn)在我們的游戲場(chǎng)景有玩家有怪物有一切游戲單位,那么我們?cè)趺醋屗鼈儎?dòng)起來呢?不知道大家小時(shí)候玩過需要上發(fā)條的玩具嗎?這種玩具會(huì)有一個(gè)設(shè)定好的行為,只要我們擰動(dòng)它的發(fā)條,它就可以按照設(shè)定好的行為行動(dòng)起來。

在游戲場(chǎng)景中,我們所有的場(chǎng)景單位對(duì)象,其實(shí)都可以類比成這一類的發(fā)條玩具。
對(duì)于場(chǎng)景單位的行為這一點(diǎn),我們可以稍微展開說一說:
一般來說,我們會(huì)對(duì)怪物,NPC,召喚物等指定一系列的行為,然后根據(jù)場(chǎng)景中的不同狀態(tài)選擇行為進(jìn)行響應(yīng)。一般這樣的系列行為會(huì)被組織成一顆行為樹或AI樹。(當(dāng)然,這里的AI和真正意義上的AI其實(shí)還差的很遠(yuǎn))。


行為樹

對(duì)玩家來說,玩家對(duì)象的行為則是由游戲前的玩家用雙手去操作的。玩家的操作通過鍵盤、鼠標(biāo)、或者手機(jī)屏幕的觸摸、滑動(dòng)傳遞到游戲客戶端,游戲客戶端再通過和服務(wù)器協(xié)定的通訊機(jī)制,把玩家的操作指令通過網(wǎng)絡(luò)發(fā)送到服務(wù)器的,服務(wù)器再把收集到的指令轉(zhuǎn)成玩家的行為,再賦予到玩家對(duì)象的身上。和其他單位相比,其他單位是由AI樹提供行為,和玩家對(duì)象由玩家提供行為。


玩家操作

好了,目前為止,場(chǎng)景有了,場(chǎng)景單位有了,場(chǎng)景單位要執(zhí)行什么行為有了,那么誰讓他們動(dòng)起來呢?

場(chǎng)景調(diào)度

我們都知道游戲的本質(zhì),其實(shí)就是計(jì)算機(jī)每幀計(jì)算出要呈現(xiàn)的畫面,最后以每秒24幀,30幀,或者60幀,或更高的幀數(shù)連續(xù)播放出來。同理,服務(wù)器為了和客戶端進(jìn)行同步,也有一個(gè)每幀進(jìn)行邏輯計(jì)算的過程,不同的是,客戶端每幀只計(jì)算一個(gè)本地場(chǎng)景,而服務(wù)器要計(jì)算N個(gè)場(chǎng)景(這取決于一臺(tái)服務(wù)器在保證計(jì)算效率的情況下能承載多少游戲場(chǎng)景)。

這個(gè)每幀進(jìn)行計(jì)算的過程,我們稱之為場(chǎng)景調(diào)度。簡(jiǎn)單來說,就是場(chǎng)景本身是不計(jì)算的,需要有人調(diào)度你的時(shí)候,你才能進(jìn)行計(jì)算。當(dāng)調(diào)度到你的場(chǎng)景的時(shí)候,就可以把場(chǎng)景里的所有單位的行為都執(zhí)行一遍。

那要如何調(diào)度,才能保證我們能把所有場(chǎng)景都調(diào)度到呢,這就不得不讓我們調(diào)度大哥出場(chǎng)了。讓我們想象一下,當(dāng)有多個(gè)場(chǎng)景的時(shí)候,這位調(diào)度大哥會(huì)指揮一堆場(chǎng)景進(jìn)行行動(dòng)。這個(gè)過程,大家是不是覺得有點(diǎn)熟悉呢?對(duì)!這不就是交通路口的交警叔叔所做的事情嗎?

我們就以交警叔叔為例子,假如我們有一個(gè)十字路口,有上下左右四條大道,中間有一個(gè)交警叔叔,來指揮四條大路,四條大路不斷來往車輛。


交警類比圖

交警叔叔每隔一段時(shí)間,就指揮一次上下左右四條大路進(jìn)行通過,指揮完了之后,就原地等待車輛通行。等到下一波車輛過來,交警叔叔再重復(fù)上面的動(dòng)作。
在我們的游戲場(chǎng)景中,場(chǎng)景調(diào)度器就相當(dāng)于我們的交警叔叔,每一輛準(zhǔn)備通行的車輛,就相當(dāng)于一個(gè)個(gè)游戲場(chǎng)景,為了讓多輛車同時(shí)通行,我們有四條大路,也就相當(dāng)于用來運(yùn)行場(chǎng)景的4根線程組成的線程池。交警叔叔每指揮一次就等待一段時(shí)間,等待車輛通行,這個(gè)過程就相當(dāng)于一次場(chǎng)景的調(diào)度,而調(diào)度完了之后,就會(huì)等待每幀運(yùn)行所需的時(shí)間,再進(jìn)行下一幀調(diào)度。

場(chǎng)景運(yùn)行器

一切都很順暢,交通井然有序,直到交警叔叔發(fā)現(xiàn)大家的車輛速度都不太一樣,有的是一腳油門就起飛的跑車,有的是裝滿砂石的貨車,有的是速度一般的家用車,大家的通過速度都不一樣。所以很快,交通發(fā)生了擁堵。


交警類比圖

交警叔叔很頭疼,怎么辦呢,交警叔叔自有辦法
交警叔叔把不同的車分成了不同的車道,規(guī)定同類型的車只能走同一條車道,并且交警叔叔還能規(guī)定每一種類型的車只能有多少輛。這樣一來,交警叔叔就能很輕松的把控每一條車道的運(yùn)行速度。比如砂石車跑得慢,那么同一條車道上,就只能出現(xiàn)4輛砂石車,而跑車跑得快,那么同一條車道里,就可以有更多的跑車。
當(dāng)然了,為了控制這個(gè)交通路口的運(yùn)行效率,交警叔叔一定要保證所有的車輛都能高效有序的通行,比如當(dāng)發(fā)現(xiàn)有三條車道都是砂石車道的話,就不然允許新的砂石車進(jìn)來了,等等限制措施。
這樣一來,在每一波車輛來了之后,交警叔叔都能通過自己的判斷,讓所有車輛的都能高效有序的通行

交警類比圖

那這樣的高效運(yùn)行的交通規(guī)則又如何應(yīng)用到游戲場(chǎng)景中呢?這就要提到我們的場(chǎng)景運(yùn)行器了。
理論上來講,有一個(gè)場(chǎng)景調(diào)度器,不停的調(diào)度我們的場(chǎng)景,把場(chǎng)景直接扔到一個(gè)多線程池子里,至于它具體在哪根線程上執(zhí)行,我們也不需要關(guān)心,這樣一來,我們游戲服務(wù)器上的場(chǎng)景就已經(jīng)可以跑起來了。
那這樣會(huì)有什么問題呢?和上面的交警叔叔的類比一樣,我們的場(chǎng)景中的有的運(yùn)行快、有的運(yùn)行慢,直接這樣無序的投遞線程池,我們對(duì)于整體的運(yùn)行效率是無法把控的,假如游戲要求一秒運(yùn)行30幀,那么一幀的運(yùn)算速度必須控制在33毫秒以內(nèi),那么如何分配場(chǎng)景,能讓這根線程上的所有場(chǎng)景在33毫秒內(nèi)執(zhí)行完,就是需要我們做的優(yōu)化。

在上面的舉例中,四條方向的大道我們可以認(rèn)為是線程池中的四根線程。為了讓每根線程在一次調(diào)度中把需要運(yùn)算的場(chǎng)景執(zhí)行完,我們就需要計(jì)算好一幀的時(shí)間能夠運(yùn)行多少場(chǎng)景:

  • 分配多了,那么這個(gè)線程這一幀還沒運(yùn)算完,下一幀將要運(yùn)算的場(chǎng)景又開始排著隊(duì)了;
  • 分配少了,那么這個(gè)線程就會(huì)有一段時(shí)間的空閑,造成線程資源的浪費(fèi)。

當(dāng)我們仔細(xì)分析就會(huì)發(fā)現(xiàn),同樣是游戲場(chǎng)景,不同場(chǎng)景的復(fù)雜度,其實(shí)是不一樣的,比如場(chǎng)景中我們又可以分為副本場(chǎng)景,工會(huì)場(chǎng)景,野外場(chǎng)景,主城場(chǎng)景等。我們完全可以根據(jù)不同場(chǎng)景類型,選用不同的場(chǎng)景運(yùn)行器,比如單人副本的場(chǎng)景,一個(gè)場(chǎng)景只有玩家一個(gè)人,那么我們就可以按人數(shù)來分配場(chǎng)景運(yùn)行器,同一個(gè)場(chǎng)景運(yùn)行器,就可以多容納更多的單人副本場(chǎng)景。而主城的場(chǎng)景中,一個(gè)場(chǎng)景里面里可能會(huì)有N個(gè)玩家,那么我們就可以限制一個(gè)場(chǎng)景運(yùn)行器中主城場(chǎng)景的數(shù)量,來保證這個(gè)場(chǎng)景運(yùn)行器的運(yùn)行速度。最后,我們把分配好的場(chǎng)景運(yùn)運(yùn)行器作為一個(gè)整體,再交給我們的場(chǎng)景線程池去執(zhí)行,這個(gè)時(shí)候,我們就基本能保證這個(gè)場(chǎng)景運(yùn)行器能在指定時(shí)間內(nèi)運(yùn)算完所有的場(chǎng)景了。我們需要做的事情,就是為了能夠合理分配我們的游戲場(chǎng)景,讓場(chǎng)景調(diào)度器在一次調(diào)度中,以滿足游戲邏輯運(yùn)算的速度來高效運(yùn)行

合理分配游戲場(chǎng)景,充分榨干多核CPU的性能,是每一個(gè)游戲服務(wù)器應(yīng)盡的責(zé)任

場(chǎng)景線程模型

我們通過以上對(duì)于游戲中的場(chǎng)景單位,單位行為,場(chǎng)景,場(chǎng)景運(yùn)行器,以及場(chǎng)景調(diào)度器的分析,最后,我們得到一個(gè)這樣的線程模型。當(dāng)然了,這肯定也不是最優(yōu)的游戲場(chǎng)景線程模型,這只能說是其中一種能夠高效利用多核CPU的場(chǎng)景線程模型。一個(gè)問題肯定會(huì)有著不同的解答,這才是設(shè)計(jì)模式的魅力所在

場(chǎng)景線程模型

現(xiàn)在再回到我們最初的問題:你和你的朋友們,你的網(wǎng)友們,是如何在游戲里一起愉快的玩耍的?,沒錯(cuò),你們就是存在于服務(wù)器上的每一個(gè)游戲場(chǎng)景中,而所有其他的玩家,也都和你們一樣,被分配在一個(gè)個(gè)的游戲場(chǎng)景中,被一個(gè)叫做場(chǎng)景調(diào)度器的老大哥以每秒30幀調(diào)度運(yùn)行。

后話

不知道這篇文章下來,我有沒有把游戲中的場(chǎng)景線程模型通過這樣一個(gè)白話文講清楚。寫這篇文章的最初,只是因?yàn)槲矣X得,任何一門技術(shù)都不是單獨(dú)存在的,在開發(fā)中,有很多的設(shè)計(jì)模型,其實(shí)都是來源于生活,或者說有很多開發(fā)中的設(shè)計(jì)模型,其實(shí)也能應(yīng)用于生活中。

仔細(xì)想想,如果是商店,銀行,游樂場(chǎng),是否也可以用類似的模型來設(shè)計(jì)一套接待系統(tǒng)?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容