示例
Explore 示例
Divooka Explore 示例包中的 Visual Novel 資料夾按順序講解 Novella,從三個節點一直到完整的遊戲。每個文件都可以直接執行:三個完整遊戲 Moon Festival Riddles、A Match for the Matchmaker 和 The Red Thread 都把各自的美術、聲音和指令碼放在文件的庫中。從 Variables and Effects 到 A Lantern Stall 的 11 個文件,每次講解一個概念,介紹不用任何指令碼編寫故事的節點;與 Story as Nodes 一樣,每個文件都通過一個小型 Play Routine 來播放。
本頁面上的每個示例都隨 Divooka Explore 一同提供,包括 The Red Thread;這裡沒有任何東西需要另外取得。
| 示例 | 形式 | 講解內容 |
|---|---|---|
| Hello Novella | Routine 圖 | 最小的遊戲:Make Novella Game、Load Script(故事放在一個 Text 節點上)、Run。故事還沒有美術素材,因此 Novella 會繪製佔點陣圖。 |
| Characters and Images | Routine 圖 | 用節點而不是指令碼定義來配置的遊戲:Define Image 定義的色塊(與內建的 black 和 white 並用)、帶顏色和影像標記的 Define Character、Set Theme 和 Set Default。 |
| Story as Nodes | Flows 圖 | 以資料形式構建的場景:Start Sequence、Scene、Narrate、Show、Say,以及一個選項為 Make Choice 節點的 Menu,然後是 Make Label、Start Story、Add Label 和 Make Game Definition。 |
| Variables and Effects | Flows 圖 | 無指令碼節點,第 1 課(共 11 課)。一個夜市場景:Add Default 為變數設定初始值,Apply Effect 在它在序列中所處的位置更改變數,配合 Combine Effects、Add To Variable、Set Variable 和 Add To List;每次更改都會通過 [variable] 顯示在下一句臺詞中。 |
| Conditions | Flows 圖 | 第 2 課(共 11 課)。走向月門的一段路:每句臺詞一個 If,分別基於 Variable At Least、Has Visited、Compare Variable 和 Variable Is Set,另有兩個基於 All Of 和 Any Of 並搭配 Not。第一個標籤以 Return 結束,因為用節點構建的標籤不會像指令碼中的標籤那樣落入下一個標籤。 |
| Choices That Remember | Flows 圖 | 第 3 課(共 11 課)。故事會用 Jump 回到的船伕選單,其中 Make Choice 接受一個 Condition,使某個問題在被問到之前一直可選,而渡河選項只在問過之後才出現。 |
| Scenes | Flows 圖 | 第 4 課(共 11 課)。四個場景,每個都是帶背景、轉場和音樂的 Make Scene,結尾分別為 Choose Scene(在 Scene Choice 上帶條件和效果)、Branch To Scene、Go To Scene 和 End Game,並用 Add Scene 彙集起來。 |
| Achievements and Gallery | Flows 圖 | 第 5 課(共 11 課)。一次孔明燈許願:Add Achievement(其中一個是隱藏成就)、每個選項中的 Achieve,以及 Add Gallery Entry,用於一張被看到後即在畫廊中解鎖的圖片。 |
| Animation and Transforms | Flows 圖 | 第 6 課(共 11 課)。河上升起的燈籠:兩段由 Start Animation、Set Property、Animate Property、Also Change 和 Repeat 構建的動畫,一段由 Define Transform 命名並帶參數,用 Show With Options 以 truecenter, float 顯示,之後改為 float(60);另一段直接連到某個 Show With Options 的 Animation 引腳。燈籠本身是用 Add Animated Image 製作的動畫影像:Show Picture 步驟之間穿插 Wait,讓它在亮和暗兩張圖片之間閃爍,無論在哪裡顯示、如何移動都是如此。 |
| Screens | Flows 圖 | 第 7 課(共 11 課)。一塊謎題板,用 Start Screen、Add Screen Text、兩個 Add Screen Button 和一個動作為 Answer 的 Add Screen Timer 佈局,旁邊是一個帶 Add Screen Bar 的狀態介面;Add Screen 把兩者放入故事,Show Screen 把狀態介面疊加在場景上,Call Screen 兩次調出謎題板,If 檢查 _return 中的答案。 |
| A Bag of Gifts | Flows 圖 | 第 8 課(共 11 課)。一個用容器佈局並跟隨故事變化的介面:Start Screen,然後是 Add Box(一個裝著 vbox 的 frame),其內容從 Start Contents 開始:一個標題;遍歷 bag 列表的 Add For Each,每件禮物一個按鈕(其動作是由 Set Variable To Action chosen = item 和 Close Screen 組成的 Then Action);以及在袋子為空時顯示一行文字的 Add If。故事呼叫該介面,用 Change Variable By Variable(bag -= chosen)取出禮物,然後再次呼叫,此時少了一個按鈕。 |
| Logic in Function Graphs | Function 圖和 Flows 圖 | 第 9 課(共 11 課)。條件和效果節點無法組合出的判斷和值,仍然不用指令碼:兩個成員 Function 圖接受一個 Story Variables,並用它的 const 成員之一 Number 讀取它,正是這一點讓資料流 Function 圖可以呼叫它;Is Generous 回答真或假,Blessing 返回一個數字,Condition From Function 和 Number From Function 在其函式引腳上指定它們。 |
| Styles | Flows 圖 | 第 10 課(共 11 課)。在節日之夜重新設定樣式的 Novella 自有介面,每個樣式一行:Start Style,每個屬性一個 Set Style Property,其值按指令碼中的寫法給出("gui/window.png" 帶引號,(64, 64, 64, 64) 帶括號),以及 Add Style。對話方塊和名字標籤使用繪製好的九宮格圖片,選項在空閒時用一張圖片、在指標懸停時用另一張(State hover);嫦娥(Chang'e)通過 Character Part Style 和 Set Character Style Property,在她專屬的對話方塊 moon_window 中說話,其父樣式是 say_window;{style=lantern} 為一句臺詞中的兩個詞設定樣式。完整的樣式系統參見 樣式。 |
| A Lantern Stall | Flows 圖 | 第 11 課(共 11 課)。用節點為遊戲自己的介面設定樣式:Set Screen Style Prefix stall,使介面的按鈕、按鈕標籤和文字分別用 stall_button、stall_button_text 和 stall_text 繪製;stall_button 在空閒、指標懸停(hover)和不可用(insensitive,用於錢袋買不起的燈籠)時各有一張圖片;Style Last Element 為容器指定 stall_sign,為標題指定 stall_title;Set Last Element Style Property 只在一個按鈕上設定 text_size。該介面被呼叫兩次,每個燈籠的按鈕用 Set Variable To Action 付款。 |
| Game as a Function | Function 圖和 Flows 圖 | 函式式工作流:成員 Function 圖 Build Game 返回一個 Game Definition,Flows 圖呼叫它並播放。 |
| Live Script | Events 圖 | 一個 Novella Application,其 Script 事件就是故事,Menu 的回答連到 Branch;並說明為什麼即時指令碼不能存檔。 |
| Commands | Events 圖 | 指令碼中的 run roll 和 run greet "Wei" 由 Command 事件通過 Set Result 迴應,Get Variable 和 Set Variable 存取故事的變數。 |
| Moon Festival Riddles | Events 圖 | 一個小型完整遊戲:中秋節的燈謎,三道謎題、兩個結局、一張畫廊圖片和三個成就,其美術由編寫它的配方繪製。 |
| A Match for the Matchmaker | Function 圖和 Flows 圖 | 完全用節點、不用指令碼編寫的完整遊戲:The Red Thread 的外傳,使用其美術和音樂,六個場景各是一個返回 Scene 的成員 Function 圖。詳見下文。 |
| The Red Thread | Events 圖 | 下文介紹的示例遊戲的完整版本:庫中嵌入了 87 個檔案,Setup 載入它們,Command 迴應故事的 fortune。 |
可以執行其中任何一個,也可以從 Properties 面板中的 Custom Preview 播放某個定義:執行之後選中 Make Game Definition(或任何 Sequence、Label 或 Story 節點),然後按 Custom Preview。這些示例用到的每個節點參見 在 Divooka 中使用 Novella。



較小的文件使用 Novella 的佔點陣圖和色塊,這正是遊戲在美術素材完成之前的樣子:


兩節樣式課繪製了自己的對話方塊、名字標籤、選項和按鈕,遊戲就用它們來繪製:



節點圖
這些圖片由 dvkview 繪製,它是 Parcel NExT 中以無頭方式渲染文件節點圖的實用工具,因此比編輯器中的樣子樸素;節點、字面值和連線都是文件本身的。
Hello Novella,整個遊戲都在一個 Routine 中:

Story as Nodes,一個場景寫成一串 Story Writing 節點,每個選項單獨一行,故事在下方組裝:

Game as a Function:構建定義的成員 Function 圖,以及呼叫並播放它的 Flows 圖:


Live Script,在 Events 圖中以過程形式講述的故事:

Commands,Command 事件按命令名稱分支:

A Match for the Matchmaker
A Match for the Matchmaker 是 The Red Thread 的外傳,使用其美術和音樂講述,完全用 Divooka 節點編寫,沒有指令碼。元宵節前夕,清嵐(Qinglan)的丫鬟小桃(Xiaotao)認定,為別人撮合了上百樁姻緣的王媒婆(Auntie Wang)也該有一樁屬於自己的,於是設法讓她和蘇老爺(Master Su)在月出時同上一座橋。遊戲有三個選單、兩個結局、一個隱藏成就和兩張畫廊圖片。

要了解如何把一個完整遊戲佈局為節點,就該讀這個示例:
| 部分 | 構建方式 |
|---|---|
| 場景 | 六個成員 Function 圖,每個場景一個,各返回一個 Scene:其臺詞是一頁 Story Writing 節點,在邊緣由 Concatenate 連線;其選單和 If 由 Conditions 節點提供輸入;其選項通過 Effects 節點更改變數;其結尾是一個帶 Go To Scene、Choose Scene、Branch To Scene 或 End Game 的 Make Scene。 |
| 故事 | 入口 Flows 圖把角色陣容、Add Default、Add Gallery Entry、Add Achievement 和 Add Scene 彙整合一個故事和一個 Game Definition,並通過與各課相同的 Play Routine 播放。 |
| 外觀 | 成員 Function 圖 Look 通過 With Config 和 With Theme 為定義賦予 The Red Thread 的設定和主題,使遊戲採用示例遊戲的對話方塊、字型和介面音效。 |
| 資源 | 庫中只嵌入了故事用到的圖片、音樂和聲音,以及涵蓋它們的署名和許可證。 |
同一個故事也有逐句對應的 C# 程式版本,即 Parcel NExT 原始碼樹中的 TestPrograms/Novella.Matchmaker,使用 故事構建器 編寫;兩者播放出的文字記錄完全相同。
The Red Thread
The Red Thread(紅線)是 Novella 的示例遊戲:一部簡短而完整的視覺小說,從頭到尾全面運用了引擎的功能。它的 C# 程式是 Parcel NExT 原始碼樹中的 TestPrograms/Novella.RedThread,是 C# API 的標準示例;同一個遊戲也作為 Visual Novel/The Red Thread 隨 Explore 示例包提供,這是一個 Divooka 文件,每張圖片、每個聲音、字型、影片和指令碼都嵌入在它的庫中,其 Events 圖所做的正是 C# 程式所做的:它的 Setup 事件新增庫並載入指令碼,它的 Command 事件迴應故事中唯一的命令。


故事
臨安(Lin'an),一座帶有宋代風味的江南水鄉小城,時值春日。陸文景(Lu Wenjing,即玩家,名字可在開頭更改)是一位年輕書生,寄居城中準備科舉。城裡最忙碌的媒婆王媒婆認定他該娶茶商之女蘇清嵐(Su Qinglan);而清嵐會彈古琴,根本不打算讓任何人給她說媒。從梅花開放到元宵節的幾個星期裡,書生可以通過傳統的求愛習俗贏得她的青睞:唱和詩句、挑選禮物、猜燈謎,最後請媒婆正式提親——或者不提。
月老——月下為命中註定成婚之人繫上紅線的老人——的傳說貫穿整個故事:故事以紅線開篇,也以紅線收尾。
| 角色 | 身份 |
|---|---|
| Su Qinglan (蘇清嵐) | 女主角:機智、精通音律、獨立。 |
| Auntie Wang (王媒婆) | 媒婆:嗓門大、滑稽,內心善良。 |
| Xiaotao (小桃) | 清嵐的丫鬟兼傳話人,調皮。 |
| Master Su (蘇老爺) | 她的父親,一位嚴厲的茶商。 |
| Lu Wenjing (陸文景) | 玩家,只以側邊影像出現。 |
| Yue Lao (月老) | 月下老人,出現在序章和尾聲中。 |
各章依次為月下序章、茶館、梅林、集市、荷花亭、元宵節和提親,共有三個結局:訂婚併成婚;一段友情,清嵐離開去京城學習音樂並寫信來;以及姻緣另結他處,書生回到他的書本中。








觀看
以下影片直接錄自引擎本身,通過真實控制元件遊玩(無頭執行,因此沒有聲音)。片頭影片、為書生命名、序章和茶館:
梅林及其對聯:
簡體中文版的元宵節:
提親和婚禮:
展示的功能
| 功能 | 位置 |
|---|---|
| 分佈在多個指令碼中、合併為一個整體的故事:設定、定義,然後每章一個檔案 | scripts/options.novella、script_01_definitions.novella ... script_09_endings.novella |
| 用指令碼編寫的配置和完整主題:英文和中文字型、九宮格對話方塊、名字標籤和選項、介面音效 | options.novella |
片頭影片,然後用 input 為玩家命名 |
序章 |
帶參數的可複用標籤 call chapter_title("Chapter One", "The Teahouse"),以及置中的標題卡 |
每一章 |
| 由檔案命名的影像、角色說話時變換的表情、玩家的側邊影像 | 貫穿全篇 |
帶參數的動畫變換(sway、drift、hop、slow_zoom)和具名轉場 |
定義部分和每個場景 |
在 while 中用 menu set 編寫的問答,使每盞燈籠只讀一次 |
元宵節 |
用 C# 實現的 run fortune 命令,從故事的隨機數生成器中抽取,因此回滾無法重新抽籤 |
元宵節 |
決定結局的變數(affection、sincerity、riddles_solved、gift) |
各結局 |
| 一封以 NVL 頁面呈現的信 | 友情結局 |
| 持久資料、畫廊、音樂空間和成就,其中包括一個隱藏成就和一個看完所有結局的成就 | 定義部分和各結局 |
| 以顯式臺詞 id 為鍵的完整簡體中文翻譯,並有用於名字、選項、標題和籤文的字串表 | zh_hans.novella |
整個遊戲的簡體中文版,介面也是中文:



執行
遊戲的美術、音樂、聲音、字型和影片存放在倉庫之外(倉庫中不儲存二進位制媒體檔案),也不會單獨釋出:要獲得完整遊戲,方法是使用 Explore 文件,它的庫中包含每一個檔案;而 C# 程式則從一個資料夾中讀取它們。這套資源中的每一項都是臨時替代品,釋出前需替換為原創作品,其署名和許可證隨資源一同提供(CREDITS.md 和 licenses/)。程式按以下順序尋找資原始檔夾:第一個命令列參數、NOVELLA_RED_THREAD_ASSETS 環境變數所指定的資料夾、程式旁的 Assets 資料夾(已釋出的副本就是這樣提供的:以自包含方式釋出,並把資源放在它旁邊),最後是使用者主資料夾下的 Data/Novella/The Red Thread。
TheRedThread [assets folder]
TheRedThread --lint [assets folder]
TheRedThread --shoot out-folder [--choices 0,1,2] [--language zh-Hans] [--steps 900] [--every 20] [assets folder]
--lint 將故事與其檔案進行核對;--shoot 以無頭方式通過真實控制元件遊玩,每隔幾步儲存一張帶描述的截圖,並儲存一份文字記錄,按給定的選項進行選擇(之後選第一個),可選擇使用另一種語言,如果有任何內容缺失或失敗,則以退出碼 3 退出。