游戲服務器設計之NPC系統
簡介
NPC系統是游戲中非常重要的系統,設計的好壞很大程度上影響游戲的體驗。NPC在游戲中有如下作用:
- 引導玩家體驗游戲內容,一般游戲內有很多主線、支線任務,而任務的介紹、接取、領取獎勵等操作都是通過NPC的操作,一般會有幾個核心NPC,再不停的任務引導中,玩家會對核心npc印象深刻,強化了游戲代入感。
- 核心功能的展示和操作。游戲大部分功能都會放到游戲主界面,但是全部功能都放進去是不現實的,其他功能則以NPC的方式提供,比如進入某副本的入口等。
- 一些運營活動,比如道具秒殺,打折促銷等,過年過節也可以制作一些應景的NPC形象。
NPC的設計
NPC跟角色怪物等相似是一個實體,所謂實體指的是必須有唯一ID,可通過ID索引到且可以在地圖動態添加,本文實現的NPC的ID由配置文件指定,其他基本屬性如名字、地圖坐標、外形、朝向等都可配置。
當與NPC對話時一般都是顯示文字和一些引導操作的按鈕。這些都是需要可配置。另外NPC的文字除了靜態描述文字,還需要一些動態數據,比如顯示玩家活動分數,排名次序等。如何定義服務器和客戶端的協議才能滿足上述要求呢?首先必須是文字協議並且可擴展,這樣才對配置友好,Json是一種,但是json夠緊湊但是對配置不是很友好尤其是對文字描述這種。xml相比更好一點,擴展性強,可讀性也好,在文字長度不大的情況下效率也可以接受。本人推薦用xml的格式NPC的顯示協議。NPC至少有兩個元素文字和按鈕,怎么用xml來表示呢?我首先想到了html。常規文字顯示就參考html的格式,特殊的ui組件,擴展一下xml就可以了,這種情況甚至不需要重啟服務器。為了客戶端解析方便,我們只需要使用html的子集即可,比如:
過年好!<br/>
<font color="red">狗年大吉!</font> <a href="showPage">旺旺旺</a>
<br/>
<button type="button" onclick="showPage">OK</button>
使用html格式的配置有如下好處:
- html大家都比較熟悉,無論是服務器客戶端都對html有一定了解,甚至策划也不陌生,接受起來非常容易。
- html編寫雖說需要一定的程序能力,但是這種在線編輯器一抓一大把,所見即所得的配置方式非常方便配置人員。
比如使用http://www.w3school.com.cn/tiy/t.asp?f=html_basic 這個在線html編輯工具可以所見即所得的編輯文字內容。結果示例如下:
使用這種格式的好處是,策划事先可以在在線編輯器上編輯好npc相關的文字,顏色、排版等都處理好,一些顯示錯誤可以一開始就發現。
關於超鏈接和按鈕
上圖顯示了一個有超鏈和按鈕的npc面板,那么點擊了超鏈和按鈕后程序如何處理呢?這時正時腳本排上用場的地方了。一個超鏈或按鈕對應一個腳本的函數,而整個腳本正好是對應了腳本的全部功能。另外超鏈是可以傳參數的,那么參數會被帶到腳本函數中,如下例所示:
查看成績
def showScore(player, npcid, param):
sortCondition = param['sort']
#do something
return
第一次點擊npc因為沒有指定超鏈,那么默認調用腳本的main函數。時序圖如下:
def main(player, npcid):
msg = '''
過年好!<br/>
<font color="red">狗年大吉!</font> <a href="showPage">旺旺旺</a>
<br/>
<button type="button" onclick="showPage">OK</button>
'''
return msg
關於安全性
思考下如果有外掛沒有點擊main直接發消息點擊showScore會怎么樣?正常情況下角色必須點擊當前看到的頁面包含的超鏈,否則會出現安全性問題,必須加以限制。npc系統每次發送npc面板內容給客戶端時,都會記錄下當前的npc面板內容,當玩家點擊超鏈,首先驗證一下是否是本次面板內的超鏈,否則拒絕,安全性大大提高。時序圖如下:
總結
- xml作為npc顯示協議具有非常強的擴展性,比如顯示文字,控制文字大小,顯示圖標等都可以通過擴展xml標記實現。
- xml與腳本結合實現npc的功能,會大大利用腳本的已修改、熱更新的優勢,一些運營活動不停機上線這是最基本的要求了,如果有bug,可以下發正確的腳本覆蓋后重新載入腳本即可。
- 這種格式易理解,好配置,對於策划這種弱程序的也是可以接受,當然基於html做個配置工具也是非常的容易。
- 實現顯示協議后,npc的外放、刪除,外形配置、文字配置等,都是策划可以搞定的,這也是團隊都希望的。
- 再考慮到擴展性前提下,保證了npc的安全性,有的時候寫代碼的人經常會寫這樣的代碼,如判斷一個人可以領獎,然后顯示可以領按鈕,點擊了領取按鈕的對應函數有可能忘了判斷有效性,在這種npc的方式下,就不太會出現重復領獎的bug,因為每次領獎,都會npc提示領獎成功,然后把player上的當前npc文字沖掉,這樣假如外掛再發領獎請求會被npc系統自動攔調,大大提高系統安全性。
- npc的點擊頻率限制,npc距離限制,這寫基本的安全性邏輯也要有,這個不在贅述,詳情看github代碼。
- GitHub地址: https://github.com/fanchy/h2engine
- 關於屬性管理器:http://www.cnblogs.com/zhiranok/p/h2engine_propmgr.html
- 關於游戲服務器引擎h2engine:http://www.cnblogs.com/zhiranok/p/ffengine.html
更多精彩文章 http://h2cloud.org/