天天看點

遊戲服務端開發之基礎概念掃盲篇

13年畢業後,做了一年多外包web開發,因為受不了在客戶現場工作的氛圍,憤然辭職。轉行做了一名手遊服務端開發。

在廣州,據我所知,選擇java作為服務端開發語言的公司大概有37互娛,百田,銀漢,易娛,要玩等等。其實遊戲服務端開發語言可說是百花齊放,c++、java、python、elang,不一而足。

記得剛入坑的時候,我連策劃資料和玩家資料都傻傻分不清,服務程序還天真地認為是tomcat啟動的。被策劃與測試聯手虐待了近3年後,我終于成為一名有經驗的“業務狗” (=。 =)

下面說一下手遊開發中碰到的一些名詞。這些概念都是自己了解的。剛入坑的朋友可以草率看一看,瞧一瞧。(^-^)

架構是簡單的伺服器架構,也就是說,大部分業務處理都是在同一個程序。沒有分布式服務的概念。

996

提起遊戲公司,比較閱聽人人認可的便是它高強度的工作時間。從剛開始的996制度(每天上午9點上班,晚上9點下班,中間休息2個小時,每周6個工作日),到後來的9106,甚至9116,簡直是殘暴剝削從業者的剩餘價值啊。不過,不加班的遊戲公司估計也沒多少人敢去上班,工資能不能按時發都是未知數了。也許有些人會說,遊戲行業工資高,獎金多。說點心裡說,雖然遊戲行業普遍工資是比較高,但綜合工作時間考慮,成本效益奇低。近幾年來,手遊行業發展迅速,每年都有非常多的手遊工作室成立,當然,也有很多手遊公司倒閉。總體來說,手遊這塊大蛋糕已被市場瓜分所剩無幾,特别是騰訊和網易兩個大廠就拿了七成左右。利潤減少,人力成本增大,導緻很多手遊項目的獎金已悄悄地被砍掉了,大部分項目成員最多就是年底拿個雙薪。(=。=)

策劃資料與玩家資料

簡單說來,策劃資料就是遊戲的規則,是由策劃配置的。玩家資料就是玩家在遊戲過程中産生的用于持久化狀态的資料,需要儲存在資料庫裡。關于策劃資料,有一點需要說明的是,策劃資料是不能被代碼修改的。一般說來,當服務程序一啟動的時候,所有策劃相關資料都會被load進記憶體。一些新手在開始做業務功能的時候,經常發生代碼不小心修改到策劃資料,導緻遊戲規則被無意修改了。這種情況對遊戲的影響非常嚴重,一旦出現,必定會被老大狂屌。當然,策劃職位也有可能填錯資料。曾經有項目因為策劃不小心把投放XX個銀币填成XX個鑽石,短時間就發生了嚴重後果,據說後來資料是采用“回檔”殘暴解決。

pve與pvp

簡單來說,pve(player vs environment),就是玩家與電腦ai對戰,包括各種關卡、副本等;pvp(player vs player),就是玩家與玩家之間真槍實火地對戰。一個遊戲,如果隻有純pve,是不能長期吸引玩家的,畢竟打電腦打多了就會沒意思。pvp一般都是一個遊戲的核心玩法,也是最不好設計的,要綜合平衡網絡延遲及戰鬥表現。時下很流行的一款休閑遊戲“貪吃蛇大作戰”倒是挺有意思的,明明是一款單機遊戲,居然能作出類似聯網對戰的效果。一開始,我還在驚訝于它的實時同步如此之屌,玩家的一個扭頭能夠及時同步到其他玩家的螢幕。然後,我試着把網絡給斷了,一切依舊運作得那麼完美!!整個遊戲除了排行榜分數是定時重新整理的之外,其他都是在本地用戶端跑,不過,能把ai做得這麼逼真,卻是非常有料的。

Socket服

遊戲主程序,遊戲的所有業務邏輯都在這裡執行。維持着所有線上使用者的socket連結。單程序的伺服器負責玩家所有業務處理,資料持久化等等。一般是采用多線程來處理使用者的請求,為了減少玩家請求的鎖競争,精心設計的線程模型非常關鍵。

網關

網關就是用于服務端與用戶端進行通信。跟socket服在同一個程序。使用者請求從用戶端發出之後,來到服務端,服務端經過業務邏輯處理,把資料傳回給用戶端。網關做的事情就是處理發包,解包,以及各種粘包情況。網關代碼一般都比較複雜,一旦穩定就不會輕易修改。業務代碼一般不需要跟網關打交道。

登入服

現在大部分遊戲都是分成很多個小區,以便在單程序的環境裡容納更多的玩家同時線上。用戶端手機通過管道sdk驗證後,就需要在登入服中根據平台與角色id找到玩家所在的服務分區。登入服一般是web項目,用戶端通過http請求,查詢玩家所在服務區的ip位址以及端口資訊。有了socket位址後,用戶端就可以直連socket服,完成登入邏輯。

gm工具

gm工具對于一款上線産品來說,具有不可或缺的重要性。既可以實作諸如開服關服之類的運維指令,又可實作提供給客服人員的查詢玩家資訊的接口,也可以輔助管理遊戲程序,實作動态修改遊戲邏輯的黑科技(熱更新)。總體來說,GM工具類似于遊戲的金手指,可以提供各種“作弊操作”和遊戲管理操作。

熱更新

對于一個上線産品項目來說,熱更新為維持項目的穩定健康提供了堅強的保障。小到策劃資料的修改,代碼bug的修改,大到動态擴充遊戲業務功能。試想一下,沒有熱更新機制,如果需要修改程式的一個小bug,都不得不踢人停服維護。這樣的事情來多一發,恐怕老玩家都被攆走了。比較有意思的是,我先前的一個項目,每次更新當日,一定少不了代碼熱更或者資料熱更,兩年裡的每一個星期都是如此,從無例外。可見熱更新的重要性了。關于熱更新的機制及方法,我的部落格裡有兩篇文章可以參考。

防挂

做遊戲背景與做web背景,關于防挂的防禦思想是一緻的。不管用戶端發什麼請求上來,即使是用戶端已認證自己的驗證,服務端都需要對請求參數進行有效性驗證。總不能說,用戶端說可以兌換100個物品,服務端什麼驗證都不用,就給角色加了100個物品。一定要有這樣的思想,用戶端完全可以通過修改包資料(加密隻能提高破解難度不能杜絕)來自定義請求參數,服務端直接處理來自用戶端請求的接口方法一定要有完善的參數驗證機制。寫的方法能否防得住挂,是區分一個初級業務狗和資深業務狗的重要标志。

使用者資料持久化

玩家的資料需要儲存到資料庫,如果一下線資料就被重置,那麼玩家每天練級還有什麼意義。比較主流的資料持久方式有兩種,一種是針對每一個功能子產品都建一張表,隻要有一個userId作為外健能關聯到User主表即可;另外一種是不差別邏輯分表,對User類的所有依賴實體(包括實體及其遞歸依賴),全部映射成字元串或者二進制。兩種做法都有優缺點。邏輯分表的優點是子產品分層定位清晰、可讀性強、容易通過sql修正玩家資料等;缺點是建立子產品必須手動建表,實體字段必須增加表屬性才能完成持久化。實體映射的優點是,隻需一張表即可完成全部資料的持久化、建立屬性實體或字段不需要額外修改表結構;缺點是可讀性差,如果存為二進制的話更無可讀性可言,而且修複玩家資料隻能通過修改程式記憶體而不能直接執行sql語句。

另外一方面,由于資料庫連接配接的資源非常可貴,不可能玩家每一個請求都需要load使用者表。一般都是玩家登入的時候就将玩家相關的使用者表全部load進記憶體。服務端有一個定時器檢測,當玩家在一段時間内沒有發請求上來,認為該玩家已經下線,相應的資料再回寫到資料庫。這樣實作的話,對資料庫的壓力就變小了很多,而且在很短的時候内頻繁上線下線也不會觸發多次讀取資料庫。

遊戲更新與維護

手遊的更新節奏是比較頻繁的,每周一更,每兩周一更,最長的周期應該是每個月一更了。很多遊戲喜歡把更新時間設在深夜或者淩晨,目的是想避開高峰時期,争取更長的開放時間,這可苦了我們這些做遊戲的人了。無數次晚上加班到兩三點或者早上6點就得趕往公司,往事不堪回首。遊戲的伺服器一般都是部署在Linux系統,是以常見的Linux指令都會熟悉。

結束語

最後,寫給即将走進遊戲服務端大坑的朋友們的心裡話。遊戲開發這個職位雖然外表華麗,個中的辛苦與苦逼隻有局中人才能了解。如果兩年後發現自己還在辛勤寫着活動業務邏輯,從未碰過大型功能玩法(例如跨服賽事,戰鬥同步等),那你應該好好思考一下,自己是否适合繼續從事遊戲開發,或者這家公司值不值得你繼續留下來。如果有志往資深遊戲開發的路走下去,建議研究一下分布式遊戲開發。畢竟,這年頭,分布式還是很前沿,逼格很高的玩意。

手遊服務端開源架構系列完整的代碼請移步github ->>  jforgame