整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          三萬字長文游戲設計左道,復雜系統與涌現

          者:余田,《流浪方舟》制作人,微信號yutianTerean

          歡迎關注作者個人公眾號“魚塘游戲制作工坊”


          零、前言


          這是一篇關于復雜系統在游戲設計中應用的文章,整篇文章分為三大部分,第一部分介紹復雜系統和涌現,第二部分借由復雜系統提出一種新的度量游戲的方法,第三部分會通過實際的原型設計,來深入探討復雜系統和涌現在設計中的應用方式。


          溫馨提示,全文字數3w+,預計閱讀時間較長,歡迎關注收藏慢慢看,一家之言,拋磚引玉,也歡迎各位朋友交流斧正。


          一、復雜系統簡介


          首先,復雜系統是什么?


          復雜系統有很多定義,比較簡潔的定義是:由大量相對簡單的自組織個體構成,個體之間通過簡單的規則交互,卻能涌現出復雜宏觀行為和現象的系統。


          蟻群,大腦,經濟系統,免疫系統,生態系統,互聯網,元胞自動機,人類社會等等,都是復雜系統。


          這里的復雜系統定義有兩個關鍵詞,自組織(self-organizing)和涌現(emergent)。


          “自組織”是指系統內部或外部沒有一個指揮者,告訴個體該怎么做,而是個體自身通過規則控制自身。


          “涌現”,就是指系統組成部分間簡單的互相交互,卻在宏觀層面產生了新的特性或行為,這些新特征或行為稱為“涌現”。這是非線性系統的特征,即1+1>2,另一種說法就是整體大于部分之和。


          復雜系統研究是一個跨學科的科學研究,涵蓋了許許多多分支,下圖是復雜系統科學的分布圖,來源網站https://www.art-sciencefactory.com/complexity-map_feb09.html:



          對復雜系統研究的重視比較晚,目前也處于探索之中,沒有公認的定義,統一理論或一般性原理。對不同復雜系統的共性探索一直是重中之重,不同領域的科學家提出了自己的理論,但還未完全達成共識。


          而我們只關注復雜系統在游戲中的應用,一般來說,復雜系統在游戲中的應用分兩個大方向:


          1. 代理(人,動物,AI等)為核心的復雜系統,例如蟻群,公司,社會,經濟系統等。沙盒,故事生成器類游戲用的比較多,例如kenshi,《模擬人生》系列,環世界,矮人要塞等等。
          2. 客觀規則為核心的復雜系統,例如基于物理化學規律的湍流,天氣,N體運動等。物理模擬類游戲,應用主動布偶的游戲,編程類游戲,某些建造組裝類游戲等等


          當然兩者也可以結合,但一般因性能和復雜度考量,都會有所側重。


          筆者最近的兩個游戲也深入應用了復雜系統和涌現的設計元素,最近的游戲《流浪方舟》利用了物理系統作為復雜系統,為我們產生有利的碰撞位移涌現,是以客觀規則為核心的復雜系統利用。


          而上個游戲《追隨者聯萌》中實現了GOAP和行為樹結合的AI,令整個NPC的行為交互組成一個復雜系統,是以代理為核心的復雜系統。關于GOAP的介紹,可以參考筆者之前的一篇介紹文章:


          https://mp.weixin.qq.com/s/U9CmZ2uTEv91KPosHDFZRQ


          總而言之,復雜系統為我在游戲開發領域,不論是技術還是設計,提供了很多不同的思考角度,是一個非常有用的工具。因此,本篇文章就是結合我的一些實踐和思考,跟大家簡單分享交流一下。


          接下來三章,我們通過復雜系統中非常具有代表性的混沌系統,來揭開復雜系統的面紗一角。


          二、混沌的發端,動力學與預測


          人們討厭宿命論,卻總想著預測未來。

          ——我說的


          首先我們簡單介紹一下動力學。


          動力學始于亞里士多德樸素但錯誤的運動理論,后來伽利略,哥白尼,開普勒以實驗觀察推翻亞里士多德流行了1500年的理論,再到牛頓橫空出世,發明了微積分,正式創建了經典力學。提出了著名的牛頓三定律:


          1. 在任何情況下,一切物體在不受外力作用時,總保持靜止或勻速直線運動狀態。
          2. 物體的加速度與物體的質量成反比。
          3. 兩個物體之間的作用力和反作用力,在同一條直線上,大小相等,方向相反。


          在牛頓進一步提出萬有引力定律后,在當時,牛頓力學完美地解釋了一切物體的運動,其適用于任何大小的物體,不論是落下的蘋果,還是燃燒的太陽。理論上,人們若是知道一個物體的初始位置和速度,就可以計算出后續的運動,自然就有聰明的小朋友想到:若是知道宇宙中某一刻所有粒子的當前狀態,那是否就可以預知后面任何時刻的宇宙狀態。


          上述精確預測的假說就是著名的“拉普拉斯妖”,數學家拉普拉斯在1814年說:


          “我們可以把宇宙現在的狀態視為其過去的果以及未來的因。如果一個智者能知道某一刻所有自然運動的力和所有自然構成的物件的位置,假如他也能夠對這些數據進行分析,那宇宙里最大的物體到最小的粒子的運動都會包含在一條簡單公式中。對于這智者來說沒有事物會是含糊的,而未來只會像過去般出現在他面前。”


          如今,我們有強大的計算機,無需一個多智近妖的智者,也許未來有了足夠強大的計算機就能做這個工作。如果真是如此,豈不是宇宙中的一切都已經注定,像一個上完發條的鐘表,遵循三定律一直循規蹈矩地走下去,這是一個多么絕望的“決定論宇宙”啊。


          還好1927年,海森堡(Werner Heisenberg)提出了量子力學中的“測不準原理”,證明不可能在準確測量粒子位置的同時,又準確測量其動量。如此,在微觀世界的準確預測夢破碎,也慰藉了不愿相信宿命的人。


          統計力學與預測


          海森堡測不準原理只針對微觀情況,而玻爾茲曼(Ludwig Boltzmann)創建的統計力學告訴我們,即使無法計算微觀尺度的每個分子的運動,也可以用統計學的方式預測大量分子整體上的平均位置和速度,當粒子數量足夠多時,他的方法“幾乎總是對的”。統計力學是鏈接熱力學和經典力學的橋梁,氣壓,熱力學第二定律都能很好的用統計力學來解釋。那么即使微觀尺度上無法預測,宏觀尺度上,是否可以通過統計學方式來預測系統的整體變化呢?


          答案是不行,下面就是大名鼎鼎的混沌系統出場的時候了。


          三、混沌系統


          有時初始條件的微小差異,將造成最終現象的極大改變。前者的小誤差,會造成后者極大的錯誤。預測將成為不可能的事,我們面對的是偶發現象


          ——龐加萊,《科學與方法》,1908年


          1959年,42歲的數學和氣象學家愛德華·羅倫茲(Edward Lorenz,1917—2008)在嘗試用一個原始的計算機來預測天氣,結果發現輸入參數時微小的差異會造成兩次結果完全不一樣,即使兩次預測計算機每一步的計算方法都一樣。



          后來,羅倫茲在一場學術會議上發表了論文來探討這種對初始條件十分敏感的天氣系統,論文題目叫——《巴西的一只蝴蝶舞動翅膀,可以引發得州的龍卷風嗎?(Does the Flap of a Butterfly’s Wings in Brazil Set off a Tornado in Texas?)》,這就是著名的“蝴蝶效應”(The Butterfly Effect)。


          天氣系統就是一個典型的混沌系統,這里可能有點反直覺,為什么有些系統對初始條件就這么敏感?答案在于混沌的“非線性”和“自我引用”特性。


          下面介紹一個經典的可以體現混沌本質的數學抽象——邏輯斯蒂映射(logistic map),它非常簡單,其特性又非常令人震撼和著迷,我第一次讀到時有種醍醐灌頂的感覺哈哈。這里主要引用梅拉妮·米歇爾的著作《復雜》的邏輯斯蒂映射一章,非常推薦大家讀讀這本復雜系統的科普讀物。


          這是邏輯斯蒂映射的方程:



          X(t)是當前值,X(t+1)是下一步的值。R是一個參數,我們可以自己調,先不管。我們要做的很簡單,定一個R,然后以一個介于0-1之間的X(0)開始,代入這個公式,得到X(1),然后把X(1)代入公式,以此類推不停得到新的值即可。這就是一個非常簡單的“非線性”的方程。


          讓我們試試R=2時會怎么樣,我們會發現有意思的事情,就是不管X(0)輸入的是什么值,最終X(t)都會停留在0.5這個值,這個0.5正是所謂的不動點(fixed point):到達這一點所花的時間依賴于出發點,但是一旦到達就會保持不動。當R=2.5時,你同樣會發現系統到達一個不動點,不過這次不動點是0.6。



          而當R=3.1時有趣的事情開始開始發生:



          不管X0輸入的是什么值,最終Xt都會在兩個值(0.5580141和0.7645665)之間振蕩。如果將前者代入方程,就會得到后者,反過來也是一樣,因此振蕩會一直持續下去。這種最終的變化位置(無論是不動點還是振蕩)被稱為“吸引子”,因為任何初始位置最終都會“被吸引到其中”。


          往上一直到R等于大約3.4,邏輯斯蒂映射都會有類似的變化:在迭代一些步驟后,系統會在兩個不同的值之間周期振蕩(最終的振蕩點由R決定)。因為是在兩個值之間振蕩,系統的周期為2。


          但是如果R介于3.4和3.5之間,情況又突然變了。不管x0取何值,系統最終都會形成在四個值之間的周期振蕩,而不是兩個。例如,如果R=3.49,x0=0.2,x的值很快就開始在四個不同的值之間周期振蕩(它們分別大約是0.872,0.389,0.829和0.494)。也就是說,在3.4和3.5之間的某個R值,最終的振蕩周期突然從2增到4。最終的結果就像下圖那樣。



          接著,更有趣的事情來了,在3.54和3.55之間的某個R值,周期再次突然倍增,一下躍升到8。在3.564和3.565之間的某個值周期躍升到16。在3.5687和3.5688之間周期又躍升到32。周期一次又一次倍增,前后R的間隔也越來越小,很快,在R大約等于3.569946時,周期已趨向于無窮。當R等于大約3.569946時,x的值不再進入振蕩,它們會變成混沌。下面解釋一下。將x0,x1,x2……的值組成的序列稱為x的軌道。在產生混沌的R值,讓兩條軌道從非常接近的x0值出發,結果不會收斂到同一個不動點或周期振蕩,相反它們會逐漸發散開。在R=3.569946時,發散還很慢,但如果將R設為4.0,我們就會發現軌道極為敏感地依賴于x0。我們先將x0設為0.2,對邏輯斯蒂映射進行迭代,得到一條軌道。然后細微地變動一下x0,讓x0=0.2000000001,再對邏輯斯蒂映射進行迭代,得到第二條軌道。圖2.14中的實心圓圈連成的實線就是第一條軌道,空心圓圈連成的虛線則是第二條軌道。



          這兩條軌道開始的時候很接近,但是到后面,兩條軌道開始分開,并且毫不相關。這就是“對初始條件的敏感依賴性”的由來。


          這就是混沌最簡單的表現方式之一,只要一個公式,就能告訴我們,如此簡單的邏輯斯蒂映射,并且完全是確定性的:每個xt值都有且僅有一個映射值xt+1。然而得到的混沌軌道看上去卻非常隨機。此外,對于產生混沌的R值,如果初始條件x0有任何的不確定性,對一定時間之后的軌道就無法再預測了。


          所以,如果對于一個實際的混沌系統,即使它簡單到只有一個粒子,它的初始狀態中若有個參數是無理數(絕大多數數字其實是無理數,有理數只是少數),例如大家最熟悉的π,那我們就要建造一臺可以輸入無限位數小數的機器,否則無論我們精確到小數點后多少位,那一位后面的誤差就會導致一定時間后,整個混沌系統都無法預測。這就是“失之毫厘,謬以千里”。


          至此,不論從宏觀上還是微觀上,預測未來都不可能。


          四、混沌系統和游戲


          前文提到我們的游戲《流浪方舟》是應用了基于規則的復雜系統,簡單描述游戲玩法,是雙方玩家各控制五個球體英雄,互相碰撞進行戰斗,其碰撞和反彈都是模擬的物理規則,并且有PVP的玩法。而我們游戲的機制,其實就已經組成了一個典型的N體系統(沒錯,N等于三就是大名鼎鼎的三體系統),也因此遇到了混沌效應。


          我們用的是幀同步方案,在不同的手機上,我們遇到了兩個玩家不同步的問題。排除各種原因包括網絡因素后,發現原因是不同機器上的浮點數運算有微小的差異(真的非常微小)。于是,某個回合微小的差異,會在幾回合后使得雙方的戰場情況完全不一樣,直接變成各打各的了。后來,我們只能是放棄Unity自帶的物理系統,自己重新實現了一個定點數精確物理系統,非常慘烈。所以,游戲利用了復雜系統,也要承受復雜系統可能帶來的問題。


          當然反過來說,我們也利用了復雜系統的涌現現象。對于游戲來說,涌現本身不是目的,而是涌現能為游戲帶來什么。


          首先,涌現能為游戲帶來意料之外的體驗,該部分的體驗是玩家不可控的。若開發者能在這部分進行部分控制,則可以進行更多發揮。當然意料之外的體驗也是新體驗,涌現本身創造了新的體驗。


          同時,涌現的妙處在于并不是所有過程都是不可預測的,往往有一小部分是可以預測的,這會帶來一定適應性,可以適應不同水平或者意愿的玩家。但是復雜系統的的突變也會帶來一個相變的臨界點,這個臨界點又可以保證不同玩家對涌現的掌控不會相差太多。


          舉例我們游戲的物理碰撞系統,復雜度來自多體運動,玩家無法預測N次碰撞后的情況,但是大多數玩家是可以預測1次碰撞后的結果,這就是初始可預測部分,這部分會進入玩家的策略考量中,而對于一些更具策略的玩家,首次碰撞反彈后的第二次碰撞,也能預測部分,這就是適應性,但是當反彈三次或以上,基本沒有玩家可以預料局面,這就可以類比為混沌相變的臨界點,用以把控不同玩家的策略差距,甚至理論上,即使有個類似深藍的超級計算機來算,也無法完全把控N變大后的情況。


          混沌系統只是復雜系統的一個分支,但確實是一個理解復雜系統的敲門磚,大概了解了復雜系統是什么之后,我們來看看游戲與其更深的關系。


          在設計復雜系統的時候,大家會發現,游戲和復雜系統的界限是非常模糊的,一個復雜系統,往往加上一些合理的目標和挑戰,就是一個具備一定可玩性的游戲。而很多游戲本身,就是一個復雜系統。也因此,對復雜系統的一些研究,同樣可以化用到游戲設計,例如復雜系統對“復雜度和信息”的研究,對游戲設計就非常有價值。接下來的部分章節,筆者會探討一種度量和優化游戲的方式,若對此不感興趣,可以跳到第八章。


          五、度量“復雜”


          首先我們來看看科學家們是怎么是度量復雜系統的“復雜”程度的:


          1.規模度量


          最簡單的度量就是規模大小,但是很顯然是不對的,畢竟單細胞變形蟲的堿基對數量是人類的225倍。


          2.香農熵


          另一種直接的復雜性度量就是香農熵,香農熵定義為信息源相對于信息接收者的平均信息量或“驚奇度”。也就是說若信息高度有序,例如“A A A A A A A……A”,則熵為零。完全隨機的序列則有最大可能熵。這種度量明顯也是不夠的,完全隨機的序列對信息接受者來說也沒有意義。所以最復雜的對象既不是最有序的,也不是最隨機的,而是介于兩者之間。


          3.計算機描述


          第三種度量方式是由柯爾莫哥洛夫(Andrey Kolmogorov)、查汀(Gregory Chaitin)和索羅蒙洛夫(Ray Solomonoff)分別獨立提出,他們將事物的復雜性定義為能夠產生對事物完整描述的最短計算機程序的長度。這被稱為事物的算法信息量。對于學計算機的小伙伴應該很好理解,也就是表達一個東西需要多少代碼。


          例如一個游戲A最少可以用10行代碼寫出來,另一個游戲B卻要用100行代碼,那按算法信息量,游戲B就比游戲A復雜。這個乍看合理,其實也有局限,100行代碼一定比10行復雜嗎,代碼本身的復雜度是簡單的線性嗎。本質上這是把系統的復雜度抽象轉移到了代碼上面,并沒有完全解決問題,只是把系統的復雜度問題變成了代碼的復雜度問題。


          4.統計復雜性


          第四種度量方式是物理學家克魯奇菲爾德和卡爾·楊(Karl Young)定義的一個稱為統計復雜性(statistical complexity)的量,度量用來預測系統將來的統計行為所需的系統過去行為的最小信息量。統計復雜性與香農熵相關,定義中系統被視為“消息源”,其行為以某種方式量化為離散的“消息”。對統計行為的預測需要觀測系統產生的信息,然后根據信息構造系統的模型,從而讓模型的行為在統計上與系統本身的行為一致。


          例如,序列ACACACACAC的信息源模型可以很簡單:“重復A C”;因此其統計復雜性很低。然而,與熵或算法信息量不同,對于產生序列ACGTGGTAGC的信息源也可以有很簡單的模型:“隨機選擇A、C、G或T。”這是因為統計復雜性模型允許包含隨機選擇。統計復雜性的度量值是預測系統行為的最簡單模型的信息量。因此,對于高度有序和隨機的系統,統計復雜性的值都很低,介于兩者之間的系統則具有高復雜性。


          第四種度量方式不止符合直觀,還有值得我們思考的是,它并不完全度量系統本身,還通過對系統演變的預測來度量系統本身的復雜度。


          還有很多度量復雜性的方法,不一一贅述。各種度量都有一定可行性,但都存在的局限性,還遠不能有效刻畫實際系統的復雜性。度量的多樣性也表明復雜性思想具有許多維度,也許無法通過單一的度量尺度來刻畫。


          而對于大多數系統例如游戲,并不是一成不變的,而是不斷更新迭代,對未來可能性預測來反推當前的復雜度是一個有趣的方向。


          六、復雜系統和游戲有效信息度


          相信很多設計師在設計游戲的時候,都曾想要“度量”自己的游戲,“可玩性”,“復雜度”,“上手難度”等等,這些都是非常難以統一定義和量化的標準。我們在本文,不討論“可玩性”這個過大的話題,只聚焦于對游戲有效內容量的探討,有效內容量,也可以從很多個角度來側面地衡量,例如游玩時長,系統復雜度,系統深度等等。而我們的角度不同,是從信息層面上,來度量和優化一個游戲,筆者稱為“游戲有效信息度”。


          游戲有多種抽象方式,其中有一種抽象就是:玩家接受信息,與游戲互動,影響游戲,游戲反饋信息的這樣一個循環。信息是交互的彈藥,是策略的基礎材料,已知信息作為安全感來源和決策的輸入,未知信息作為鉤子吸引玩家探索,作為不可控因素帶來變化等等。


          “游戲有效信息度”就是指整個游戲系統所提供的內容,通過一定規則展現后,對于玩家預期來說,具有意義的信息量。這個信息量越大,我們可以認為游戲內容越豐富,游玩價值和可玩性往往更高。


          游戲的信息豐富度當然不完全等于可玩性,但是對所有玩家或人類來說,都有不停獲取新信息的欲望,同時人類又是高效的模式識別機器,當玩家熟悉特定模式和規律,一直沒有新信息攝入,則會快速感到無聊。信息刺激,本身也是可玩性的重要一環。


          接下來我們舉個具體例子,來探討一下有效信息度的概念:


          舉例,現在我們做了一個線性關卡的游戲A,每一關擊敗一個不同的敵人,即可去下一關,直到通關,關卡與關卡之間并沒有直接的聯系。


          假設我們制作了一系列的關卡內容,例如10關,我們預期這些關卡玩家會游玩一次,通關后不再想玩,我們先假定,這個游戲的有效信息度為10。


          以此為前提,有幾個有趣的問題:


          問題1


          這時候,加入一個設定,通關后所有關卡會打亂,假設我們預期玩家會因為這個設定再通關一次,耗費了玩家雙倍的時間。


          那這個游戲的有效信息度會變成20嗎?


          如果不是,那是更偏向10還是偏向20?


          問題1探討


          很顯然,不是20,重點就是有效信息度不等于游玩時長,而是玩家對內容的感知,能接受到的有意義的信息量,而關卡若只是打亂隨機,對于玩家游玩來說,關卡信息并沒有變化,換句話來說沒有新的信息給到玩家,也就沒有新的體驗。所以問題1的游戲有效信息度應該是接近并略大于10的一個值。注意,我們在此并不關心有效信息度的絕對精準值(也無法做到完全精準),我們只需要盡量定量,并且通過對比分析等方式逼近實際值即可。這個問題也呼應了復雜系統復雜度的度量,純隨機和純秩序,復雜度都很低。(所以優秀rogue的重玩性并不是只來自隨機)


          問題2


          在問題1 的討論我們已經知道,游玩時長和次數是結果,并不等于有效信息度。在這個基礎上,所有關卡打亂后,讓玩家可以一直重復游玩,每次游玩的關卡順序都會變化,那游玩價值又有什么變化?


          問題2探討


          本質上消耗的是順序不同帶來的體驗價值


          和前面的信息呼應,純隨機和純秩序都是信息量較低的狀態,也就是游玩價值不會很高


          同時,討論線性和非線性系統也有額外的意義,若關卡間的關聯小,則先A后B還是先B后A并沒有本質區別,而若關卡間是非線性地互相影響,則順序本身就被賦予了意義,或者說被賦予了額外信息和復雜度,則可能產生更多的有效信息度。所以重點不在于關卡打亂的隨機,而是在于關卡間的關聯設計,是否賦予這個隨機足夠的意義。


          問題3


          在原方案基礎上,多做了1關,并且設定為通關一次后,再次通關才可以玩到這個額外的關卡。


          假設每個玩家都因為這個設定,重新通關一次,那此時這個游戲的有效信息度大約是多少?


          和直接放出11關給玩家的區別是什么?


          問題3探討


          和問題1的探討類似,也許這個游戲的游玩時長的度量接近翻倍,但有效信息度只是接近11左右,這意味著,玩家在近翻倍的體驗時間中,體驗的質量其實是有所下降。其實和直接放出11關給玩家沒有本質的區別。那么為什么還有很多游戲會使用這個技巧來延長游玩時間呢?其實是來源于除了上述游戲機制本身之外帶來的可重玩性,類似問題2討論的非線性關卡,這些額外的因素,使得游戲的有效信息度在其他維度得到了提升,所以不屬于問題3的討論范疇。這個例子想要說明的是,有效信息度的分析一定要客觀剝離其他因素,否則將失去參考價值。


          問題4


          還是這個線性關卡的游戲,什么都沒變,但是給與一個額外目標,通關時間,然后允許玩家重玩,游戲有效信息度又如何?


          問題4探討


          這個問題,理論上有效信息度相對于原方案并沒有太大變化,但是我們直觀會認為,相比原方案,該方案更具可玩性。這個問題想要說明的是,技巧挑戰等內在驅動力,會為相近有效信息度的游戲,帶來較為不同的可玩程度。這也是證明游戲有效信息度并不完全等于可玩性的例子。


          問題5


          基于問題4的額外通關時間目標的設計,更進一步探討,若是游戲中原本就有一個道具,本來強度一般,但對速通有幫助。因此,玩家在沒有通關時間目標時,和有通關目標時間時,有效信息度的變化?


          問題5探討


          我們可以看到,除了目標的變化,其他都沒有區別,理論上,信息量完全沒有差別。但是實際上很顯然,后者有效信息度一定大于前者。這就是“有效信息度”定義里的“有效”的意義:一份信息,通過機制,轉化為對可玩性有意義的信息后,才能稱為有效信息。具體見下一章的探討。


          經過上面幾個問題,大家應該可以理解游戲有效信息度的意義,它雖然不等于可玩性,但是是對一定時間內,玩家體驗的豐富有效程度的一個度量。它尤其能幫助我們思考時摒棄無效游玩時長的陷阱,并在一定程度上幫助我們對比衡量游戲設計優劣。


          七、有效信息度與游戲設計


          有效信息度如何切實幫助設計?我們應該如何看待,操作游戲中的信息?


          玩家游玩游戲的過程可以視作一個接受信息,處理信息,獲得信息反饋的過程。設計師提供一系列的信息給與玩家處理,玩家在處理這些信息的時候,通過自身的操作和策略等,收獲不同的反饋。對于一個玩法,持續有節奏地給與玩家適量的,有意義的新信息讓玩家舒服地處理,則從信息角度來說是一個好的玩法。


          游戲的信息不是全部一次性釋放給玩家的,一個游戲的信息有很多種維度,例如規則信息,游戲世界環境的信息,關卡以及挑戰的信息,反饋及收獲的信息等等。玩家的目標挑戰反饋循環中,每個環節都在不停釋放新的信息。而新的信息的意義是什么?是產生新的變化。


          但是,如前文所說,一份新的信息,產生的變化往往不是一份新的游玩體驗,而我們的目標,就是讓一份信息,產生十份變化,最終轉化成兩份可玩性。


          有限的內容下,如何規劃這些信息將是關鍵。直接說幾種方法:


          1、規則輔助對手產生新信息


          拿棋類游戲-象棋舉例,象棋所有規則信息,是不多的。而戰場環境信息(當前棋盤情況)是千變萬化的,我們很容易得知道,象棋不是靠規則信息的逐步釋放來產生變化,同時象棋又不帶任何隨機性,所以是個很好的例子,幫我們聚焦到這一方式——規則輔助人產生信息。


          人人間動態的博弈,帶來持續可玩性,不是什么神秘的事情,但在信息角度,其實是有要求的,人產生有意義的內容,需要規則進行引導,什么叫引導?例如象棋里對所有棋子移動方式的限制,就是一種引導,這些限制使得玩家能夠部分預料下一步對方會如何行動,從而結合場面,最終給與當前回合玩家,一個正在不停變化但又有決策參考意義的信息,這個信息將會結合對方玩家的行棋風格,水平等因素,產生多局之間的變化。


          一個好的機制或者說規則,告訴玩家能做什么是基本,更重要的是約束玩家不能做什么,將無限的選擇空間壓縮到合理范圍且不策略收斂,并且讓對手每個選擇反饋出新的信息,例如,單步中沒有明顯的最優解,那是防守還是激進換子,其實暗藏對手風格信息,這個信息,是基于規則但超越規則的額外信息收益。


          2、輔助玩家自身產生新信息


          我們可以把游戲抽象成目標挑戰反饋三者循環,整體游戲由無數個大小循環嵌套組成。從信息角度我們可以有新的視角看待這個循環,每個部分都能通過設計輔助玩家產生新的有效信息。


          對于目標,往往是最明確簡單的信息,對于單個循環一般不會刻意藏匿目標的信息,因為對于設計來說,單個循環目標越明確越清晰越好。但整體上,目標可以有多個,可以逐步釋放,可以引導玩家自身賦予目標,有非常大的操作空間,目標往往是一切的起點,會成倍放大其他信息的效果。


          最好的方式,就是刺激玩家自己賦予自己目標,例如沙盒游戲,通過包裝世界觀等信息,讓玩家想要爬上那個跟任務無關的山頂,想要拯救某個無關緊要的村民。設計師提供的信息作為外因驅動作為引導,玩家自發產生的目標作為強大的內因驅動。


          對于挑戰,分為挑戰本身和玩家克服挑戰的過程,例如策略和操作。對于這部分信息的自發產生,來自挑戰本身需要提供足夠高的適應性,使得玩家自身情況的不同,能在挑戰和克服挑戰的過程中體現出來。同時要足夠敏感,玩家細微的變化,最好都要所體現。


          舉個例子,完成挑戰的方式有多種傾向,玩家根據自身喜好,能力,選擇其中一個方式進行挑戰,此時,玩家所有的操作和策略,將會產生基于自身的獨一無二的信息。


          對于反饋,這里重點不在給與玩家的反饋,而在于完成挑戰后給與系統的反饋,重點在于前后不同挑戰間的關聯變化,也就是說,需要配合上述挑戰部分,玩家做出的細微區別,反饋需要讓系統對接下來的挑戰產生足夠影響,就會產生指數增加的變化。如此配合,也是涌現的一種設計方式。(具體后面章節細說)


          3、促進多人之間產生互動


          和第一點本質一樣,稍有區別,留作思考題吧哈哈,分析麻將和雙人棋類間的區別即可。感興趣的朋友可以參考筆者的麻將相關的文章:https://mp.weixin.qq.com/s/RUFNdkrFy8e2oqEhsYp_Xg


          4、逐步釋放和重組信息


          玩家自發發現信息,而不是設計師塞給玩家,發現的過程本身是一種有意義的獲得行為,會豐滿整個游戲。這是一種較好的逐步釋放信息方法。


          巧妙地重組信息,來重用信息。這點比較好理解,就不贅述了。


          八、復雜系統與涌現應用


          上面的章節簡單介紹了一下復雜系統以及和游戲的一些關聯,由復雜系統啟發,提出了一個游戲度量方面的不成熟想法,拋磚引玉。接下來的章節將會以實際的原型設計為案例,來深入探討一下復雜系統和涌現設計在游戲設計中的應用。


          思維實驗


          第一步我們先來做一個思維實驗,前文介紹過,現實世界就有很多復雜系統,我們不妨試著挑選現實中的某個復雜系統,假設我們是全能的計算機之神(狗頭),已經把這個系統百分百實現出來了,同時,作為設計師,我們知道,擬真不等于好玩,那現在,我們需要思考一下這個系統中不好玩的東西是什么,去掉,好玩的東西是什么,強化。再添加一點佐料,加入一點目標,設置一些挑戰,給與足夠的反饋,這個時候,相信我們的腦海里已經有一個也許簡陋,但也能成立的游戲了。


          對現實的抽象和剪裁過程尤為重要,我們會逐步抽絲剝繭,把不重要的外在去掉,看到涌現的核心,來隨便舉個例子。


          假設我們取現實中的經濟系統作為我們的復雜系統,我們先賦予一個簡單的目標,就是賺得多少金錢。然后我們刨除掉一些冗余的東西,最終可能剩下這么一個系統:


          系統中有若干個經濟理性人,包含玩家在內,他們會想辦法以最小的代價去獲得最大的利益,這些決策實體我們統稱為“代理(agent)”——代理(agent)是一個計算機,人工智能和經濟學領域的術語,指的是接受信息,進行決策,執行行為的主體,可以是人,AI,組織,一段程序等等。在這個過程中,代理們會和其他代理,和環境進行交互,進行時間,信息,資源,收益的不停交換。想象一下,當這個系統運轉起來,我們在這個系統中的獲得的樂趣來源于什么?與一個普通的交易模擬游戲的差別在哪里?


          這個簡單的系統拋開聲光電反饋等冗余外在,我們可以發現,玩家的核心策略是收集信息,根據信息做出自己收益最大化的決策,自身的決策又會影響整個系統,系統改變其他代理的行為決策,每個代理的行為都相當簡單,但整體上會涌現出很多有趣的現象,例如哄搶,壟斷,通脹通縮等等現象,使得挑戰/問題/謎題動態變化,像是多只蜘蛛在彈奏同一張蛛網。


          以上,這個復雜系統在提供有意義的變化,產生新的可玩內容,這是重玩性的根本。同時,由于玩家對環境的影響足夠深遠,反饋會更強。


          讓我們再對這個游戲加點料,假如這個游戲加入了另一個玩家,雙方有同樣的目標,這時候我們很容易發現一點,復雜系統不可控的部分,正在平衡優劣勢,拉近不同水平玩家距離,同時部分降低操作和策略門檻。


          更進一步,我們會發現,就類似于現實的經濟系統,我們這個簡陋的復雜系統本身就是一個自適應系統,有時候像海綿,吸收玩家和代理們的重大行為,減小影響,有時候又像喇叭,放大一些微小的噪音。而在這個時候,我們如果再為這個簡化版的經濟系統加入一些引導性的設計,例如價格和資源消耗的調控(類似央行和美聯儲),可以去操控它的海綿或者喇叭,達成改變和控制游戲節奏的目的。


          再進一步,我們不滿足于單個目標,若是我們加入了多個勝利條件,我們會發現,基于復雜系統本身的多目標,更好設計,更能滿足不同類型玩家的游玩需求。


          最后一步,讓我們把對方玩家又去掉,把玩家會進行的一些行為和代理的行為進行比較,把一些簡單的,玩家會額外進行的侵略性較強的行為,或是非理性的行為,賦予代理。并且把和玩家的對抗的目標改為和代理對抗,我們就會發現,相對于其他游戲,在玩家感知中,代理會更接近真實玩家。


          當玩家面對一個整體的復雜系統,去對抗其中的一些代理時,要比對抗某一個NPC時,對系統智能的評價更高。因為玩家對一個客體的智能的評價,除了智能行為本身,還由很多和智能不相關的因素組成,例如外觀,強度,數量,環境等等。例如光環設計師在GDC分享過的一點,只是單純的增加敵人的強度不改變AI,玩家對敵人的智能評價就會更高。例如帕魯正因為遠離人的形象,玩家對其智能期望低,反而覺得其智能表現不錯。復雜系統的不可控和可解釋是一種更好的“難度放大器”,同時,復雜系統放大行為的反饋同樣適用于代理,這就是在解釋和掩蓋一些非智能行為。


          通過以上這個思維實驗,我們可以大致總結一下復雜系統和涌現的優勢,同時也是我們設計他們的目的:


          1. 產生有意義的變化,來提供新的體驗
          2. 增強玩家對環境的影響與反饋
          3. 平衡優劣勢,拉近不同水平玩家距離,降低操作和策略門檻
          4. 改變和控制節奏
          5. 承載不同類型玩家的游玩需求
          6. 部分替代其他玩家的作用


          以上思維實驗中,每位朋友選取的復雜系統可能都不一樣,但當我們多思考幾個復雜系統,將真實世界抽象的過程中,我們會發現,復雜系統和涌現可以分為兩個偏向:


          1. 以代理(人,動物,AI等)為核心的復雜系統,例如蟻群,公司,社會,經濟系統等。
          2. 以客觀規則為核心的復雜系統,例如基于物理化學規律的湍流,天氣,N體運動等。


          當然兩者混合也是一類,這里不討論,只探討這兩大類,這兩大類核心區別當然就是代理主體的存在與否。對于游戲來說,這兩個偏向的設計方式相差非常大,第一類代理為核心的游戲有模擬人生,SLG等等,而我的世界,noita,以及我們自己的游戲流浪方舟,更偏向第二類。


          接下來,我們會通過七個玩法原型,一一來窺探涌現設計的一些精華。這些都是紙面原型,只需要簡單的紙筆,或者一些簡單的道具例如骰子就可以實現,感興趣的朋友可以跟著做出來玩一玩,會有更深的理解。如果對設計不感興趣的朋友,可以直接跳到第十六章結論和探討部分。


          九、原型1隨機平替涌現


          1.1設計目的


          原型要求


          • 盡量簡單的規則,只利用單純的數字,加減法
          • 能夠成立的基礎博弈,不會發生策略收斂
          • 能夠提供一定的策略深度,拉開不同玩家之間的差距
          • 有隨機性的空間,用隨機來模擬涌現
          • 能夠展現重玩性,優劣勢平衡等特征


          隨機和涌現的異同:


          • 由于一個由確定性導出混沌,另一個由隨機性導出混沌,對于玩家的感知來說,前者的掌控程度遠大于后者,也就是說,玩家會更覺得涌現的結果和自己的決策或者輸入相關。同時,玩家對于兩者發生結果的歸因會有差異,隨機性的結果玩家會更歸因于系統,涌現若是設計的好,玩家會更歸因于自身。這個特性,是涌現優于隨機性非常重要的一點,也對游戲設計有非常重要的意義。
          • 第一點是感知上的掌控程度,而實際上,對于玩家來說,涌現部分理論上也是可掌控的,對不同情況的玩家適應性會更強。
          • 兩者從確定到不確定的起始節點,是完全不同的,隨機*隨機,某一層隨機,往往就是混沌的起點,相對離散,而涌現則連續很多,這一點對設計也很有意義。
          • 涌現是確定性的,就像前文展示的邏輯斯諦方程一樣,每一步迭代都是確定的,可計算的,只是超過計算能力的部分,對于計算者來說,就是混沌不可預料的。
          • 對于隨機來說,即使不同隨機結果的概率已知,對于計算者來說,仍舊是不可控的結果,若疊加了很多重隨機,也就是我們常說的隨機*隨機,這個時候更容易出現對于概率預期不清,于是完全放棄這部分計算,變成混沌不可預料,對于這部分,隨機和涌現在結果上有相似之處。


          然而,兩者的混沌部分,仍舊有幾個非常重要的區別:


          還有一些異同,總結在下表中:



          綜上,由于隨機和涌現在不可控部分,有一定相似的特征,并且隨機的實現難度遠小于涌現,所以原型一般先用隨機來平替涌現,來驗證可行性。


          1.2玩法規則


          玩法概述



          雙人游玩,有三個戰場,每個玩家四張手牌,共四個回合,每回合雙方放一張手牌到戰場,最終結算點數,三個戰場中獲勝占領兩個以上的玩家獲勝,平局按點數分勝負。


          回合階段:



          1. 雙方各從6張1——6的數字牌中隨機抽取4張牌
          2. 從5種場地效果中隨機抽取3個場地效果,先不揭示
          3. 揭示第1個場地效果,雙方各自選擇放入一張手牌在該戰場,背面朝上,然后揭示
          4. 重復上述,直到3個戰場各放置3張牌
          5. 第4回合,雙方將剩下的最后一張牌放在任意戰場,雙方不知道對方放置情況(拿兩張無用牌掩蓋)
          6. 揭示最后一張牌,結算結果


          結算階段


          優勝場地數量相同,則比較總點數,總點數高的玩家勝利


          總點數相同,則視為平局



          例如場地內是1和2,場地效果是[小于等于3的數+1],則最終變為2和3


          1. 根據場地效果對每個數字單獨進行修正
          2. 對比每個場地內雙方的卡牌點數總和
          3. 總和較大的一方獲得該場地的優勝,一樣則平
          4. 優勝場地較多的玩家取得勝利


          5個場地效果


          1. 單數卡片結果+4
          2. 雙數卡片結果+3
          3. 大于等于4的卡片結果+1
          4. 小于等于3的卡片結果+4
          5. 投六面骰,投中點數在該戰場視為7


          1.3設計思路


          基礎


          • 用簡單的數字創造1個原型玩法
          • 最小玩法為雙方各出1個數字比大小,大者勝


          加入策略對抗和策略深度


          • 第1層:引入3局2勝的上校博弈,考驗玩家的資源分配能力
          • 第2層:加入第4張牌,第4張牌可以作為關鍵牌逆轉局勢,也可用來詐唬,考驗玩家的博弈能力
          • 兩層策略相乘,創造出足夠的策略深度


          隨機和對抗隨機


          • 通過資源分配對抗隨機
          • 通過推理對抗隨機
          • 通過博弈對抗隨機
          • 考慮場地效果的后續可能性去進行資源分配,對抗場地效果的隨機性
          • 根據對方前3張牌,推理對方最后1張牌的數字,對抗對方手牌的隨機性
          • 在牌處在劣勢的情況下,制定高風險高收益的策略,進行詐唬和偷雞,對抗我方手牌的隨機性
          • 第2輪隨機,隨機范圍小,兩層小隨機只是承載一點重玩性和策略拉差,不加入過多策略負擔
          • 通過場地效果拉平各數字的價值,對抗第1輪隨機,降低隨機手牌對勝負的影響,防止策略收斂
          • 與第一輪隨機同理,揭示第1個效果后,后續只有6種組合,揭示第2個效果后,最后1個場地只有3個選項,玩家只需要在個位數的選項中,決定自己的資源分配策略
          • [雙數+3],[單數+4],單數額外+1,保證單雙數價值相同
          • [大數+1],[小數+4],小數比大數的加成多3點,拉近大小數價值
          • 隨機1個數字變為7,第3輪小隨機,提升廢牌(吃不上其他場地效果的牌)的價值,為玩家提供翻盤或詐唬的可能
          • 第1輪隨機,隨機范圍小,限制了不可控的部分
          • 決戰階段,對方最后一張牌只有3種選項,玩家根據3個選項進行推理即可
          • 保證任何拿法,一方一定有至少一張單數雙數,至少一張小牌和大牌
          • 卡牌6隨4
          • 場地效果5隨3
          • 玩家對隨機的對抗


          1.4與撲克的對比優化


          原型1已經以比較優雅簡潔的方式實現了一個隨機替代涌現的方案,但是仍有不足之處,我們拿撲克來進行對比:


          信息暴露密度


          • 優化:在翻地階段雙方輪流出牌,降低暴露密度,后手玩家可根據先手玩家出的牌和場地效果去出牌,降低了后手玩家的推理量,后手玩家在翻地階段取得了信息上的優勢,需要平衡雙方的優劣勢,可以在決戰階段,要求后手玩家先出牌并揭示卡牌所在場地,讓先手玩家在決戰階段獲得信息優勢
          • 但上述的優化會引入先后手問題。
          • 撲克的信息暴露頻次高,信息量較小,每翻1次牌,每加1次注就暴露一層信息,且前后關系聯系緊密,方便玩家進行推理,負擔較低。
          • 原型1的信息暴露頻次低,但信息量較大,每次翻2張牌,分析量翻倍,且需要通過全局的卡牌和地牌進行推理,負擔較高。


          信息可控程度和信息范圍


          • 優化:隨機場地效果后,直接揭示全部場地效果,或先揭示前2張,降低不可控的信息。
          • 但是加入加注設定后,不揭示場地效果更好。
          • 撲克的河牌是已知的,不可控的信息是對方的2張手牌,且玩家數量會越來越少,不可控的信息會逐漸減少
          • 原型1中玩家有4張卡牌,對方的卡牌與卡牌分配策略,對于玩家來說是不可控的信息,相對撲克數量翻倍,但因為只有1——6,信息范圍會相對減少
          • 原型1中還有3張場地效果,場地效果陸續揭示,在未揭示之前,這也是一部分不可控的信息


          勝利條件


          • 撲克勝利條件簡單,用卡牌花色和數字進行大小對比,玩家很容易處理
          • 原型1的勝利條件,涉及到優勝區域計算和點數計算,玩家不容易處理


          1.5原型1總結


          原型1通過非常簡單的規則,已經具備一定的可玩性和深度,同時具有重玩性。同時用兩道非常受控的隨機來模擬涌現,已經可以感受出前述的兩個特性:


          1. 產生有意義的變化,來提供新的體驗。
          2. 平衡優劣勢,拉近不同水平玩家距離,降低操作和策略門檻。


          這是一個很簡單的原型,主要是展示怎么用隨機來平替涌現,以及涌現在游戲中的大致感受,我們還可以以這個原型為基礎,不斷拓展規則,例如加入撲克下注的玩法:


          只需加入一個規則,前三回合,玩家可以在每一輪揭示戰場上的牌之后,點數大的一方進行下注,對方必須跟注才能繼續下一輪。同時一方也可以隨時放棄,另一方拿走所有籌碼。


          如此設計,在原先的策略基礎上加入了心理博弈,更發揮出每回合信息暴露的策略樂趣,提高策略上限。


          原型1是一個簡單的基于規則涌現的設計展現,接下來會從抽象即時戰斗的原型開始,逐步探索基于代理的涌現設計。


          十、原型2即時戰斗抽象


          2.1設計目的


          我們來嘗試抽象一場典型的即時制戰斗,先將戰斗簡化為1v1的兩個玩家,各操控一個單位,勝利目標是擊殺對方單位。其他各種衍生玩法都可以視作該單局最小戰斗的變種。進一步抽象,玩家是在調配戰場中的所有資源,達成戰勝敵方的目的,將敵我雙方的所有資源分為如下幾個類型:


          1. 直接關聯勝負的生存能力,例如血量,續航等
          2. 直接關聯勝負的輸出能力,直接間接傷害,限制敵方續航等等
          3. 直接關聯勝負的生存輸出能力變體,例如機動性,限制敵方機動性的能力(同時包含生存和輸出能力)
          4. 前三個能力的間接版本,例如召喚物或環境的各項能力或者是他們賦予關鍵單位的能力


          和之前的原型一樣,我們要用最簡單的規則,只用數字的加減,來模擬這個戰斗模型,這個原型同樣要達成以下幾個目的:


          1. 能成立的基礎策略博弈
          2. 對即時制1v1戰斗有足夠準確的抽象表達,尤其是和戰斗策略緊密相關的屬性,比如機動力
          3. 足夠健壯,適合拓展,作為后續涌現設計的基礎


          2.2玩法規則


          玩法概述


          雙人對戰,玩家將資源投入到輸出/生存/機動屬性上,機動屬性可再進行一次分配,分配到[進攻]和[躲避]上,雙方互相攻擊,造成的傷害由玩家分配的資源情況決定,血量先歸0者失敗


          玩法流程


          受擊方[躲避點數]與進攻方[進攻點數]對比,每高1點,進攻方造成的傷害減少20%,至多減少100%,沒有進攻高,則進攻方造成傷害不變


          1. 將15點基礎點數分配到各自戰斗單位的輸出/生存/機動屬性上,然后公示分配情況
          2. 將輸出屬性*10作為戰斗單位的攻擊值,將生存屬性*100作為戰斗單位的生命值(非必要,為了計算簡單,減少小數計算)
          3. 每回合戰斗開始時,將機動屬性上的基礎點數進行1次分配(機動屬性高的一方可額外獲得1個點數),分配至[進攻]行為和[躲避]行為上,然后公示分配情況
          4. 高機動屬性的一方先進行攻擊,根據攻擊值對對方造成1次傷害,傷害需要根據雙方行為點數進行1次修正
          5. 雙方攻擊結束后,沒有單位血量歸0,則從步驟3重新開始,有單位血量歸0,結束戰斗



          2.3設計思路


          先采用最小單位,兩個戰斗單位互相攻擊


          用離散的回合來模擬即時,更直指本質


          將戰斗單位的優劣勢抽象成3個維度,輸出/生存/機動


          引入點數,玩家需要分配點數到3個維度中,用簡單的數字進行戰斗模擬


          • 機動能力高,則輸出/生存能力就會降低
          • 第一輪分配,通過限制點數的總和,模擬了機動能力對輸出/生存能力的影響


          第一輪分配結束后,輸出和生存點數固定,機動點數可再進行分配


          • 機動能力可用于追擊對方,提升輸出能力
          • 機動能力可用于躲避攻擊,提高生存能力
          • 機動點數稍微比對面高,則在每輪的攻擊中占據優勢,但高于一定值后,將不再獲得收益
          • 機動點數的再分配影響戰斗單位的傷害,再次模擬機動能力對生存/輸出能力的影響
          • 機動點數的再分配,每一輪戰斗都允許不一樣,模擬了機動能力的轉化能力


          2.4原型2多V多拓展


          可以很簡單的將原型2拓展到多VS多的規則:


          額外多一個目標選擇階段,機動力低的單位先開始選擇(相等時隨機),選定目標后本回合不能改變


          目標選擇完成后,進入機動性分配階段,規則有所補充:


          機動性的進攻點數,只能分配給該單位之前選的目標,而躲避點數,可以分配給所有以該單位為目標的敵方


          但是,每多分配一個目標,機動性額外消耗1


          所有單位分配完機動性,則開始戰斗


          戰斗結算順序,所有同時結算即可


          結算時規則和基礎戰斗規則一致


          2.5原型2總結


          通過讓玩家在戰斗中將有限的資源進行分配,體現出了機動能力的兩個特性


          1. 可自由轉化成輸出/生存能力,對輸出/生存能力產生影響
          2. 當機動能力高于敵方過多時,將反而變成劣勢


          在原型2可很簡單的拓展至1對多和多對多的玩法,進一步模擬復雜戰場上的情況,初步證明了原型2的拓展性較強


          資源分配的還能體現出對戰游戲中的一些設計思路


          • MOBA游戲中的行動指令(移動、攻擊、釋放技能)
          • 回合制游戲中的行動指令(攻擊、防守、釋放技能)
          • 卡牌游戲中的行動費用
          • 而在設計戰斗單位風格時,也是對這3個方面進行資源分配
          • 可留有一定的空間讓玩家進行分配,比如說加入天賦系統和養成系統
          • 戰斗單位的所有優劣勢都可抽象成輸出/生存/機動3方面
          • 在戰中可進行再分配的機動屬性,為玩家在局中創造出了策略空間,讓玩家去自主的進行變化,創造不同的游戲內容


          原型2策略博弈分為兩層,一層為開始的三個初始戰斗資源分配,一層為戰斗中機動力的使用,這兩層策略和對方的信息關系都不大,更偏心理博弈,單看這個原型策略深度不夠,但作為后續原型的基礎是足夠的。


          十一、原型3搶占資源


          3.1設計目的


          到這一步,我們有了一場基本戰斗的抽象,在原型3之前,我們先將原型1的思路融入原型2,再次從另一個角度分析一下涌現


          玩家已有單位間的變化,與玩家變化統一,并且互相影響,則抽象為:


          玩家在削弱敵方玩家的生存,輸出和機動能力,最終目標是生存能力歸零


          同時,玩家防御敵方對自身這三種能力的削弱


          在以上過程中,對環境產生影響,并受到環境的反饋


          環境的反饋可能有益于我方或敵方,并且分為可控和涌現部分


          1可控的部分


          • 玩家有意識追求有利于自身的可控部分,需要盡量簡單并控制數量,因為環境本身需要盡量對雙方都公平
          • 這部分真正的目的是刺激玩家與環境的交互,來作為涌現的觸發器
          • 例如玩家為了摘蘋果砍樹,樹倒了砸中玩家或敵方玩家
          • 值得注意的是,可控部分對于雙方玩家最好是一致的設計,因玩家的各種差異而自然分出有益與否,降低信息復雜度


          2涌現的部分


          • 不可控部分,有益于敵方還是我方沒有區別,但是設計上,傾向于有益我方的可控部分引出的涌現,是同樣有益于我方的
          • 同時,涌現的部分,玩家不是完全不可控,而是掌控程度較低,與可控部分是一個漸進變化的過程,同樣作為玩法上限
          • 最后,涌現部分需要設計師盡量可控,例如傾向于幫助弱勢的玩家等等,但是需要盡量讓玩家覺得合理


          忽視原型2,我們從頭抽象一個符合我們玩法的最小模型來實現上述理論:


          1. 最簡的不可控部分用隨機數進行表達,數字越大優勢越大
          2. 最簡的可控部分與核心機制保持一致
          3. 將玩家的能力抽象為三部分,輸出能力,生存能力,機動能力,用數字表達
          4. 機動能力高的一方有優勢,但是邊際效益快速遞減
          5. 機動能力本身有其作用,同時對生存和輸出能力有加成


          戰斗開始時雙方自由分配9點點數到三大能力上


          戰斗開始時,根據分配到機動性上的點數M進行隨機1-M,雙方較大的一方額外加1


          雙方可以將最終的點數M自由分配到輸出能力和生存能力上,作為臨時輸出和臨時生存


          雙方互相用自身的輸出對對方的生存造成傷害,優先扣除臨時生存,回合結束,清空臨時輸出和生存


          循環回合,生存能力先歸零的一方失敗。


          接著我們將涌現抽象為:


          臨時加成,永久加成,臨時代價,永久代價


          自選風險,高風險高收益


          考驗類,輸出or生存or機動性大于等于N時,獲得加成X


          臨時代價以及臨時加成類,輸出or生存or機動性臨時減X,臨時獲得加成X


          永久代價永久加成類,輸出or生存or機動性永久減X,永久獲得加成X


          最后我們將涌現拆分為幾個部分:


          1. 玩家可控交互部分,包含玩家可控的交互,涌現系統給與的反饋。玩家能夠給與涌現系統的有a資源信息,當前/最大/基礎/臨時的輸出,生存,機動能力的數值信息;b資源本身,消耗或變化輸出,生存,機動能力本身;c玩家的選擇或操作交互。
          2. 可控交互部分對涌現系統的影響,涌現系統的自組織。涌現系統本身內部的邏輯需要支持獲取外界的信息,并且在內部進行交換。
          3. 涌現系統自發進行的變化,對玩家產生的反饋。


          基于以上的分析,我們來看看原型3的實際規則:


          3.2玩法概述


          基于原型2的基礎戰斗,改為每個回合都會產生三個臨時屬性,臨時攻擊,臨時生命,臨時機動力


          每個回合依次出現三個隨機資源,雙方投入自己的三種臨時屬性進行爭奪,競價模式


          爭奪完三個資源后,使用剩余的臨時屬性進行基礎戰斗


          3.3具體規則


          1. 戰斗開始時雙方自由分配N點屬性到攻擊,生命,機動力上,這三個屬于永久基礎屬性,同時揭示結果
          2. 從若干種資源中隨機抽取三個資源放在場上,不揭示
          3. 每個回合開始時,揭示一個資源,并根據當前基礎屬性,產生對應點數的三種臨時資源
          4. 雙方開始競價爭奪這個資源,一方可以出價N點臨時屬性,另一方可以選擇大于對方點數的臨時屬性,或者放棄,以此類推
          5. 獲得資源的一方,即時觸發資源的效果,完成觸發結算資源后,進行下一回合。
          6. 當三個資源都爭奪完成后,雙方用當前的臨時資源進行一輪戰斗,戰斗規則和原型2一致,額外的,超過臨時生命的傷害扣到基礎生命屬性上。


          資源具體效果


          6張資源消耗卡,臨時攻擊/生命/機動,永久攻擊/生命/機動


          6張資源獲得卡,臨時攻擊/生命/機動,永久攻擊/生命/機動


          每次隨機資源效果時,從消耗卡和獲得卡中,各隨機抽取一張,組成該次資源的效果


          每種組合有不同結算效果,具體如下:


          1.消耗臨時XX,獲得臨時XX


          玩家自己選擇1-10的N點消耗的代價,N不能大于自身擁有的點數


          投一個10面骰子,點數需要大于等于N才成功,成功后收獲是代價的2倍,失敗代價不返還


          舉例:


          抽到了消耗臨時攻擊,獲得臨時機動,這時候玩家有6點臨時攻擊


          玩家可以選擇1-6的消耗,例如選了5點,則投10面骰子,大于等于5,則判定成功


          該玩家扣除5點臨時攻擊,并且獲得了10點臨時機動,反之,則扣除5點臨時攻擊,什么也沒獲得。


          2.永久換臨時


          玩家自己選擇1-10的N點永久代價(扣除基礎屬性),N不能大于自身擁有的點數


          10面骰子需要大于N才成功,成功后收獲是代價的5倍,失敗代價不返還


          3.臨時換永久


          玩家換1點永久資源,玩家有N點該臨時資源,10面骰結果小于等于N才成功


          例如該玩家抽到了臨時生命換永久生命,該玩家有7點臨時生命,則10面骰投中小于等于7就會獲得1點固定生命


          該臨時資源只用于判定,不會消耗


          4.永久換永久


          固定1點資源換2點永久資源


          不需要判定,直接消耗1點對應資源,換取2點目標資源


          3.4設計思路


          • 該原型模擬的實際情境是,若是引入環境的涌現因素,玩家某一段時間片段內,其實是會將這段時間的臨時資源投入到環境優勢的獲取上,例如經典的野怪,河道buff,或者是占據一個優勢地形。這些戰中的優勢,其實都需要玩家拿一定資源進行交換,比如玩家移動到一個優勢地形,其實就是拿一部分機動力換取地形優勢,地形優勢如果是加防御,其實就是我們的臨時機動力換臨時生命。其他同理,所有戰中不直接和敵方進行戰損交換的行為,都可以用這個原型進行抽象表達。
          • 同時,該原型的目標之一是用極簡的方式來實現涌現的適應性,尤其是對戰局優劣勢變化的適應性。
          • 引入玩家對抗不可控的體驗,通過讓玩家自由選擇風險回報策略
          • 同時玩家的決策通過隨機性,間接地影響系統的結果以及接下來的戰局,部分模擬涌現的過程
          • 用一個10面骰子實現了簡單的正態分布,保證收益最大化在中間數,低值低風險低收益,高值高風險高收益


          3.5原型3總結


          只說這個原型,還有一些優化的空間,例如:


          1生存能力的資源獲取隨機,會造成節奏拖慢,我們可以把資源獲取中的永久生存能力的隨機獲取去掉,更進一步,可以直接去掉臨時生命力,只保留臨時機動和臨時攻擊的設定。


          2機動性補充公式需要優化,實際不是輸出或生存掉一點,機動漲一點。經過驗算后可以維持機動力設計,但需要盡量保證15點分配左右以及555均衡分配,則誤差較小


          最后,非常建議大家上手玩一下原型3,其中設計親手游玩體會更深,原型3已經具備一定的可玩性,重玩性,涌現平衡優劣勢,玩家對戰局環境的影響和反饋也體現了一部分,同時,即使沒有中央控制系統,該原型也體現了一部分對節奏的調控能力,還算比較優雅。


          同時,讓我們回憶一下復雜系統和涌現的目的,也是我們實現的目標:


          1. 產生有意義的變化,來提供新的體驗
          2. 增強玩家對環境的影響與反饋
          3. 平衡優劣勢,拉近不同水平玩家距離,降低操作和策略門檻
          4. 改變和控制節奏
          5. 承載不同類型玩家的游玩需求
          6. 部分替代其他玩家的作用


          這個原型,在一定程度上,已經將前4條優勢體現出來。然而,這還只是一個比較簡單的原型,如果我們將資源視作一個單元,當前方案只有一種輸入,單個玩家的輸入。也只有一種輸出,對單個玩家的輸出。這是規則類涌現的一個典型,所以接下來,我們將嘗試基于代理的涌現原型設計。


          十二、原型4九宮格涌現


          4.1設計目的


          我們先假設單局戰斗中存在一種第三方單位作為代理,這種單位需要實現復雜系統的6個目的,那他們如何最簡單最直接的實現?如何由目的倒推對復雜系統的要求?具體分析如下:


          1.產生有意義的變化,來提供新的體驗


          提供新的驗證場景,將我們想要考驗玩家的點放在這些單位上來實現。新的驗證場景,例如如果要考驗玩家的形狀,或者其他單純敵我單位戰斗考驗不到的東西,則要先考慮,是否可以放在敵方單位上面,若是不能放在敵方單位上再考慮放在復雜系統上。


          反過來思考,什么是敵方單位不能實現的,就是應該由復雜系統來實現。例如敵方單位由對方玩家來決定,一些可控穩定的需求無法實現,系統由設計師來定,可以更可控。例如敵方單位會盡量偏向敵方優勢,系統可以承載雙方中立平等的設計。


          2.增強玩家對環境的影響與反饋


          作為反饋的一環,則是將對玩家做的任何行為盡量明確放大的反饋給玩家,并對戰局有意義。反饋需要復雜系統對玩家的行為等信息敏感,并且需要做出符合玩家認知的反應


          3.平衡優劣勢,拉近不同水平玩家距離,降低操作和策略門檻


          拉平玩家差距,這些單位會幫助弱勢的一方,需要復雜系統可以識別出敵我雙方的優劣勢,并且做出反應


          4.改變和控制節奏


          代理需要在合適的時機,改變和控制節奏,例如殘局時加快節奏等等


          5.承載不同類型玩家的游玩需求


          承載不同目的的玩家,根據目的設計,例如擊殺AI單位局外獲取更多金錢,可以擊破擂臺攻擊觀眾等。


          例如分化玩家的目標,局外塑造多種單局追求,局內才能體現。


          例如除了戰勝敵人之外,類似coc來搞資源是一種,為下一局做鋪墊局與局之間做關聯,給與弱勢玩家一個補償,但是更適合異步PVP。


          例如單局之間的關聯,可以是讓代理有記憶能力,根據玩家過去做的行為,影響超越單局。


          例如有NPC陣營,對玩家有好感度,在單局游戲中隨機遇到,視對雙方的好感度,對雙方玩家做出不同的行為


          于是玩家在游戲中可以有第三種目標,刷陣營好感度,或改變對方陣營好感度,或者陣營可以發布任務,完成任務作為第三種目標。


          6.部分替代其他玩家的作用


          復雜系統需要整體上給與玩家足夠多變的挑戰,代理需要和玩家擁有一致的底層規則。


          上面是我們的目標,一步步來,接下來,我們將會引入最簡單的代理,代理的行為也很簡單,挑選一個合適的目標,進行戰斗即可。同時我們需要用簡單的規則,讓多個代理在整體產生涌現行為。


          4.2玩法規則


          戰場為一個九宮格格子地圖。除了雙方玩家外,地圖上有7個中立單位,開局時用10面骰子隨機中立單位的攻擊屬性和生命屬性,機動力固定0忽略,玩家單位和前述原型一致,自由分配15點屬性。如下:



          每個回合開始時,遍歷九宮格所有中立單位,向所有附近非中立單位進攻


          中立目標選擇的邏輯是單元格總輸出最高》生存最高》隨機


          進攻單位格有玩家單位時,該玩家可自行選擇用雇傭單位還是本體來先防御


          戰斗規則和原型2基礎戰斗一致,中立單位和雇傭單位機動視作0


          玩家行動階段,機動性高的一方先行動,可以消耗一點機動性移動到附近格或不動


          移動階段完成后,所在單元格若是友方單位,無事發生,敵方單位或中立單位則戰斗


          若是中立單位則直接戰斗,若有敵方單位則和敵方單位進行戰斗,戰斗規則一致


          若既有敵方單位又有敵方雇傭單位,敵方可選擇誰來迎戰,戰斗結束后,敵方下個回合可選擇繼續進攻


          當玩家戰勝所在格子的中立單位或敵方雇傭單位后,若該格子沒有其他我方雇傭單位,可以選擇消耗自身的屬性,生成一個我方雇傭單位,雇傭單位屬性為消耗屬性的兩倍,機動力固定為0


          例如玩家攻擊為5,生命為8,可以消耗N點攻擊,M點生命,生成一個2N點攻擊,2M點生命,0點機動的我方雇傭單位


          當玩家行動完畢后,回合進入結束階段,結束階段若是地圖上有空位,隨機生成中立單位


          4.3原型4總結


          上面是最基礎的代理模擬,其中用移動能力的消耗來防止滾雪球是合理的,并且原型4的中立單位已經對游戲產生一定有意義的影響,甚至可以“涌現”出最簡單的夾擊,可不要小瞧這個簡單的夾擊,它就類似康威生命游戲中的元胞自動機行為,都是由最簡單的規則(原型中的中立單元選擇目標規則),自行出現的一些現象。這個原型中的涌現也許簡單到一眼看穿,但仍揭示了涌現的本質。


          雖然原型4基本是成立的,但仍有以下的問題:


          1. 消耗機動性進行地圖位移不合理,不是同一個層次的移動資源,額外需要設計一個大地圖移動能力,和機動性相關,但是不同層次需要獨立。
          2. 需要防止消極逃跑的策略,加入主基地?加入移動能力變化?加入大地圖遠程傷害手段?
          3. 高風險高收益需要更明確簡潔的吸引力和反饋。
          4. 有地形后仍缺失創造局部以多打少的策略能力考驗場景,以及少打少的維持能力,用于提供調度資源的空間和時機把控可能性。


          十三、原型5主基地涌現


          5.1設計目的


          吸收原型4總結的優缺點,我們進一步進行優化的同時,將更多目光轉移到,涌現如何參與進一個合理的目標挑戰反饋結構。先復習一下什么是好的目標挑戰反饋結構?一場戰斗,是由多個并存,嵌套的大小目標,挑戰和反饋組成:


          1目標


          • 合理,有難度但夠得著的目標,可以被分解的目標
          • 不同類型層次的目標,大目標永遠有希望但難達成,作為最終追求hook
          • 中目標有挑戰但在能接受的延時反饋的極限內能達成,作為階段反饋
          • 小目標作為容易達成或容易失敗后快速學習達成的填充反饋


          2挑戰


          • 有了目標,就要設置挑戰,挑戰是一切的核心,也是最難的部分
          • 對不同大小的目標,要有不同的挑戰,好的挑戰是需要有難度但能完成的挑戰
          • 最好的挑戰就是使出渾身解數剛剛好極限完成的挑戰,方法一般有自適應變化的挑戰難度,自適應變化的目標,將失敗作為挑戰的一環,模糊挑戰的概念等等


          3反饋


          • 和目標以及挑戰不同,不管什么大小的目標和什么難度的挑戰,反饋都有共同的要求
          • 首先,反饋有標識進度的作用,使得玩家知道自己在這個挑戰的什么階段,離目標有多遠
          • 人類的感知是不均衡的,離終點遠時,或未知終點距離時,會放大這個距離,離終點近時,會縮小這個距離。所以,及時,明確的分階段反饋,能夠幫助玩家更好的進行一個挑戰,靠近一個目標
          • 其次,正向的反饋,給與玩家動力,給與玩家操作的確認
          • 最后,負向的反饋也很重要,教學玩家,懲罰玩家,反向激勵玩家


          之前我們已經說過涌現的優勢,對于這個目標挑戰反饋結構當然同樣適用,我們來實際嘗試一下:


          5.2玩法規則


          還是九宮格地圖,每個玩家擁有一個主基地,主基地被占領則失敗,地圖設計如下:



          分基地和原型4的雇傭單位一致,只不過是初始固定給與我方的單位


          主基地屬性可以為9攻9血,分基地可以為5攻5血,屬性可以適當自己調整試試,會決定游戲節奏


          玩家操控的單位或者主基地被破壞,則游戲失敗


          玩家操控的單位每回合可以移動一格


          回合流程是機動力高的一方先移動


          玩家操控單位所在的格子沒有敵方和我方其他單位時,可以產生雇傭單位,產生規則和原型4規則一致


          雙方移動完后,所有建筑可以向相鄰格子分配點數產生雇傭單位,每個格子友方非玩家操控單位數最多2個


          雙方輪流操作后,進行戰斗環節,戰斗環節規則不變


          額外的,單個單位屬性值不大于9


          5.3原型5總結


          相比原型4,原型5解決了一些問題,例如消極避戰,機動資源不合理等。同時,對于目標挑戰的優化,體現在結果上,我們會發現玩家的策略自由度會高很多,可以基于簡單的九宮格進行一些更復雜的策略,例如創造局部以多打少等。同時,我們最關注的涌現部分,仍舊和原型4接近,沒有什么損失,反而,因為玩家的決策自由度增加,在感知上,涌現部分會更加突出,這也是這個原型體現出的一個有趣的現象。由此我們可以知道,對于涌現的利用,至少需要一定程度的策略自由度,有了策略自由度,才能對整個復雜系統做更多輸入的可能性。


          下一步,我們反其道而行之,做做減法,用更抽象的方式來實現一樣的博弈。


          十四、原型6抽象分階段戰場


          6.1設計目的


          根據原型5的驗證成果,我們還可以進一步抽象,來感受涌現:


          1. 可以專注于資源分配,降低移動和戰場位置的相關因素,更加抽象
          2. 雇傭單位的機動性很關鍵,往帶機動性,更接近僚機而不是建筑的方向驗證,中立單位還是可以是建筑
          3. 直接分配點數,基地可以換一種形式存在,同時點數的存在也為下個原型打下基礎
          4. 加入戰斗中途加入單位的設計,分散決策


          6.2玩法規則


          戰場由戰場效果和戰場收益,以及中立防守單位三者組成


          戰場效果設計目的是輔助決策,平衡優劣勢,有以下三種:


          1. 考驗,若投入的單位總點數大于XX,則臨時加成XX
          2. 輔助,若投入的單位總點數小于XX,則臨時加成XX
          3. 消耗,加強中立單位X點


          戰場效果第一回合不揭示,回合結束后才揭示


          戰場收益,玩家追求目標,且可控,開始時就揭示


          1. 每回合增加總自由點數上限X,X隨機,且決定中立防御的點數配比
          2. 增強玩家本身,暫時不用


          玩家游戲開始時15點分配到自身單位,還有自由點數X點


          開始游戲時放入三個戰場,將戰場收益揭示,戰場效果不揭示


          玩家每回合可以雙盲做兩個操作,將自由點數分配到三個戰場中的一個,成為雇傭單位,和之前原型不同的是,雇傭單位可以有機動性,和玩家單位基本一致


          玩家將自身單位移動到某個戰場或從戰場移回基地,玩家單位去另一個戰場需要移回基地,如下圖:



          回合結束時結算戰斗,和之前規則一致


          每個戰場除玩家單位外最多一個雇傭單位,有一個雇傭單位時,基地無法派遣新的


          回合開始時自由點數回滿,并且每個戰場若沒有中立單位,則重新隨機生成一個中立單位


          中立單位生成規則為6面骰,投三次代表輸出,生存和機動,投到生存0則不生成


          6.3原型6總結


          原型6的體驗和前兩個原型又有所不同,雖然更加簡潔,但可玩性反而相對更高,這是因為將空間位置博弈更加抽象后,可以反而可以強化單個區域的效果,對涌現的表現加成更大,這也是這個原型給我們的啟發之一:


          代理和環境的存在都是涌現非常重要的一環,他們都是復雜系統的組件,是相輔相成的,或者可以直接視為一體。


          而在玩原型6的時候,也發現了一些可以更優的部分,例如第一步改為依次揭示戰場可以減輕決策成本,也體現了不可控部分降低決策成本這一點。例如玩家操控單位會有點被中立單位喧賓奪主,戰場收益還可以更高一點等。最重要的是,整體決策數較少,每一步決策負擔過高。


          十五、原型7細分決策平衡優劣勢


          7.1設計目的


          根據原型6的驗證成果,除了優化細節,我們來嘗試將決策拆分,降低每一步決策的信息不確定性和負擔,但每一步決策之間互相關聯,考驗玩家思維步數深度,從精確策略轉向模糊策略,這是原型7的重點之一。


          另外一方面,我們再次將目光放到優劣勢平衡這一點,探討利用局外資源帶入局內和涌現結合的方式:


          對于一個常規的帶局外的單局戰斗為核心的游戲來說,單局戰斗最終目標是為了獲取勝利的快樂以及獎勵,獎勵是服務于局外的發展,最終為了更好的進行單局戰斗。同時根據養成,經驗,技巧等等因素,對于一個玩家來說,戰中剛進入對局時有3種狀態:1明顯強于對方,2接近勢均力敵,3明顯弱于對方。


          對于玩家來說,略強和略弱以及勢均力敵的情況是最常見的情況,且是我們期望最多的情況(通過elo匹配等方式)


          在這種情況下,期望玩家目標是獲取勝利,勝利的獎勵大于其他路徑。


          有所不同的是,這種情況下玩家可以有兩種偏向,第一是放大優勢和縮小劣勢后進行戰斗,第二是直接進行戰斗分出勝負,偏弱的一方會傾向前者,偏強的一方會傾向后者。


          對于明顯強于對方的玩家,我們需要給與一個更難達成,獎勵更高,且過程中會削弱玩家的路徑,例如破壞敵方基地,毀滅敵方所有建筑,攻擊第三方單位等等。


          反之,對于弱于敵方的玩家,可以是幫助第三方單位防御,獲取防御資源等。當然也需要一個合理的勝負條件,要考慮弱勢方是否會主動承受傷害,消極比賽,投降,快速結束比賽。


          也不能通過簡單的戰斗力來供系統決定優劣勢,會促進壓戰力行為出現,和復雜系統的結合,我們需要玩家根據戰場情況自己判斷雙方優劣勢,做出不同的決策,來決定優劣勢。


          那局外資源又如何去達成平衡優劣勢的目標呢?這邊探討一種適合和涌現結合的可能性:


          我們將玩家在戰中的目標分為兩大類,勝利和獲取資源,兩者不沖突但有側重;


          玩家的實現這兩個目標的時候,有兩種抉擇,第一,減少局外獲得資源以獲取局內更強的戰力,第二犧牲局內戰力獲取更多局外資源;


          其中是漸進的變化,如此,不管優劣勢方,都可以走兩條路,風險和收益并存且由玩家自己把控;


          舉個例子,例如我們設一場戰斗勝利可以獲得10分的戰利品,失敗保底有2分的戰利品。局內存在復雜系統(例如一個第三方陣營),玩家可以與其進行不同的交互,進攻會獲取更多局外戰利品,也會損傷自身的戰斗力,也可以做第二類交互,用局外戰利品的消耗或者減少,來增強自身的戰斗力。


          如此,我們達成一個目標,理論上玩家最優解是戰力剛剛勝過對方能夠拿下勝利的前提下,盡可能多的用戰力換局外資源,這樣一來,玩家間會與復雜系統一起,進行非常動態的博弈,自適應地平衡優劣勢。


          因此,原型7將引入一個新的資源,用來模擬局外帶入局內的,除戰斗單位外的一種可支配資源。


          7.2玩法規則


          共有三片戰場,連成直線,一端靠近玩家A,另一端靠近玩家B,如下



          玩家自己的旗艦初始在主基地,旗艦取消機動性,初始分配點數為10點,但是旗艦血量乘10


          玩家每回合可以從自己的自由點數中分配N點成為一個雇傭單位,可以0點,雙盲,必須生成在主基地


          回合下一步雙盲決定旗艦前進后退還是不動三項操作


          下一步,所有雇傭單位所在的格子若沒有敵方或中立單位,則自動向敵方主基地移動一格


          下一步戰斗結算傷害,規則和之前的原型一致


          每個回合結束時戰場會生成中立單位


          中立單位生成仍舊是投6面骰子兩次,分別作為輸出和生存能力,機動性視為0


          每個回合生成戰場收益,收益大小隨機投擲10面骰


          加入利息設計,每N點回合結束時加1點,降低預測敵方的難度,同時增加博弈空間


          加入占領成功一次性獎勵,促進玩家更加激進,例如占領單位+1+1,或者戰利品自由分配占領單位還是收回


          戰利品分配在下輪怪物和收益生成之后,雙方雇傭單位之前完成


          每個戰場最多可以投兩個雇傭單位


          7.3原型7總結


          原型7體現了將策略拆密拆細,這種方式會更加契合涌現的設計,因為涌現本身需要一定步長的決策深度來拉差。不止是涌現,在做設計的時候,我們整體上都會偏向將精確策略模糊化,不僅僅為了涌現,而是更貼合人類做決策的本能。


          尤其在即時制游戲中,一般將精確策略作為額外深度上限提供,考驗玩家對游戲的掌握,信息收集,反應,記憶,快速決策等能力。操作上來說,偏向高頻操作考驗反應,收益代價都較小,低頻操作考驗策略,收益代價都較大。操作速度,操作精準度,操作策略深度三者為不可能三角。所以對于我們來說,相比精確策略更偏向模糊策略,并且重點是利用涌現令玩家產生模糊策略是精確策略的錯覺,再利用機制放大模糊和精確策略的反饋。


          同時,更偏模糊策略配合前文所說的動態平衡優劣勢才能成立。(完全精確策略,則優勢玩家最優解很明確,優于敵方的前提下,將所有戰斗力換為局外資源,劣勢玩家則什么也干不了)


          十六、涌現設計總結


          感謝耐心看到這里的朋友,上面我們設計了七個原型,一步步展示了復雜系統和涌現設計的一些要點,原型都我自己快速設計的,比較簡陋,如果在玩的過程中,有更好的想法,隨時修改原型即可,達成設計目的就行。借由上述的原型設計,我來總結一下涌現設計的一些經驗:


          1.規則盡量底層,抽象,通用


          對于復雜系統,復雜度來自代理間,規則間的交互,不在于規則本身的復雜度。反而,對于設計來說,用越簡約的規則實現設計目的,越優雅,并且也好調試,預測和利用涌現現象。多次迭代的輸入輸出,每次迭代都盡量簡單易懂,規則清晰。舉個例子,我們設計一個元素反應的復雜系統,不該是去設計木頭遇到火就會燃燒,火遇到水就滅這樣的規則,而是應該設計更底層通用的規則,例如溫度系統,所有這些元素會改變周圍的溫度,溫度超過燃點就燃燒,低于冰點就結冰。如此設計,所有的涉及溫度變化這個單一度量可以描述的元素反應,都統一起來了,不僅簡潔,后續拓展性也強。這就是一個例子,規則越底層,越抽象,越簡潔,越通用,才是一個適合復雜系統的設計。


          2.博弈空間,決策復雜度,學習成本,玩家掌控程度之間的平衡


          信息不能太完備,否則決策門檻較高,也不能太缺失,否則策略意義太小。一般通過逐步釋放的方式來達成信息密度的控制。同時,信息除了對決策的影響,往往還影響玩家對戰局的可控程度,這一點往往和涌現緊密相連,特別需要注意一個現象:某個信息和高收益相關,逼著玩家不得不去深入涌現,帶來巨大的決策成本。同理,信息,包括復雜系統內部的規則信息,也無需急匆匆教學玩家,在有復雜系統的游戲中,不需要追求玩家過多的掌控程度,探索復雜系統本身也可以作為樂趣之一,對復雜系統的熟悉程度也可以作為不同玩家間的拉差。


          3.拆分降低每一步的決策成本,及時反饋,減少長考


          如原型7所說,策略拆密拆細,這種方式會更加契合涌現的設計,因為涌現本身需要一定步長的決策深度來拉差。我們追求的是玩家盡量用模糊策略來應對復雜系統和涌現,但是通過涌現結果,UI暗示等等設計手段,讓玩家感覺自己在做精確策略,獲得高反饋。


          4.注意涌現中濫用隨機


          不可控部分大多數時候是降低策略成本,因為不需納入策略考量之中,控制隨機,對抗隨機,利用隨機,也能帶來相當大的樂趣。涌現也是類似,他們都是不可控的一種,那有朋友就可能會想了,涌現加上隨機會如何?


          我們舉個簡單例子,模擬人生中的小人,他們有自己的想法,但這時候我們讓某些想法出現的規則隨機。這時候,對于這些想法的涌現部分玩家會如何看?結論就是看不了,濫用隨機,隨機會侵蝕涌現的意義,最后,變成隨機蓋過涌現的樂趣,或者兩者互相影響。


          我們再細一點,如果把涌現和隨機的結合分為前中后三類:


          1. 我們會發現,涌現前隨機,對涌現影響不大,但意義也不大
          2. 涌現后隨機,會破壞涌現的意義
          3. 涌現過程中摻雜隨機,大大增加不可控程度,實際上也在破壞涌現


          所以,同一個游戲中,隨機部分和涌現部分最好是分離開來,且可以隨機的結果和涌現相關,但不要摻雜兩者,或者涌現的結果再隨機一道


          5.平衡優劣勢


          需要給劣勢方優勢的同時,盡量保持規則統一,不要過度依賴涌現本身的不可控來平衡優劣勢,更好的是以一個自洽的規則讓系統合理的平衡優劣勢,最好的是讓優勢方自適應追求高風險高收益,來平衡優劣勢。例如前文說的局外資源帶入的方式。


          6.利用提前認知降低理解學習成本


          復雜系統一般都有比較高的理解學習成本,并且現實生活中有非常多已有的復雜系統,因此,多多利用現實生活的提前認知,來降低門檻。例如原創設計了某些規則,那也去生活中找一個最接近的復雜系統,包裝一下靠過去。


          7.代理與AI的異同


          代理不等于AI,這是常見的一個誤區,因為很多時候他們兩個有重疊的部分,但從設計上講,一定要注意,代理是一個以一定規則執行輸入輸出的組件,它完全不需要追求智能,復雜,靈活等等,如果這樣去設計,就跑偏了。可以看出上面幾個原型,都會將代理設計的非常簡單,重點不是代理本身多復雜智能,重點是代理與代理直接的交互規則,在整體上能否產生我們想要的涌現。好的代理應該享受和玩家操控單位一致的底層邏輯,但是利用好代理所獨有的優勢。就類似AI的設計,擬真AI大多數不是最好體驗的AI,最好的是利用AI可以作弊這一點,更大化發揮AI對玩家體驗的作用。例如類似求生之路的導演系統,光環敵人AI等等達成的效果。


          代理不等于AI,但是可以參考AI和玩家可以用的策略,來進行設計,以下是我對1V1對抗的策略博弈的一些不完整總結:


          1. 最簡單石頭剪刀布,離散的循環克制,最基礎的策略
          2. 上校博弈,資源分配策略,以弱勝強,在總資源的基礎上博弈資源分配能力
          3. 連續循環克制,例如某資源高一點優勢,高太多反而是劣勢,大多配合上校博弈或資源規劃
          4. 競價博弈,雙方花費資源競價一個目標,一種連續的心理博弈
          5. 加注博弈,典型的就是撲克單挑,同樣是連續的心理博弈
          6. 深度博弈,比拼思考步長,大多數棋類
          7. 競速博弈,雙方比拼達成目標的速度,本身很難成立,一般輔以雙方交互的設計,麻將就是典型,或者是和其他策略設計結合,比如結合上資源規劃


          大多數實際的策略,是由上面多種設計復合配合,而這些策略,都可以應用于代理的設計。


          8.超越復雜系統


          最后,本文探討的是,復雜系統和涌現在游戲中的利用方法,我們追求的從來不是模擬一個復雜系統,或是多么追求和現實一致的涌現。我們追求的是利用復雜系統和涌現,服務于我們的設計目的。


          所以我們要學習復雜系統,但要超越復雜系統,我們可以重構現實的復雜系統,例如流浪方舟里面實現的設計物理,就跟真實物理不同。同時,我們也可以有外力給與系統,不用追求完全的系統內部達成自適應,也可以主動放大涌現等等,當然,當復雜系統和涌現對核心玩法沒有幫助時,不要猶豫,砍掉,一切為設計目的服務。


          十七、結語:涌現,生命,智慧


          上面8個章節,都是以一個設計師的視角,較為理性地去剖析復雜系統和涌現,目的性非常強地探尋其在游戲中的利用方式,希望對大家有所幫助。接下來最后一章,隨便聊點不那么理性的感想,隨便交流談笑一番。


          對復雜系統和涌現現象的著迷,離不開對自己對生命和智慧的敬畏與好奇。很多朋友不知道,生命到如今也沒有一個準確的定義,生命是什么?和復雜系統如何定義類似,這是一個至今沒有完全達成共識的話題,科學家們只能對生命提出了一些較為普遍的特征,例如:


          1. 結構,生物體的各種化學成分在體內不是隨機堆砌在一起的,而是嚴整有序的結構。只有當大分子組成一定的結構,或形成細胞這樣一個有序的系統,才能表現出生命現象。
          2. 新陳代謝,生命會與周圍環境不斷進行著物質交換和能量流動。一些物質被生物體吸收后,在其中發生一系列變化,成為最終產物而被排出體外,這被稱作新陳代謝。
          3. 應激性,生物能接受外界刺激而發生反應。包括感受刺激和反應兩個過程。
          4. 自我復制。
          5. 進化和適應,生命通過遺傳和進化,可以適應不同環境。


          以上只是一些特征,生命的定義多種多樣,至今沒有準確定義。而從復雜系統的角度來定義,生命不過一些簡單的組件聚集在一起,所涌現出來的整體現象。就像美國物理學家默里·蓋爾曼(Murray Gell-Mann)曾說:我們在周遭世界所見的復雜行為——甚至在生命世界中——只是“從深奧的簡潔中浮現出的復雜表象”。


          有人也會問,涌現是否只是一種錯覺,是我們主觀強加給系統表象的意義?這個問題,其實和智慧是否存在,是否是大腦的錯覺沒有本質的區別,每個人也許有不同的答案,但作為一個智慧的載體,我很難承認,我們僅憑錯覺能夠建立起我們璀璨的文明,留下名傳千古的詩篇,但是也許在更高智慧的生命眼中,我們的文明火花,不過是螞蟻抱團表現出來的蠢蠢集群智慧,說不得還被定義成集群效應,戴不上智慧的王冠。


          而對游戲來說,前面幾章沒有深入探索的最后一部分,就是復雜系統部分替代其他玩家的作用這一點,正是來源于對涌現生命智慧三者關聯的啟發。這一部分來自我們最新對長線游戲的思考——對于一個著重創意設計的小團隊,怎樣的方向最適合做長線內容。這是一個很大很重的話題,這里不展開,以后有機會單獨寫文章,先直接說我認為的三個可行方向:


          1. 多人競技,靠多人之間的交互博弈,不斷產生新的內容。
          2. 利用涌現的代替玩家的部分功能后,1V1的競技,彌補1V1競技人人博弈產生內容不如多人的部分。
          3. 利用涌現或其他方式,高重玩性高設計空間的單局PVE,高效更新關卡來做長線。


          以上是一家之言,只適合我們自己團隊,僅供參考,其中第二點,就是我們一直在探索的方向,如何利用涌現模擬玩家,讓系統能夠代替部分玩家間互相給予的體驗。就像之前說的,這里不是要做一個擬真AI去模擬人的智能,而是用涌現系統,去模擬人類玩家給其他玩家帶來的那種,理智中帶著混沌,可控中混雜著不可控,沖動瘋狂和理性決策交纏的感覺。


          好吧,寫著寫著又想著對游戲設計的作用,職業病發作,本篇文章前后耗時數月,可能有些啰嗦不連貫,感謝耐心看到這里的朋友,歡迎多多交流,也歡迎關注我的公眾號《魚塘游戲制作工坊》。


          下面就用一段上篇文章被我刪掉的胡言亂語,來結束這篇文章吧!


          “生命與智慧不是偶然,而是必然。


          熱力學第二定律-熵增定律表明,一個封閉系統,整體混亂度會隨著時間流逝增加,直到所有事物都走到最無序的狀態。于是維多利亞時代的熱力學家想象,宇宙這個封閉系統,所有能量也會慢慢轉化成廢熱,恒星各自熄滅,黑洞也會耗盡自身,最終所有一切都會處于平淡一致的寂滅,這就是所謂的“熱寂”。然而,在這個不可逆的過程中,宇宙似乎有些不甘,逐漸平靜下來宇宙海洋,在某些角落驟起波瀾,一些有序的構造體,從無序的物質中涌現出規則。這些構造體在行星的原初羊水中翻滾,用盡全力吸收恒星的光芒,用簡單的碳元素做骨架,配上一些別的東西,堆積出復雜的自適應系統,有些甚至還能開出漂亮的花朵。雖然,這些微小秩序的產生需要來自系統之外的能量,代價是宇宙其他區域更多的混亂。


          可是,宇宙在走向無序混沌的過程中,還是在一些角落悄悄孕育了有序的生命,它們是如此的珍貴,那是宇宙對抗無序的囈語,是宇宙為自身加冕的桂冠。而生命中涌現出來的智慧,更仿佛是宇宙的囈語恰好吟唱成了一曲歌謠,是桂冠上璀璨的寶石,是奇跡中的奇跡。每個人的心靈,都是獨一無二,從混沌中掙扎著長出的花朵,每個人的靈魂,都是宇宙靈魂的一部分。


          所以,用力活著,用力地思考,不辜負這奇跡。”


          感謝您的閱讀。

          自github

          機器之心編譯

          參與:吳攀


          2017 年伊始,再度出山的 AlphaGo 化名 Master 在網絡圍棋平臺上打遍棋界無敵手。你是否也想打造一個自己的 AlphaGo 呢?GitHub 用戶 Brian Lee(brilee)發布了一個效仿 AlphaGo 的極簡圍棋引擎的 Python 實現 MuGo。


          MuGo 項目地址:https://github.com/brilee/MuGo


          這是 AlphaGo 基本組成部分的一個純 Python 實現。


          AlphaGo 邏輯/控制流(logic/control flow)其實并不非常復雜,本項目就是其復現。AlphaGo 的秘密武器是在于其各種神經網絡之中。


          就我所知,AlphaGo 在對弈過程中使用了三個神經網絡。


          第一個神經網絡是一個速度很慢但很準確的策略網絡(policy network)。這個網絡被訓練用來預測人類的走子(大約 57% 的準確度),它會輸出一個可能走子的列表,并且每一種走子方式都對應了一個概率。這個網絡為蒙特卡洛樹搜索(MCTS)提供了可能的走子起點。這個神經網絡很慢的一大原因是它具有很大的規模,這是因為這個神經網絡的輸入是圍棋棋盤上的各種計算成本高昂的屬性——氣的數量、叫吃、征等等。


          第二個神經網絡也是一個策略網絡,它比第一個更小更快,但準確度更低(大約 24%),這個網絡并不使用復雜的屬性作為輸入。一旦到達了當前 MCTS 樹的葉節點(leaf node),這個第二個更快的網絡就會被用來得到一個棋盤局面的可能走子,并且對這個這個最終局面進行評分。


          第三個神經網絡是一個價值網絡:它為棋盤輸出一個預期獲勝的范圍,而不會自己下任何棋。


          然后,將使用第二個神經網絡的蒙特卡洛得到的結果和使用第三個神經網絡的價值計算結果進行平均,然后這個值被記為該 MCTS 節點的近似結果。


          開始


          安裝 TensorFlow


          開始需要安裝 TensorFlow,并使用 GPU 驅動器(即英偉達顯卡的 CUDA 支持)


          獲取用于監督學習的 SGF


          接下來需要一個 SGF 文件源。你可以在 https://u-go.net/gamerecords 獲取 15 年時長的高段位對局數據。你也可以從其它來源下載專業比賽的數據庫。


          預處理 SGF


          第三,對你的 SGF 文件進行預處理。這需要 SGF 文件中的所有局面并提取出每一個局面的特征以及記錄正確的下一步走子。


          然后將這些局面分割成塊(chunk)——一塊用于測試,其它的都用于訓練。這個步驟需要一定時間,而且要是你修改了 features.py 文件中的特征提取步驟,你還需要重新預處理。


          python main.py preprocess data/kgs-*


          注:這句代碼用了通配符,比如說:KGS 目錄可以名為 data/kgs-2006-01、data/kgs-2006-02 等等


          監督學習(策略網絡)


          使用上面預處理過的 SGF 數據(默認輸出目錄是 ./processed_data/),你可以訓練策略網絡。


          python main.py train processed_data/ --save-file=/tmp/


          網絡訓練好了之后,當前模型會被保存在 --save-file。你可以通過如下代碼繼續訓練這個網絡:


          python main.py train processed_data/ --read-file=/tmp/savedmodel

          --save-file=/tmp/savedmodel --epochs=10 --logdir=logs/my_training_run


          此外,你也可以使用 TensorBoard 跟蹤你的訓練過程——如果你為每一次運行定義了一個不同的名字(如:logs/my_training_run、logs/my_training_run2),你可以將這些運行彼此重疊起來:


          tensorboard --logdir=logs/


          與 MuGo 對弈


          MuGo 使用了 GTP 協議,你可以通過任何兼容 GTP 的程序來使用它。要調用原始策略網絡,使用如下代碼:


          python main.py gtp policy --read-file=/tmp/savedmodel


          要調用集成了 MCTS 的策略網絡版本,使用:


          python main.py gtp mcts --read-file=/tmp/savedmodel


          通過 GTP 下棋的一種方式是使用 gogui-display(它有一個兼容 GTP 的 UI)。你可以在 http://gogui.sourceforge.net/ 下載 gogui 工具套件。參見 http://gogui.sourceforge.net/doc/reference-twogtp.html 了解使用 GTP 的有趣方式。


          gogui-twogtp -black 'python main.py gtp policy --read-file=/tmp/savedmodel' -white 'gogui-display' -size 19 -komi 7.5 -verbose -auto


          另一種通過 GTP 玩的方式是對抗 GnuGo,同時還能觀看比賽:


          BLACK="gnugo --mode gtp"

          WHITE="python main.py gtp policy --read-file=/tmp/savedmodel"

          TWOGTP="gogui-twogtp -black \"$BLACK\" -white \"$WHITE\" -games 10 \

          -size 19 -alternate -sgffile gnugo"

          gogui -size 19 -program "$TWOGTP" -computer-both -auto


          還有一種玩法是通過 GTP 連接 CGOS(http://yss-aya.com/cgos/ 計算機圍棋在線服務器)。由 boardspace.net 運營的 CGOS 服務器已經關閉了;你需要在 yss-aya.com 接入 CGOS 服務器。


          配置好了你的 cgos.config 文件之后,你可以通過 cgosGtp -c cgos.config 連接到 CGOS,以及使用 cgosView yss-aya.com 6819 查看你自己的游戲。


          又到深夜了,我按照以往在公眾號寫著數據結構!這占用了我大量的時間!我的超越妹妹嚴重缺乏陪伴而 怨氣滿滿!


          超越妹妹時常埋怨,認為數據結構這么抽象難懂的東西沒啥作用,常會問道:天天寫這玩意,有啥作用。而我答道:能干事情多了,比如寫個小游戲啥的!


          當我碼完字準備睡覺時:寫不好別睡覺!

          分析

          如果用數據結構與算法造出東西來呢?

          • 什么東西簡單容易呢?我百度一下,我靠,這個鳥游戲原來不好搞啊,得接觸一堆不熟悉的東西,搞不來搞不來。

          有了(靈光一閃),寫個猜數字游戲,問他加減乘除等于幾。

          • 超越妹妹又不是小孩子,糊弄不過去。

          經過一番折騰,終于在半夜12點確定寫迷宮小游戲了。大概弄清楚其中的幾個步驟。

          大概是

          • 畫線—>畫迷宮(擦線)—>方塊移動、移動約束(不出界不穿墻)—>完成游戲

          畫線(棋盤)

          對于html+js(canvas)畫的東西,之前學過javaswing應該有點映像。在html中有個canvas 的畫布,可以在上面畫一些東西和聲明一些監聽(鍵盤監聽)。

          對于迷宮來說,那些線條是沒有屬性的,只有位置x,y,你操作這個畫布時候,可能和我們習慣的面相對象思維不一樣。所以,在你設計的線或者點的時候,記得那個點、線在什么位置,在后續劃線還是擦線還是移動的時候根據這個位置進行操作。

           <!DOCTYPE html>
          <html>
           <head>
           <title>MyHtml.html</title> 
           </head> 
           <body>
           <canvas id="mycanvas" width="600px" height="600px"></canvas>
           
           </body>
           <script type="text/javascript">
          
          var aa=14;
           var chess = document.getElementById("mycanvas");
           var context = chess.getContext('2d');
          
           // var context2 = chess.getContext('2d');
           // context.strokeStyle = 'yellow';
           var tree = [];//存放是否聯通
           var isling=[];//判斷是否相連
           for(var i=0;i<aa;i++){
           tree[i]=[];
           for(var j=0;j<aa;j++){
           tree[i][j]=-1;//初始值為0
           }
           } for(var i=0;i<aa*aa;i++){
           isling[i]=[];
           for(var j=0;j<aa*aa;j++){
           isling[i][j]=-1;//初始值為0
           }
           }
           
           function drawChessBoard(){//繪畫
           for(var i=0;i<aa+1;i++){
           context.strokeStyle='gray';//可選區域
           context.moveTo(15+i*30,15);//垂直方向畫15根線,相距30px;
           context.lineTo(15+i*30,15+30*aa);
           context.stroke();
           context.moveTo(15,15+i*30);//水平方向畫15根線,相距30px;棋盤為14*14;
           context.lineTo(15+30*aa,15+i*30);
           context.stroke();
           }
           }
           drawChessBoard();//繪制棋盤
           
           // var mymap=new Array(36);
           // for(var i=0;i<36;i++)
           // {mymap[i]=-1;}
          
          
           </script>
          </html>

          實現效果

          畫迷宮

          隨機迷宮怎么生成?怎么搞?一臉懵逼。

          • 因為我們想要迷宮,那么就需要這個迷宮出口和入口有連通路徑,你可能壓根不知道迷宮改怎么生成,用的什么算法。小聲BB:用并查集(不相交集合)

          迷宮和不相交集合有什么聯系呢?(規則)

          • 之前筆者在前面數據結構與算法系列中曾經介紹過并查集(不相交集合),它的主要功能是森林的合并,不聯通的通過并查集能夠快速將兩個森林合并,并且能夠快速查詢兩個節點是否在同一個森林中!

          而我們的隨機迷宮:在每個方格都不聯通的情況下,是一個棋盤方格,這也是它的初始狀態。而這個節點可以跟鄰居可能相連,也可能不相連。我們可以通過并查集實現。

          具體思路為:(主要理解并查集)

          • 1:定義好不想交集合的基本類和方法(search,union等)
            2:數組初始化,每一個數組元素都是一個集合,值為-1
            3:隨機查找一個格子(一維數據要轉換成二維,有點麻煩),在隨機找一面墻(也就是找這個格子的上下左右),還要判斷找的格子出沒出界。
            具體在格子中找個隨機數m——>隨機數m在二維中的位置[m/長,m%長]——>這個二維的上下左右隨機找一個位置p[m/長+1,m%長]或[m/長-1,m%長]或[m/長,m%長+1]或[m/長,m%長-1]——>判斷是否越界
            4:判斷兩個格子(一維數組編號)是否在一個集合(并查集查找)。如果在,則重新找,如果不在,那么把墻挖去
            5:把墻挖去有點繁瑣,需要考慮奇偶判斷它那種墻(上下還是左右,還要考慮位置),然后擦掉。(根據數組轉換成真實距離)。具體為找一個節點,根據位置關系找到一維數組的號位用并查集判斷是否在一個集合中。
            6:最終得到一個完整的迷宮。直到第一個(1,1)和(n,n)聯通停止。雖然采用隨機數找墻,但是效果并不是特別差。其中要搞清一維二維數組的關系。一維是真實數據,并查集操作。二維是位置。要搞懂轉化!

          注意:避免混淆,搞清數組的地址和邏輯矩陣位置。數組從0開始的,邏輯上你自己判斷。別搞混淆!


          主要邏輯為:

          while(search(0)!=search(aa*aa-1))//主要思路
           {
           var num = parseInt(Math.random() * aa*aa );//產生一個小于196的隨機數
           var neihbour=getnei(num);
           if(search(num)==search(neihbour)){continue;}
           else//不在一個上
           {
           isling[num][neihbour]=1;isling[neihbour][num]=1;
           drawline(num,neihbour);//劃線
           union(num,neihbour);
           
           }
           }

          那么在前面的代碼為

          <!DOCTYPE html>
          <html>
           <head>
           <title>MyHtml.html</title> 
           </head> 
           <body>
           <canvas id="mycanvas" width="600px" height="600px"></canvas>
           
           </body>
           <script type="text/javascript">
          //自行添加上面代碼
           // var mymap=new Array(36);
           // for(var i=0;i<36;i++)
           // {mymap[i]=-1;}
           function getnei(a)//獲得鄰居號 random
           {
           var x=parseInt(a/aa);//要精確成整數
           var y=a%aa;
           var mynei=new Array();//儲存鄰居
           if(x-1>=0){mynei.push((x-1)*aa+y);}//上節點
           if(x+1<14){mynei.push((x+1)*aa+y);}//下節點
           if(y+1<14){mynei.push(x*aa+y+1);}//有節點
           if(y-1>=0){mynei.push(x*aa+y-1);}//下節點
           var ran=parseInt(Math.random() * mynei.length );
           return mynei[ran];
          
           }
           function search(a)//找到根節點
           {
           if(tree[parseInt(a/aa)][a%aa]>0)//說明是子節點
           {
           return search(tree[parseInt(a/aa)][a%aa]);//不能壓縮路徑路徑壓縮
           }
           else
           return a;
           }
           function value(a)//找到樹的大小
           {
           if(tree[parseInt(a/aa)][a%aa]>0)//說明是子節點
           {
           return tree[parseInt(a/aa)][a%aa]=value(tree[parseInt(a/aa)][a%aa]);//不能路徑壓縮
           }
           else
           return -tree[parseInt(a/aa)][a%aa];
           }
           function union(a,b)//合并
           {
           var a1=search(a);//a根
           var b1=search(b);//b根
           if(a1==b1){}
           else
           {
           if(tree[parseInt(a1/aa)][a1%aa]<tree[parseInt(b1/aa)][b1%aa])//這個是負數(),為了簡單減少計算,不在調用value函數
           {
           tree[parseInt(a1/aa)][a1%aa]+=tree[parseInt(b1/aa)][b1%aa];//個數相加 注意是負數相加
           tree[parseInt(b1/aa)][b1%aa]=a1; //b樹成為a樹的子樹,b的根b1直接指向a;
           }
           else
           {
           tree[parseInt(b1/aa)][b1%aa]+=tree[parseInt(a1/aa)][a1%aa];
           tree[parseInt(a1/aa)][a1%aa]=b1;//a所在樹成為b所在樹的子樹
           }
           }
           }
          
           function drawline(a,b)//劃線,要判斷是上下還是左右
           {
          
           var x1=parseInt(a/aa);
           var y1=a%aa;
           var x2=parseInt(b/aa);
           var y2=b%aa; 
           var x3=(x1+x2)/2;
           var y3=(y1+y2)/2;
           if(x1-x2==1||x1-x2==-1)//左右方向的點 需要上下劃線
           {
           //alert(x1);
           // context.beginPath();
           context.strokeStyle = 'white';
           // context.moveTo(30+x3*30,y3*30+15);//
           // context.lineTo(30+x3*30,y3*30+45);
           context.clearRect(29+x3*30, y3*30+16,2,28);
           // context.stroke();
           }
           else
           {
           // context.beginPath();
           context.strokeStyle = 'white';
           // context.moveTo(x3*30+15,30+y3*30);//
           // context.lineTo(45+x3*30,30+y3*30);
           context.clearRect(x3*30+16, 29+y3*30,28,2);
           // context.stroke();
           }
           }
           
           while(search(0)!=search(aa*aa-1))//主要思路
           {
           var num = parseInt(Math.random() * aa*aa );//產生一個小于196的隨機數
           var neihbour=getnei(num);
           if(search(num)==search(neihbour)){continue;}
           else//不在一個上
           {
           isling[num][neihbour]=1;isling[neihbour][num]=1;
           drawline(num,neihbour);//劃線
           union(num,neihbour);
           
           }
           }
           </script>
          </html>


          方塊移動

          這部分我采用的方法不是動態真的移動,而是一格一格的跳躍。也就是當走到下一個格子將當前格子的方塊擦掉,在移動的那個格子中再畫一個方塊。選擇方塊是因為方塊更方便擦除,可以根據像素大小精準擦除。

          另外,再移動中要注意不能穿墻、越界。那么怎么判斷呢?很好辦,我們再前面會判斷兩個格子是否聯通,如果不連通我們將把這個墻拆開。再拆的時候把這個墻的時候記錄這兩點拆墻可走即可(數組)

          另外,事件的監聽上下左右查一查就可以得到,添加按鈕對一些事件監聽,這些不是最主要的。

          為了豐富游戲可玩性,將方法封裝,可以設置關卡(只需改變迷宮大小)。這樣就可以實現通關了。另外,如果寫成動態存庫那就更好了。

          結語

          在線嘗試地址,代碼直接查看網頁源代碼即可!

          筆者前端能力和算法能力有限,寫的可能不是特別好,還請見諒!當然,筆者歡迎和一起熱愛學習的人共同進步、學習!歡迎關注,如果感覺不錯,歡迎關注、點贊!蟹蟹!


          主站蜘蛛池模板: 国产综合视频在线观看一区| 国产日产久久高清欧美一区| 欧美日韩精品一区二区在线观看| 亚洲一区AV无码少妇电影| 日韩最新视频一区二区三| 国产一区二区精品久久凹凸| 在线一区二区三区| 少妇激情一区二区三区视频| 一区二区三区四区在线播放| 亚洲av无码片vr一区二区三区| 国产韩国精品一区二区三区| 中文乱码人妻系列一区二区| 亚洲AV福利天堂一区二区三| 丰满岳乱妇一区二区三区| 国模无码一区二区三区| 无码国产精品一区二区免费16| 一区二区高清在线| 日韩精品一区二区三区在线观看l| 精品国产乱子伦一区二区三区| 国产在线精品一区二区三区直播| 精品91一区二区三区| 久久久久久人妻一区二区三区| 97久久精品无码一区二区天美| 日本一区二区在线| 日本在线不卡一区| 亚洲国产精品一区二区第一页| 内射女校花一区二区三区| 精品乱子伦一区二区三区高清免费播放| 成人区人妻精品一区二区三区| 人妖在线精品一区二区三区| 精品一区二区三区四区在线播放| 亚洲国产一区二区三区青草影视| 色狠狠一区二区三区香蕉蜜桃| 精品一区二区三区免费观看| 亚洲人AV永久一区二区三区久久| 人妻体内射精一区二区| 亚洲一区无码精品色| 久久久国产一区二区三区| 国产精品一区三区| 国产爆乳无码一区二区麻豆| 消息称老熟妇乱视频一区二区|