分支劇情創作中的挑戰和工具

icue發表於2021-07-30
引言

在製作遊戲時,我們常遇見一種四個字就能概括的問題:分支劇情。它構想起來並不困難,無論是腦海中、紙面上還是電子螢幕上,我們都能順其自然地畫出劇情流程圖。然而待具體實現時,這簡單的幾個字下卻隱藏著諸多挑戰——要以何種方式創作分支劇情,才能把它轉變成遊戲引擎,或者說機器能夠理解的媒介?

分支劇情創作中的挑戰和工具

困難究竟在哪

如果把剛才這個問題中的“分支”兩個字去掉,它彷彿就變得不那麼棘手了。最顯而易見的辦法,無非是把所有的“在某件事發生之後觸發哪個新的事件”、“誰在何時說了一句什麼話”等等直接寫到遊戲本身的邏輯裡去。雖然這個方法到頭來會讓劇情變得較難維護、對本地化不友好,但起碼它直白、可行。

那麼現在我們把“分支”兩個字加回來。最直接的辦法其實仍然存在——條件語句嘛。在現有的程式碼裡,加上一個“取決於主角是否已完成某個任務,走向 A 劇情或者 B 劇情”不難吧?畢竟“完成過某個任務”是應該很容易拿到的一個、本身就會因為其它理由而存在的資料——等一下,如果是沒那麼唾手可得的資訊呢?

如果劇情的分支需要取決於“主角是否與某名 NPC 有過交流”呢?這個資訊聽起來並不像是本來就會被記錄的那種。辦法還是有——記錄下來嘛。每次主角與任何 NPC 交流,都在 Gameplay 邏輯中,額外地在遊戲的資料庫裡標記一下。現在,可想而知,由於劇情走向難免會取決於各種資訊,我們經常需要在 Gameplay 邏輯中記錄和管理雜七雜八的、可能只服務於劇情的狀態。

然而,當蜿蜒曲折的劇情發展到後期,即便我們做到了管理各種狀態,條件語句也會變得越來越臃腫。這麼做同時帶來了更嚴重、也是剛才一直被逃避的問題:Gameplay 邏輯和敘事邏輯被混在一起,使得除錯、排查和維護任何一邊都變得愈發困難。某一段劇情沒有按照預想的方式被觸發,可能是因為此刻滑鼠的點選沒有被監聽到,也可能是因為劇情上的觸發條件沒有寫完備——到了這一步,開發只會越來越低效。

所以我們的問題變成了:如何既在敘事中安插分支,又將 Gameplay 邏輯與敘事邏輯儘量解耦,保證兩邊的思路各自清晰。

況且,剛才的分析都建立在了一個隱形的條件上——(對於作家和程式分開的團隊來說)為遊戲創作劇本的作家也得花時間和精力學習遊戲引擎和程式碼,不然就得讓程式設計師特地將劇情邏輯“複製”進遊戲程式碼當中去。怎麼選都不是什麼優雅的方案,所以我們更加需要設法解耦,讓寫故事的人和寫程式的人互不干擾,各自最大效率地產出內容。

常見解決方案

其實有些讀者讀到這兒,在腦海中應該能預想出一個解決方案了。說白了,我們需要的是一個獨立於遊戲引擎,但又比日常的文字編輯器強大的劇情編輯工具。它起碼得對作家友好、能設計分支劇情、跟蹤狀態,以 Gameplay 邏輯為輔而不是為主,並生成能被遊戲引擎識別的內容。

幸運的是,這個問題早已被許多遊戲開發者意識到了,也因此湧現出不少外掛、工具和敘事引擎。我在這裡介紹幾款較為主流的,它們的使用場景有重疊,但也有不同。需要額外指出的是,針對 Galgame 以及型別相似的文字冒險遊戲,已有較為成熟的遊戲引擎,本文探討的諸如分支流程等問題已經被那些引擎自然而然地解決了。所以,接下來要介紹的這些工具,是應用於非文字冒險、但又涉及到分支劇情/對話的那些遊戲的。《極樂迪斯科(Disco Elysium)》?《霓虹出租(Neo Cab)》?《林中之夜(Night in the Woods)》?是,就是那些風格。事實上,這幾個遊戲全都使用了這些工具中的某一個。

限於篇幅,我不能對這些工具深入展開,希望簡短的介紹起碼能講清楚它們各自是什麼。至於具體怎麼用,我會在小標題連結到官網,那裡通常配有技術文件幫助上手。

Twine

Twine 連結地址

Twine 是一個開源的基於網頁的分支劇情創作器。

分支劇情創作中的挑戰和工具

每個劇情節點內都包含了一段文字劇情,節點之間的箭頭使流向變得直觀,分叉處也顯而易見

從未寫過程式碼的人可以迅速上手,而對於有程式設計經驗的人來說,Twine 也提供了語法來實現賦值變數、條件控制(某些選項只有滿足特定條件才會可選)等。

Twine 可以線上使用也可以下載客戶端。撰寫劇本的過程中可以隨時從指定節點起“試玩”接下來的劇情,遊玩的過程即用滑鼠在網頁上點選選項,劇情會按照設計好的路線來推進。這聽起來很簡陋,但這可能是迅速建立一個可玩的互動電子劇本的最快方法了,所以適合迅速搭建原型。

在 itch.io 上有近 6000 個使用 Twine 製作的遊戲,這龐大的數量也得益於 itch.io 對網頁遊戲的支援——Twine 可以直接生成網頁遊戲,但不能生成被其他遊戲引擎讀取的資料檔案。有一個叫做 Cradle 的外掛可將 Twine 生成的故事匯入 Unity,但該外掛已不再維護,隨著 Twine 自身的更新迭代,我並不推薦去研究 Cradle 。如果對 Twine 的操作模式和功能感到滿意,但又不滿足於只在網頁上游玩、想要和遊戲引擎深度整合,那麼接下來的 Yarn 是更好的選擇。

Yarn

Yarn 連結地址

Yarn 開源,基於 Twine,正如它們兩個詞的意思本身也很像。

分支劇情創作中的挑戰和工具

Yarn 的編輯器,但是也可以選擇不借助流程圖,使用文字編輯器

Yarn 的設計者之一 Jon Manning 曾在一個講座上提到過他們的理念:讓作家不需要學寫程式碼,但允許作家通過 Yarn 來實現程式碼能夠實現的事。所以,和 Twine 類似地, Yarn 定義了一套非常簡潔的指令碼語言,來實現條件判斷、變數追蹤等。不同的是 Yarn 可以配合 YarnSpinner 使用,將整個劇情邏輯匯入 Unity(所以在 Unity 的 Gameplay 邏輯裡可以一鍵“進行到下一段劇情”),甚至可以在 Unity 中定義函式,在使用 Yarn 編寫劇情的過程中呼叫它們。

但 Yarn 自身不支援預覽劇情,我的理解是,這意味著只有在匯入 Unity 並完成相關的讀取邏輯以後,才能在 Unity 中試玩到使用 Yarn 創作的劇情。這是 Yarn 目前比較大的一個短板。

從官網可知 Yarn 對本地化的支援不錯。著名的藉助 Yarn 完成的遊戲有《林中之夜(Night in the Woods)》(正是該製作組帶來了 Yarn)、《短途旅行(A Short Hike)》。

ink

ink 連結地址

如果說 Yarn 兼顧了視覺上流程圖的直觀性和邏輯上指令碼語言的靈活性,那麼 ink 可以說是在靈活性上走向了極致——這個工具不提供流程圖,因為劇本片段之間的關係太過千變萬化。

分支劇情創作中的挑戰和工具

ink 的編輯器 inky,左邊進行劇情編寫,右邊則是實時試玩

ink 是帶來了《80 天(80 Days)》《天堂之穹(Heaven's Vault)》等作品的 inkle 工作室開發並開源的一個指令碼語言。主創之一 Jon Ingold 曾不止一次說過他並不喜歡所謂“流程圖”的概念,因為流程圖本身的存在,就意味著節點有固定的先後順序:

A flowchart says this blob exists within a structure, where this comes before and this comes after. In Heaven’s Vault, when Six and Aliya walk around, there’s a bucket of about 3,000 to 4,000 things they can say.

And Ink just runs through all of them and says, ‘give me all the conversations that would make sense at this moment’. And then it says, ‘which one is the most relevant to what you were talking about last’, and it puts that in front of the player. And that’s all it does, there is no structure, no flowchart.

通過 Jon 的這段描述,我們不難理解 inkle 從不依賴流程圖。如果某個角色接下來要說的話有三千種可能性,而這三千個備選項也能存在於不同流程裡更早或更晚的對話中,那麼我們需要的顯然不是流程圖,而是一個篩選器,挑選出最符合當下語境的那一句,然後推進劇情。而被選出來的那一句話,在下一次相似語境中就不會再被選中。

不僅對話,在 inkle 的設計理念中,劇情片段也是一樣的道理。接下來要發生哪段劇情,與上一段發生的是哪段劇情並非強相關,更多地,系統會考量自遊戲開始後的各種狀態、玩家的歷史選擇——ink 預設會記住玩家作過的每一個選擇,包括很久以前的,而不需要我們手動使用變數去跟蹤——從整個劇情池中挑出一個來推進劇情。

當然,ink 仍然支援之前 Twine 和 Yarn 支援的那種傳統分支結構,只是在這裡一切都需要靠指令碼語言去編寫,不再有流程圖了。

擺脫了流程圖的束縛,ink 可以實現相當細膩的“響應式(responsive)文字”。

分支劇情創作中的挑戰和工具

GDC 幻燈片截圖(文末有連結)——上為 ink 中的一段,下為編譯後眾多可能結果中的兩個

在這個例子裡,短短的一段文字,經過隨機短語間的排列組合,取決於玩家是否穿著潮溼的衣服、當前地形是否為樹林,便能有好幾十種最終的呈現方式,底下的兩段只是其中的兩種。若這樣精細的內容調整貫穿整個劇本,那流程圖當然難以體現密密麻麻的走向可能性。

也正是因為沒有流程圖,一旦學習了 ink 的語法,寫劇本的效率要高於其他工具——畢竟不必每次想新增一段劇情,都先用滑鼠在流程圖上新建一個節點了。在這裡,就像傳統寫作那樣,手指不必離開鍵盤,一直打字就行。

ink 官方提供了 Unity 外掛,民間則有虛幻、Godot、GameMaker Studio 2 的外掛。可惜 ink 對本地化的支援不好,用一種語言寫完的劇本,若想要翻譯,那麼劇本里的可變部分(也就是那些響應式的部分)越多,翻譯過程就越艱難,如果跨語系就更加如此。

ink 也不只適用於文字為主的遊戲。作為一個免費的開源工具,怎麼用完全看需求。像《霓虹出租(Neo Cab)》、Sable這類音畫佔比也很大的遊戲,也都使用了 ink。

articy:draft

articy:draft 連結地址

方才的 ink 在寫作過程中可以說是程式導向的,而接下來的 articy:draft 則能滿足物件導向的設計——等一下,寫互動劇本也能物件導向嗎?這不是計算機領域的詞彙嗎?

遊戲開發的本質仍然是程式開發,當然可以物件導向。就拿主角的一句臺詞來說,一句臺詞包含什麼?

倘若我們能想到的只有人物和臺詞這兩個屬性,那還是沒有跳出傳統寫作的框架。試想,在各種需求下,顯示這句話的文字顏色、人物表情的不同立繪、語音播放這句臺詞所需的時間長度、這句臺詞在選項選單裡顯示的縮略文字(因為可能顯示不下完整的臺詞)等等等等,都是遊戲裡可以被繫結在“臺詞”身上的屬性。

而人物的屬性就不言自明瞭,等級、職業、血量……從這個角度出發,我們的確可以物件導向地先定義每句臺詞、每個人物的屬性,設定預設值,進而在創作劇本時系統性地照顧到它作為“遊戲劇本”的方方面面。

而 articy:draft 天然地支援往對話和人物上新增自定義屬性、設定型別和預設值。一旦屬性設定完畢,就能在流程圖的各個地方去引用和修改。使用者也可以自己定義新的 Entity,例如“武器”,設定武器的各個屬性,並在 articy:draft 而不是遊戲引擎內新建多把武器。接著就可以往人物裡新增一個“武器”欄位,代表人物目前持有的武器,而這一切資訊都將在遊戲引擎內被讀取——這進一步說明 articy:draft 適合物件導向的創作思路。

分支劇情創作中的挑戰和工具
articy:draft 的分支對話流程圖

在 articy:draft 的流程圖中,每個節點可以是一段劇情或是一句臺詞,通過條件、指令等串聯。articy:draft 支援節點的無限巢狀,這對管理具有從屬關係的劇情片段非常有幫助;合理安排層級關係,那麼劇情流程圖從外到內就能井井有條。articy:draft 自帶一個資料庫管理的皮膚,可定義全域性變數,在流程圖中讀取和賦值;在預覽故事流程時,還能實時檢視每個變數的值。

配合剛才提到過的“在流程圖內引用和修改人物屬性”、“在 articy:draft 裡管理人物配備的武器”,不難發現 articy:draft 其實已經可以在劇情邏輯裡實現相當一部分 Gameplay 邏輯了。如此一來,一個作家不需要掌握遊戲引擎也能在撰寫劇情的同時包攬一些 Gameplay 邏輯。當然,這是否可取就見仁見智了。

articy:draft 支援本地化、配音、版本管理和多人協作,官方還提供了 Unity 和虛幻的外掛。其實 articy:draft 能做的不僅僅是分支劇情的管理,它還能管理遊戲設計文件、劇本大綱、遊戲地圖等,但這些方面我瞭解得不多,也不是本文討論的重點,故不再展開。

有不少互動小說使用了 articy:draft,如《極樂迪斯科(Disco Elysium)》《奧威爾(Orwell: Keeping an Eye On You)》《駭遊俠探(Gamedec)》等。在官網可以找到相關遊戲各自的訪談。

不同於之前的幾個工具,articy:draft 是收費的,好在 Steam 上打完折也不是很貴。一些大廠如 CDProjekt RED、Techland 也是 articy:draft 的客戶,這麼想,或許能讓這錢花得更心安理得些。

其他方案

  • Chat Mapper:類似 articy:draft 但是訂閱制,我瞭解不多。
  • Dialogue System:Unity 素材商店的強大素材,自身可用於編寫節點式分支對話(但要注意,這等於還是要在 Unity 裡進行劇本創作),也支援 ink、articy:draft、Chat Mapper 等的匯入,將來也會支援 Yarn。
  • 自己實現工具:我相信對於資源豐富的大廠來說,都有成熟的內部工具來輔佐各種型別劇本的創作了。黑曜石就曾分享過他們的分支對話工具使用心得,同樣是基於流程圖的。而對於有閒功夫的獨立遊戲人,想自己造一個這樣的工具出來玩,也值得鼓勵——何況上邊介紹到的許多開源產品都可以用作參考。

結語

讓我們回顧一遍開頭的問題:如何既在敘事中安插分支,又將 Gameplay 邏輯與敘事邏輯儘量解耦,保證兩邊的思路各自清晰?

回想介紹過的那些工具,除了不支援和遊戲引擎結合、但適合快速在網頁上搭建原型的 Twine 以外,其餘都能滿足這個要求。當然,剛開始都需要花時間學習工具本身的使用,以及如何和遊戲引擎結合。另外,可以看到這些工具或多或少都支援從敘事流程中呼叫遊戲引擎裡 Gameplay 相關的函式——如何劃清敘事邏輯與 Gameplay 邏輯的界線也是我沒能展開討論的話題,但我認為這個問題沒有標準答案,很大程度上取決於遊戲本身的性質、甚至創作人員對兩邊工具的熟悉程度。總之,工欲善其事必先利其器,一旦上手,之後的劇本創作和遊戲開發將齊頭並進、不再混沌。

每個工具的設計理念不盡相同,這些簡短的介紹只是一個引子;究竟哪個適合自己,還得留給讀者自行考察與斟酌。即便沒有迫切需求,也希望對這些工具的探討能觸發大家對分支敘事實現方式和應用場景的思考。


來源:indienova
原文:https://indienova.com/indie-game-development/tools-for-branching-dialogs-and-narrative/

相關文章