零、快速入門
【套接字API】
1. socket():因爲還不會生成新的TCP連接,所以不存在TCP連接狀態;
2. connect():SYN→SYN/ACK→ACK(三次握手);
- 主動打開 – 客戶端調用發起連接;
- 被動打開 – 服務器被動建立連接;
3. bind():不會生成新的TCP連接,只是設置本地生成的套接字的監聽端口號;
4. listen():“被動打開”後,服務器進入Listen(待機)狀態,等收到客戶端發來的SYN數據包後就會開始生成新的套接字;
5. accept():在建立TCP連接(處於ESTABLISHED狀態下的新通信鏈路)後,獲取連接的套接字的文件描述符用於通信;
6. read()/write()/send()/recv()/sendto()/recvfrom():用於實際的數據收發,必須在ESTABLISHED狀態下;
7. shutdown():通知OS不要再寫入/讀取數據了。
SHUT_WR側發送FIN→接收方返回FIN並進入CLOSE_WAIT→SHUT_WR側收到返回FIN/ACK並釋放通信鏈路→接收方收到關閉通信鏈路;
8. close():等同於調用shutdown(SHUT_RD|SHUT_WR)來同時關閉讀寫雙方.
【各網絡層頭信息】
- ocet: 8位位組,因爲部分機器”一個字節(byte)不等於8位(bit),以下單位皆爲ocet;
- 以太網幀: 前導碼(7) + SFD幀首定界符(1) + 目的地址(6) + 源地址(6) + 長度/類型(2) + 數據/LLC(46~1500) + FCS幀檢驗序列(4);
- 4層傳輸層: TCP(20) + 3層網絡層–IP(20) + 2層數據鏈路層–以太網協議(26) + 物理層(1層) = 66ocet包頭大小;
- 數據塊: OSI參考模型,若發送小數據塊,則頭信息將佔據大部分通信,加重物理層負擔;若用1400字節的大數據塊,則可達理論速度;
- 網絡遊戲數據塊: 數據單位有時不得不20個字節左右,性能只有理論的幾分之一.如100Mbit/s發送最小的數據時可達148810次;
【UDP的使用】
- 發送那些與可靠性相比速度更爲重要的數據;比如FPS中移動消息,因TCP在數據丟失是會重發從而造成較大的通信延遲,UDP不會重發.
- 爲了實現NAT遍歷功能;
【多核與線程】
- 客戶端:根據音效處理、AI、網絡、主循環、渲染等方面,用3~5個線程;
- 邏輯處理最好不要使用多線程。
【提高開發效率】
- Windows下開發,Linux部署;
- 服務端 和 客戶端在碰撞檢測等方面使用相同的遊戲處理代碼;
- 使用封裝保持源代碼級的兼容性;
- 降低OS差異性的封裝工作;
二、何爲網絡遊戲
【商業層面的要求】網絡遊戲是製造業+服務業
- 有趣:
- 儘早開發出原型並迭代;
- 有效招募玩家儘早測試(解決明顯不佳的平衡性; 無趣/引起不滿的遊戲內容):
- 封測(平衡性,服務器負載等):500~3000名測試2~6月的試玩;必須充分測試(一經發行就遭遇失敗的遊戲是無法復興的)
- 公測(宣傳營銷目的,不限人數):系統負載與正式服務是等同的
- 不斷更新,運營時間久(具有可擴展性),評價高(提供多種收費選擇)
- 定期補丁:常規bug修復,細微的平衡性調整,系統改進等.(公開測試服供嚐鮮玩家試玩);
- 大型擴展:追加與之前有極大差別的遊戲系統新玩法等(需準備測試服,爲避免泄漏,會嚴格限制人數);
- 緊急維護;
- [分別設置問題修復+新內容開發團隊; 儘可能分離源代碼和數據內容; 模塊化,避免干擾]。
- 降低成本(減少服務器數量;節約帶寬;從小規模開始,確保可擴展性);
從小規模開始–將風險降到最低,不要錯過取勝機會; - 希望有大量玩家參與(適配多個平臺;發行多國版);
- 不給玩家添麻煩:
- 低成本、儘早可靠地消除攻擊者,比如防止打金外掛 – 因其佔用服務器併產生大量流量;
- 根據情況增加GM巡視;
- 日誌分析;
- 調整經濟系統;
- 減少停服:”服務器停一次,就會流失%1玩家”; 計劃內停服維護影響不大;
- 遊戲平衡和經濟缺陷:立刻修復, 回滾, 封號等處理; 一定要即時精準;
- 服務器崩潰:不可避免,應根據遊戲類型充分準備; 實現自動重啓機制;
- 超負荷:設計時要做到部分設備超負荷不會影響到整體; 設法減輕符合; 超負荷時通知運維和用戶;
- 低成本、儘早可靠地消除攻擊者,比如防止打金外掛 – 因其佔用服務器併產生大量流量;
- 更佳的用戶體驗:
- 頻繁進行各類活動,使玩家能長時間遊戲不會厭煩;
- 反饋遊戲結果:遊戲元信息 – 排行榜; 成就; 其他統計; 記錄並提供給玩家;
- 促進玩家間的交流;玩家間更易相遇
- 玩家匹配:”網絡遊戲是一種交流工具”; 自動選擇(根據各種條件快速匹配) 遊戲大廳 虛擬世界(可實時交流)
【人員和組織】 開發人員:80% 運維:20%
- 開發(策劃,程序,美工,測試,工具製作) 小型2~4人;多數情況20人左右;大型150+;
- 運維(安全,負載,OS管理,數據備份,緊急情況處理);
- 銷售(市場調研,商業調研,資金籌備,質量保證,營業活動,活動舉辦,商業數據分析等);
- 開發團隊不可或缺的4中職業:項目總監(統籌管理), 程序, 美術, 策劃
- 多數20人團隊配置:總監2人(技術,美術) 程序4人(架構,底層,邏輯,工具) 美術6(角色,動畫,地圖)建議外包 策劃8人(關卡,劇本,腳本);
- 不同類型,人員配置不同; 小型企業需避開電影式遊戲,選擇工具/社交等小型遊戲;
【所需技術與經驗】
- 編程基本技術:
- 設計:技術(結構化,模塊化,面向對象,設計模式等); 任務(併發性,事件驅動,錯誤處理,容錯性,可用性); 質量(定義, 基準, 檢測); UML;
- 架構: 管理(計劃,預算); 編碼(多語言,安全模型,內存管理,文檔化,優化); 複用(儘量利用已有資源); 質量(單元測試,組合測試);
- 測試: 功能,性能,負載,安裝,可用性等各種檢測; 管理(測試計劃);
- 維護: 現有代碼的修復,移植,交接,文檔化,說明書;
- 編程基本知識:
- 版本管理,自動化構建/測試;
- 排序算法; 加密算法; AI(狀態機/行爲樹);
- 嵌入式腳本Lua Python等;
- 特定遊戲類型的知識(動作,RPG,射擊,卡牌,冒險,策略,競速等不同遊戲,基本架構差別很大);
- 數據庫知識: SQL, 查詢優化, 高速緩存, 擴展性
- 系統運維知識: 各種業務流程(通告,數據入庫,用戶管理,維護等); 服務器部署; 負載均衡; 數據備份/恢復; 服務器監控;
【支持網絡遊戲主體的3大核心】
- 數據形式:
- 一次性的(每次初始化後就丟棄);
- 持久化的(持續存在於服務端); 格鬥競速持久性短,MMORPG存續時間長
- 通信方式:P2P; C/S
- 響應速度(延遲):
- 25ms以下(MOBA,格鬥等實時對戰);
- 100ms以下(FPS,戰略遊戲);
- 300ms(MMORPG等動作性少的C/S遊戲中)
三、網絡遊戲的架構
【遊戲編程特性–保持快速響應】
- 遊戲編程三大痛苦:
- 遊戲數據要在“16毫秒”內持續變化;
- 大量對象的顯示直接關係到可玩性;
- 不知道會在何時操作,無法事先計算;
- 網遊特有要素:通信延遲; 帶寬; 服務器(成本,數量估算); 安全性; 輔助系統;
四、C/S MMO遊戲開發
【基本流程】
- 項目文檔:如圖根據先後順序列出的流程所需文檔;齊備的文檔能大幅降低失敗概率。邊編文檔邊聚集必要的程序。
- 開發的進行和文檔準備流程;
概要設計 → 評估 → 詳細設計、工作量列表、開發日程、開發原型 → 確定程序和數據形式,開發管理/運營工具 → 籌備服務器,構建運營體制 → 實現收費系統 → 內部測試(不含玩家的多人測試) → 限制人數的內測 → 公測 → 收費 → 每隔幾個月內容更新 - 技術文檔:程序(開發工具,單元測試,bot,UML,時序圖等) 數據(遊戲設定,音視頻) 測試(操作手冊,性能測試結果) 運營(管理工具,運維操作手冊)
【MMO發展趨勢和對策】
- 特有遊戲內容:處理大量數據; 向玩家嚴格保密設定信息; 嚴格維護遊戲數據的更改; 設定信息更改容易; 易於結合SNS等其他服務系統;
- 架構的限制:延遲較大; 服務器帶寬負荷高; 服務器維護費用高; 服務器停止時間無法遊戲;
【策劃文檔和5種設計文檔】
- 概要設計:簡單概括出遊戲的核心要素和玩法;
- 詳細設計:沒有完備的詳細設計開發出來的遊戲,最多隻能是原型,而非最終產品;
- 核心要素:聊天、公會、戰鬥、NPC、消遣、地理、拍賣行、排行榜、互動場景、持有物、物品、經濟、原來、結構、付費、小遊戲、小任務、音樂、玩家PK、婚姻、家園、任務、隨機事件、規則、限制、技能、裝備 等要素列表;
- 細化單項:比如(伐木技能 → 樹類型; 斧頭類型; 技能等級; 關聯製造品如弓箭、船等等);
- 必要條件:”全部的設定要素有多少?” “各種要素間存在怎樣的關係?” “某個數值與另一數值全部被定義”;
- 技術上,必須準備相關的文檔、設法降低程序和數據間的耦合度、開發用於測試數據一致性的工具及用於高效製作大量數據的工具等;
- 五種設計文檔:
- 系統基本結構圖;
- 進程關係圖;
- 帶寬/設備資源估算;
- 協議定義;
- 數據庫設計圖;
- 設計上重要的判斷:
- 一概不採用實時性高的策劃內容;
- 並行啓動多個內容相同的遊戲世界,不與朋友在同一世界遊戲也沒關係;
- 延遲200~500ms也無關係(探索,經濟活動,戰鬥等); 不需要頻繁發送其他玩家動作方面的數據; 敵人行爲調整得較慢,邏輯負荷小;
【系統基本結構圖的制定】
- 基礎:
- 確定期望的同時連接數,以及收費等商業模式;
- 確認預想的瓶頸內容,並選擇用來避免瓶頸的擴展方式;
- 可擴展性:遊戲發佈時將服務器限制在最低程度,之後,必須能在不改變程序和設計的情況下,簡單地增加服務來加強遊戲對大量玩家的支持; 各種瓶頸:
- 客戶端渲染性能瓶頸: 磁盤到主存(非常緩慢,毫秒計); 主存到GPU內存(較慢,微妙計); GPU內存內部傳輸(非常快,納秒計);
- 不要”一口氣讀取所有必需的數據”,而是在保持幀速率的情況下花時間一點點讀取;
- 即使在讀取紋理數據的過程中,也儘量只先進行輪廓的渲染,只對所處位置有所瞭解;
- 用戶側帶寬瓶頸; 服務器邏輯處理性能瓶頸; 數據庫寫入性能瓶頸:
- 空間分割法(遊戲世界地理分割多服務器/進程處理);
- 實例法(將負荷高的部分獨立到專用服務器處理,如遊戲副本實例);
- 平行世界(即新服。數據庫並行化分割,會造成玩家自己無法在各世界間移動,玩家交流也被切斷了);
- 客戶端渲染性能瓶頸: 磁盤到主存(非常緩慢,毫秒計); 主存到GPU內存(較慢,微妙計); GPU內存內部傳輸(非常快,納秒計);
- 估算(實例查看P197):同時在線數 → 確認瓶頸 → CPU消耗(同時在線數×各玩家面對的敵人數×敵人每秒行動次數×每次行動所需CPU時間×安全係數2 = 1秒) → 數據庫處理負荷(同時在線數×各連接的平均數據存儲頻率×1次存儲所需的查詢數×安全係數2 = 數據庫服務器總共的可查詢頻率)
- 例子:3萬玩家,每人面對20個怪,策劃設定玩家速度爲5次/秒,測定每次行動需10微秒,代入公式,單核可承載500玩家,則3萬/500=60核;
- 3萬玩家1分鐘存儲1次數據(3萬×(1/60)×10×2 = 10000),假設測定的Mysql實際速度爲2000次查詢/s,則平行世界所需數量=5;
- 制定系統基本結構圖;
【進程關係圖的制定】
- (空間分割法)服務器連接的結構:
- (平行世界法)服務器連接的結構:
【服務器資源估算文檔的制定】
- 以進程列表爲基礎估算:
- CPU頻率與核心;
- RAM內存;
- 存儲器如硬盤;
- TCP會話數;
- 以CPU爲中心和以存儲爲中心的服務器:
- CPU爲中心 :CPU較快,內核較多,內存一般,存儲量少,容錯性低。一次性的;
- 存儲爲中心:CPU一般,內核一般,內存高,存儲量大,容錯性高。使用期長;
- 服務器資源的成本估算,先從初期費用開始;
- 帶寬成本的估算:節省方案(策劃的調整; 程序上下功夫);
【協議定義文檔的制定】
- 協議:進程與進程之間以怎樣的順序交換怎樣的內容;
- 協議的基本性質:
- 哪些作爲服務器,哪些作爲客戶端;
- 永久還是一次性連接;
- 是否需要在服務器端管理會話狀態(是否是有狀態的);
- 是否有必要管理認證狀態;
- 1對1? 1對多? 多對多?
- 是否需要推送(Push)消息;
- 連接中斷時是否需要立即結束服務;
- 協議、進程間關係的種類:見表4.5(P213); 協議名根據”連接到哪臺服務器”來決定,比如dbsv被gmsv、loginsv、msgsv連接,但都稱爲”dbsv協議”;
- 各進程類型的協議與”協議的基本性質”的對應:
- 左側的列表示[客戶端]; 上面的行表示[服務器];
- 基本所有都是永久性連接,不是的會註明”隨時連接”;
- “stateful” – 需要在服務器管理各個會話的狀態;
- “auth” – 需要管理認證狀態;
- 1對1, 1對多, 多對多 – 1:1, 1:n, n:n;
- “push” – 表示需要推送消息;
- “critical” – 連接中斷需立即結束服務; 不需要記爲”harmful”;
- 協議涉及的基本策略:
- 在與後端通信時應儘可能無狀態;
- 採用永久連接,因爲每次開始TCP會話開銷很高;
【協議定義文檔–協議的基本性質】
- 實現原則:
- 後端實現基本的、通用的功能, 前端實現專用功能;
- 採用前端依賴於後端的結構;
- 協議是無狀態和簡單操作的集合;
- 在一個地方接受外部異常(比如數據都用dbsv);
- 優秀API的調用時序:
- 不調用更好;
- 調用但無返回值;
- 調用一次後獲取返回值的呈三角狀的時序圖;
- 呈鋸齒狀的時序圖;
- 有必要推送嗎?好好考慮,儘量不用,若使用,應在調用處的附近管理函數返回。
【協議定義文檔–協議的API規範(概要)】
- gmsv協議:負責執行管理敵人行動、事件、角色升級、作弊檢測等遊戲邏輯;
- [通知]反映了只調用無返回的”單向時序圖”,比如來自cli的鼠標移動角色的通知API;
- [請求]反映了調用1次期望返回1次的”三角狀時序圖”,比如來自cli打開物品欄獲取物品列表的API;
- [推送]比如敵人行爲,即使cli沒發任何指示,gmsv仍需每秒發送數次通知;
- loginsv協議:cli登錄管理,負責服務整體使用情況的管理、負載控制以及分配會話祕鑰;
- msgsv協議:用於使聊天、即時消息、公會等社交活動能跨越平行世界/空間分割來進行消息交換的服務器; 分三種API:
- [通知]聊天輸入,好友添加請求等;
- [請求]獲取好友列表等;
- [推送]好友上線通知; 其他玩家的聊天分發等;
- dbsv協議:對MySQL等DBMS進行統一的連接;在異步訪問數據庫時,實現必要的負荷降低處理;將各表的CRUD操作作爲API來提供:
- [通知]來自前端服務器諸如玩家角色保存等操作,不需要返回值;
- [請求]來自前端服務器的查詢,比如玩家角色的加載;
- worldsv協議:使用【空間分割法】時,屬於世界的所有gmsv都連接到該服務器進程上,負責爲各個世界提供通用處理:
- [通知]來自gmsv的通知,比如保存所有在線玩家的座標;
- [請求]來自gmsv的請求,比如獲取包括其他gmsv在內的所有玩家座標;
- commondbsv協議:使用【平行世界方式】時,對所有世界共同需要的信息進行持久化;比如保存用戶ID、密碼、好友列表等與世界無關的:
- [通知]比如gmsv通知其當前在線人數;
- [請求]來自loginsv、msgsv、gmsv的請求,比如獲取各服在線人數;
- 非平行世界不需要commondbsv,而應由dbsv實現;
- authsv協議:調用結算公司提供的API,相當於與結算公司間的網關,比如獲取是否成功收取了某玩家費用;
- logsv協議:通過TCP收集整個遊戲服務中的日誌,根據時間順序羅列,保存在文件中,用於檢索; 只提供”日誌寫入”,只通知無請求和推送。
【協議定義文檔–協議的API規範(詳細)】P223
- API的函數定義(參考P224):各個服務所提供的API,也就是函數。這裏講解部分具有代表性的API定義.
- API的調用時序:規範更改不可避免,一開始制定完整的時序圖並不划算,但應對最低限度的模式進行確認. 表4.9(P230) <協議儘量無狀態>
- 必要的時序圖:
- 驗證;
- gmsv中角色創建;
- 登錄gmsv、msgsv;
- 從gmsv登出;
- gmsv中的角色移動;
- gmsv中角色的商業操作(購物、交易);
- msgsv中向好友列表添加/刪除好友;
- 向在線後右發送消息;
- 編程前對這些事務的時序圖進行繪製並加以確認,可避免以後發生一些難以更改的時序上的問題;
- 複雜性(條件分支和異常處理等根據情況不同而有所差異的程序所特有的處理)儘可能集中在網絡的終端,也就是cli側;
- 各必要時序圖詳見(P232-P237);
- 時序圖制定的要點:只有gmsv、msgsv、loginsv等前端服務器保持狀態,並向作爲主體的後端服務器和客戶端收發各種消息,後端被動應答;
【協議定義文檔–數據包的格式】
- C/S MMO主要採用TCP;
- C/S MMO使用包含專用字節數組的二進制協議(“處理負荷較低”; “耐得住更改和攻擊”; “良好的開發效率”)
- 二進制協議的實現(從術語的整理開始):
- ”TCP流”由一系列0~1400字節左右不定長的”TCP數據包”組成; 最大長度1460字節;
- 記錄的大小:用戶通過鼠標/鍵盤輸入,字節數不多(數十字節左右),但發送頻率高,傳輸量也不小;
- 數據部分的壓縮和加密:壓縮–雖然會對CPU造成一定負荷,但會大幅降低帶寬傳輸量; Snappy、LZO(壓縮解壓縮快,消耗CPU較少);
- 加密–用RSA和Diffie-Hellman等方式共享祕鑰,會話期間持續使用;
- 爲了提高壓縮率,加密一定要在壓縮完成後進行;
【數據庫設計圖】
- 編程前要對重要的表進行設計;
- 鍵值存儲數據庫KVS:如MongoDB(無模式、只有簡單的查詢、高速、無事務功能<收費和驗證等輔助系統需要事務功能>);
- 在確認策劃內容的同時,記錄下需要持久化的要素的特性和內容;
- 瞭解保存可變長度數據的必要性; 詳見表4.10(P248);
- 表數量越少越易於管理; 需另外建表的數據特性(1.相關信息的數量對各玩家來說差異很大如物品; 2.條目數會不斷增加如任務);
- 數據庫性能預測:
- ①查詢類型:a.指定主鍵,只取1行; b.使用主鍵在內1個以上索引,以一定條件檢索、排序<儘量少用>; c.不使用索引<不要採用!!!>
- ②各表特性與預測: 詳見表4.11(P251)
- ③對拍賣/郵件等歷史信息很重要、需要檢索的表中採用[查詢類型b];其他都用類型a,對於類型a,具備KVS的功能就足夠了;
- ④read:除了日誌,其他表的訪問模式都是10分鐘/次;
write:
- 用戶表基本不寫入;
- 角色、物品、任務日誌1分鐘/次,是read頻率的10倍;
- 日誌表,10秒/次;
- 其他表都是1小時~1天/次,頻率低,不會成爲負荷;
read注意”拍賣” “郵件”; write注意”角色” “物品” “任務日誌”;
- ⑤拍賣:典型實現方法–分爲兩個表; “拍賣物品表”(每行對應一個拍賣物); “競價表”(每行對應藝名買家的競拍價);
買家查詢拍賣物時顯示列表、獲取某個拍賣物的競價列表 這兩種處理的負荷較高; 優化,新上架物品延遲10~20秒關係也不大;
【服務器/客戶端軟件+中間件】
實踐中不可或缺的開發基礎:ProtocolBuffer等;
【程序開發中的基本原則】
- 數據結構優先:構成遊戲世界的數據結構要在編碼前大致確定下來;
- 維護可玩狀態:經常試玩遊戲,在對可玩狀態確認後繼續進行開發;
- 後端服務器延後:以客戶端 → 前端遊戲服務器 → 後端服務器的順序開始開發;
- 服務器持續測定:經常對延遲、帶寬、CPU時間進行測定,將其表示出來,以此爲參照進行開發;
【實現–編程開始】
- 開發安排:
- ①框架階段:編寫cli, gmsv, dbsv, 最低程度能進行測試的1組與遊戲本質內容無關的程序; (1名主程1周時間); 詳見表4.12(P269);
- ②原型階段:保持運行狀態,持續擴展和調整;開發1個自動對服務器測試和1個可進行遊戲的客戶端; (1+1客戶端程序); 框架見表P270;
- ③整體實現:若確認遊戲具有可玩性,開始製作開發工具,dbsv以外的後端服務器; (2~4程序)
- ④量產階段:進行遊戲數據的量產;
- ⑤收尾階段:修正Bug,調整平衡性,試玩等開始準備正式運營;
- ⑥試營後階段:並行實施用戶支持和補丁的追加;
- 進度管理形式:
- 1~2階段[文本文件];
- 2~3[xls文件];
- 3~+[項目+跟蹤管理工具如JIRA]
- 遊戲特殊性:”不實際運行起來是不會理解的!” [可玩,滿足性能,通信,數據等開發要素]
- 框架整體結構:如SDL渲染庫; boost; cli, dbsv, gmsv所有源碼; proto協議定義文檔及生成的原文件; 詳見(P276)
- 首先編寫cli與gmsv的協議定義文件,先完善cli測試bot直到通信順序和參數沒什麼大問題時再實現客戶端;
- 協議定義要點: ①通信連通確認; ②賬號登錄; ③賬號驗證; ④角色創建; ⑤角色登錄; ⑥角色移動; ⑦角色攻擊;
- 移動:
- 以方格爲單位;
- 路徑搜索和實際移動處理;
- 移動路徑的發送方式(優先發送最終結果);
- 移動通知範圍;
- 自動測試客戶端:(P300);
- gmsv中線程的使用:(P305);
- 圖形客戶端cli的創建和運行確認;
- 框架之後的開發:
- ①充實遊戲設定數據;
- ②增加影音特效改善界面;
- ③用於高效的服務器啓動和版本管理等的工具;
- ④用於分析遊戲結果/查找問題的日誌解析工具;
六、網絡遊戲的輔助系統
【輔助系統需要的功能】
- 現有的通用服務,如Steam、Uplay、AppStore等;
- 功能一覽,詳見表6.1(P364);
【交流/通信功能】
- 玩家匹配:P2P MO遊戲中查找對手玩家;
- 遊戲大廳:P2P MO遊戲中玩家查找對手;
- 中繼服務器:解決有NAT問題的P2P MO遊戲玩家通信問題;
- 聊天功能:客戶端 → 聊天服務器 → 服務器推送(1~2秒內)(不要給不在線的玩家發送)(不需要保存日誌);
- 郵件;
- 好友列表;
- 玩家狀態:登錄/退出(絕不能省略), 所在服務器/位置(儘量別省略), HP變化/擊殺敵人的名字等(可省略);
- 加鎖服務器:防止雙重登錄、數據損壞或無限增長的情況;
- 黑名單:”客戶端”服務器消息全發送,客戶端決定是否顯示; “服務端”聊天郵件等功能結合,會加大處理負荷;
- 語音:1人發言需10kbit/s左右,向5人發送要佔用50kbit/s; 實際遊戲中同時發言玩家並不多,可根據該特點設計;
【客戶端實現相關的輔助系統】
- 玩家成績管理:如何防止作弊、怎樣在之後追加遊戲成績;
- 存儲功能:需防止作弊、DB碎片化; 可通過用戶ID進行橫向分區;
- 客戶端更新:利用現有服務、Bt等工具實現,注意帶寬、文件一致性; 訪問更新服務器 → 版本對比 → 下載 → 校驗 → 更新 → 重啓;
- 排行榜:
- 使用DBMS時,增加”rank”列,排名前100的數據每次都重新排序並實時更新結果,其他數據排序和更新每天1次;
- 內存中處理,每次都進行排序,但不能處理大於100萬行的數據;
- 臨時排名法:找出”在比自己分數低的玩家中,分數最高的玩家的排名”然後加1;
【運營輔助系統】
- 新聞發佈:有限定時間、自動更新、已讀管理等問題;
- 客戶端版本比對時更新顯示;
- 遊戲開始時,彈框遮擋開始按鈕;
- 遊戲中,如郵件紅點/商店購買東西時提示;
【付費相關的輔助系統】
- 付費認證:a.付費機制(包時/月; 付費道具; 虛擬貨幣); b.支付序列圖(P386圖);
- 虛擬貨幣管理:功能需求(總額顯示; 交易記錄; 即使故障也不會輕易丟失);
- 交易日誌(交易ID; 玩家ID; 增減值; 原因; 日期);
- 定期維護歷史記錄,比如備份數據庫,刪除過期(如1年前)的數據等;
【其他輔助功能】
- 遊戲數據查詢工具:最低要求–能以便於閱讀的形式瀏覽玩家的遊戲數據,並具備關鍵詞、時間、項目或角色數值查詢的功能;
- 遊戲數據的保存:
- ①劃爲不同數據列;
- ②BLOB;
- 兩種混用;
- 需要索引的數據用方式①,其他以方式②保存;
- 遊戲設定數據和數據庫–使用KVS這樣的ODBMS(對象數據庫)更適合;
- 遊戲數據的保存:
- 敏感詞過濾:與黑名單的區別–①不需要用戶動態增加關鍵詞; ②敏感詞用戶不可見; ③無需實時更新;
七、支持網絡遊戲運營的基礎設施
【基礎知識】
- 基礎設施架構需要進行的工作(從開發整體來看):
- a.策劃概要的決定;
- b.程序設計;
- c.基礎設施的大體估算;
- d.程序實現;
- e.基礎設施估算;
- f.詢問報價;
- g.報價評估、下訂單;
- h.決定日程;
- i.架構;
- j.負荷測試,調試,反饋;
- k.上線;
- l.開始運營;
- m.設備和服務更新;
- 硬件、信息設備:服務器, 存儲設備, 路由器/防火牆;
- 軟件:服務器OS(Red Hat / CentOS), 數據庫(MySQL / Mongo), 殺毒軟件, VMware;
- 服務費:監控服務; 域名使用費、電子簽名服務費;
【架構技巧】
- 規模擴大/縮小:對於MySQL等數據庫服務器,調整風險和成本較高; 對於gmsv等前端服務器,調整容易;
- 典型環境:
- 初始環境(公司內部搭建的小規模服務器);
- 數據中心(機櫃中設置自己購買的服務器);
- 雲服務;
- 負荷曲線:初始設計應考慮峯值的應對;
- 服務器部署:測試服務器程序 → 打包 → 上傳 → 暫停用戶登錄和註冊 → 強制退出遊戲 → 停止舊版本 → 備份數據庫 → 需修正數據庫時運行相應的SQL批處理 → 確認數據庫 → 啓動新版本 → 自動+手工測試 → 開放服務器
- 登臺環境:與正式服環境相似,用於測試新版本; 需注意防止版本發佈誤操作; a.面向開發者; b.面向特殊設定的一般用戶;
- 監控:
- OS: 設置MRTG, 監控CPU&內存&硬盤使用率, 進程數, 通信量等信息;
- 數據庫: 大小, 進程, CPU, 規定時間內能否執行完特定SQL查詢, 是否有慢速查詢, 單位時間處理的查詢數;
- 應用: 通過HTTP只返回給監控服務器(同時在線數, 內存中對象數量, 單位時間內主循環的處理次數);
- 用戶行爲: 影響遊戲平衡的惡意行爲, 不良商家或玩家的行動(比如金幣增加最多的10位, 發送過禁止詞彙);
- 日誌管理:
- ”儘可能保留所有日誌” “原因和結果都保留”:
- 道具交換/獲取/使用;
- 玩家技能使用/獲得;
- 經驗/HP等角色狀態變化;
- 對敵人造成的傷害/技能效果;
- 與商店NPC的所有對話;
- 登錄登出記錄;
- 地圖跳轉記錄;
- 日誌輸出方法:
- 通過標準輸出中的管道傳輸給其他進程或在文件中保存;
- 寫入文件並傳送給其他工具;
- 通過網絡發給服務器;
- 寫入syslog;
- ”儘可能保留所有日誌” “原因和結果都保留”:
【負荷測試】
- 篩選關鍵點測試:
- 超負荷會造成致命影響的部分;
- 發佈後不易修改/橫向擴展的後端部分;
- 關鍵創新玩法;
- 具體測試場景:
- 創建大量用戶,保存遊戲信息;
- 用戶登錄;
- 隨機移動、發送消息5秒/次;
- 用戶退出;
- 測試的分解:
- 測試後臺服務器負荷時使用多臺遊戲服務器;
- 在1臺遊戲服務器上測試最大同時在線數;
- 監控命令:①vmstat; ②/proc/interrupts; ③ps; ④top; ⑤netstat;
【遊戲上線】
- 上線前:
- ①防止系統外部攻擊的安全設定:
- 數據包內容檢測(固定字段);
- 每個IP地址的連接/帶寬限制(路由器防DoS);
- ②系統內部管理相關的安全設定:
- 遠程連接服務器用SSH登錄;
- 只對部分人員開放服務器訪問權限;
- 參考網絡安全相關書籍;
- ①防止系統外部攻擊的安全設定:
- 上線後:
- ①服務器進程因Bug當機–準備好自動啓動的腳本;
- ②服務器進程在高負荷下無法訪問–管理程序通過HTTP連接查看運行狀態,若無反應或超負荷,SSH登錄服務器Kill進程(腳本化);
- ③服務器不能訪問–一旦不能訪問立即重啓;準備好預備服務器,可隨時更改路由器的NAT設定進行快速切換;
- ④因Bug原因保存了異常數據:
- 簡單回滾數據;
- 運行問題解析腳本修復;
- 手動執行SQL修復;
- 服務器組羣化:使用腳本、容器等方法減少操作,降低失誤;
- 故障應對:
- 程序: a.等待; b.重啓程序/數據庫/OS/服務器; c.更改設定文件; d.發佈更新; e.修改數據內容; f.修改程序;
- 非程序: a.搜索日誌; b.查看/修改數據庫內容; c.更改設定文件; d.重啓;
八、網絡遊戲開發體制(團隊管理的挑戰)
【特有的挑戰】
- 遊戲數據的持久化:
- ①運營剛開是的3個月最困難,運營可持續5~10年;
- ②遊戲的運營和技術人員–合理安排工作和計劃,防止頻換更替人員;
- 要點:
- 希望長期參與項目的人是否有相關技能;
- 如何合理使用項目完成後想立馬參與新項目的人員;
- 運營後團隊的休假計劃如何安排;
- 項目獎金該如何設置;
- 遊戲中玩家關係:
- 對抗–可互相攻擊/破壞,如對戰/即時戰略類遊戲;
- 競爭–如賽車等競速遊戲;
- 合作–不合作無法取得進展,不存在勝負;
- 共享–共享少量數據,比如好友送禮或在遊戲空間小破壞,基本單人也可玩;
- 遊戲結果的共享範圍:
- 只展示給自己;
- 可逐個發送給別的玩家;
- 互相關注的好友;
- 展示給粉絲;
- 公會、粉絲團;
- 遊戲服務器的範圍;
- 不限範圍的全體玩家;
- 聊天系統的類容:①沒有聊天; ②有固定句子; ③自由輸入;
- 維護和升級的計劃:每週、隔週、每月或不定期; 一般更新越頻繁,玩家的留存率或回頭率越高;
- 代碼規模:如果需要迭代的代碼過多會遇到問題;
【網遊開發團隊的實際情況】
- 工作分配:
- 橫向分配 – 客戶端和服務端開發工作分開;
- 垂直分配 – 根據遊戲策劃內容分配(如戰鬥,賭博,釣魚等);
- 程序員提升:
- ①守[從模仿開始]:
- 參考模仿現有遊戲(要模仿經典);
- 要使用標準的、爭議少的庫;
- ②破[技術研討會]:
- 參加如GDC等技術講座瞭解自己與業界資深人員間的技術差距並學習;
- 多參與不同技術領域的遊戲開發,比如Web,手遊,教育遊戲,數據挖掘等項目;
- 關注Blog,看書學習,共同提高等;
- ③離[最高級階段]: 帶領團隊開發全新遊戲,發表書刊論文等等;
- ①守[從模仿開始]:
- 項目管理:比如採用Scrum進行敏捷開發; OA流程工具管理等;
- 項目的移交:
- 測試的準備 – 實際移交前,首先更新遊戲的自動化測試工具並添加儘可能多的操作;
- 縮短環境搭建時間 – 如OS、必要程序庫、開發工具的安裝等(推薦使用容器);
- 設定合適的訪問權限 – 交接過程中應”逐漸”開放最大訪問權限;