適合小型遊戲快速創建原型的方法

作者:Jakub Kasztalski

對於我最初的兩款遊戲《Postmortem》和《Karaski》,使用的傳統工具去管理遊戲數據,以下便是有關遊戲對話樹的例子:

karaski129-indie-game-dialogue-sneaking(from gamasutra)

karaski129-indie-game-dialogue-sneaking(from gamasutra)

我使用了免費的yEd圖表編輯器以及一些自定義編碼將XML數據輸入我的遊戲中。我同時還爲所有遊戲內部文本內容解析了一些簡單的文本文件。這一系統非常有效,但卻需要花些時間進行設置與調試。當我開始致力於自己的故事/冒險遊戲《HEADLINER》時,我便更傾向於快速原型創建。我不想再去想全新的數據結構並再次在JavaScript上編寫分析程序。正是在這時候我想到了,爲什麼不直接在代碼中明確我的數據呢?

newspapers中的簡單字符串

閱讀newspaper數據字符串的“適當”方式便是去創造一份清楚的JSON文件,對其進行解析並創造適當的對象。但我略過了中間人而直接在獨立的JavaScript文件中定義了它們。如下所示:

headliner-newspaper-files(from gamasutra)

headliner-newspaper-files(from gamasutra)

它幾乎沒有任何語法問題,我可以通過簡單整合JS文件而擁有一個即時可行的數據結構。我並不需要進行任何“加載”或解析。我同時也添加了一些腳本對象(如ReqApproved),如此我只需要檢查每個遊戲日去判斷是否需要呈現特定paper。

交談中的條件分支

因爲我並未計劃太多分支,反倒我希望看到的是條件反應,所以我需要設置一些if/else條件,這是參考world-state變量並設置它們的一種方法。即意味着編寫一個分析程序並執行一些腳本形式。再一次地,我意識到,不,等等,爲什麼要編寫代碼去解釋代碼?我可以直接寫下代碼的。所以我的交談將變成另一個JavaScript文件。我寫下一些輔助功能去設置NPC的講話或獲取代幣等等。

neverwinter-nights-dialogue-editor(from gamasutra)

neverwinter-nights-dialogue-editor(from gamasutra)

我們並不需要去解析代碼,因爲它是自動執行的。它需要的是更多語法問題,但一旦你能理解一個奇怪的結構和輔助功能,這些語法問題便是可解決的。

headliner-conversation-files(from gamasutra)

headliner-conversation-files(from gamasutra)

實體和NPC

爲了創造一個充滿真實的生物和吸引人的戰利品的世界,大多數遊戲都使用了編輯器在3D或2D空間呈現這些內容。然後遊戲將在開啓時加載這些“場景”並創造所有明確好的實體。然後就是各種解析。

我並未使用Phaser和JavaScript去這麼做(而如果你想要一個開箱即可使用的方法我還是會推薦你Phaser Editor),基於各種不同條件每個遊戲日也會有所不同。所以就像之前那樣,我劃分了代碼本身:

headliner-npc-spawning-code(from gamasutra)

headliner-npc-spawning-code(from gamasutra)

基於一些輔助功能以及關於位置標記的預設常量,我將能夠快速創造遊戲世界。因爲這是一種代碼,所以我可以通過檢測變量,事件觸發器或隨機結果去自定義每個遊戲日。如此無需輸出或解析第三方編輯器,我便能夠馬上呈現出所有改變內容。這非常適合在一個地方調整內容並確保所有內容的清楚有序。

這一方法並不適用所有人

需要注意的是,這一基於代碼的數據方法只適用於原型創建或擁有容易管理的數據且所有參與遊戲製作的人都清楚代碼基礎的小型遊戲。如果使用得當的話這將能幫助你省下許多時間,但是對於基於更復雜結構或擁有明確團隊角色的更大型項目來說就不是如此了。這也是我要設置整個系統從第三方圖表編輯器(擁有關於我的前兩款遊戲的交談的腳本支持)中輸入XML數據的原因。在兩年的製作中我發現從視覺上編輯對話的能力非常重要,即使是我那非技術型作家也能有效使用該方法。但如何嘗試在代碼中定義這一方法將會很可怕:

karas64-indie-game-dialogue-tree(from gamasutra)

karas64-indie-game-dialogue-tree(from gamasutra)

所以就像在線遊戲開發教程那樣,考慮一些常識也很重要。這也只是一種適用於特定情況的特殊工具。

本文爲遊戲邦/gamerboom.com編譯,拒絕任何不保留版權的轉發,如需轉載請聯繫:遊戲邦

Rapid Prototyping Tip: Defining data as code files

by Jakub Kasztalski

I used the free yEd graph editor and a bit of custom coding to import the XML data into my game (read about it here!). I also parsed simple text files for all the in-game text items like newspapers. The system worked great, but took a while to set up and debug. As I started on my current experimental story/adventure game HEADLINER, I was embracing a more rapid-prototyping mindset. I did not want to come up with new fancy data structures and write parsers yet again in JavaScript. And it occurred to me – why not define my data directly in code?

Simple strings in newspapers

The “proper” way to read the newspaper data strings would be to create a neatly laid out JSON file, parse that, and create appropriate objects. But I skipped the middle-man, and instead defined them in a separate JavaScript file directly as objects and arrays. Here’s what it looks like:

It’s barely a little bit of extra syntax fluff, and I had instantly-accessible data structure I could reference by simply including the JS file! I didn’t need to do any “loading” or parsing either. I also dded a few scripting members (like the ReqApproved) that I’d just check each game day to see if given paper should show or not.

Conditional branching in conversations

Previously I used graphs for flexibility, and many RPG games used flat text files or the (godawfully difficult to follow) trees, like in Neverwinter Nights.

Since I didn’t plan on too much branching but wanted conditional responses, I’d need to set up some if/else conditions, a way to reference world-state variables, and a way to set them. Meaning: coding a parser and implementing some form of scripting. Again, I realized – wait, why write code that interprets code? I can just write code directly. And so my conversations became yet another Javascript file. I wrote a few helper functions for setting what the NPC says or getting tokens like Player Name, and boom!

No need to parse code or tokens, since it’s automatically executed. Yes, it does require more syntax fluff, but it’s pretty manageable once you get the hang of the weird structure and helper functions (like SetThread() or AddResponse()).

Entities and NPCs

To create a world brimming with lively creatures and lucrative loot, most games have some sort of editor to visually place those in 3d or 2d space. The game then loads these “scenes” at startup and creates all the entities as defined. Parsing, parsing, parsing…

I didn’t have that with Phaser and JavaScript (though I recommend checking out the Phaser Editor if you’d like an out of the box solution), and each game day would vary a lot depending on numerous conditions. Like before, I differed to the code itself:

With a few helper functions (Spawn two NPCS with a dialogue, spawn a group of protesters, spawn a rioter who runs and throws a molotov etc.) and pre-defined constants for locations markers, I could quickly create my game world. Because it is code, I could customize each game day by checking for variables, event triggers or randomizing results. All my changes showed up instantly without any exporting/parsing from a 3rd party editor. And it was good for tweaking, keeping everything neatly in one place (rather than closing/reopening multile “day scenes” or tracking conditionals on each entity individually).

This solution is not for everyone

An important caveat needs to be made. This data-in-code approach is really meant for prototyping or small games where you know the amount of data will always be manageable and everyone working with it knows the basics of coding. It can be a huge huge time saver when used properly, but a hindrance on bigger projects with more complex structures or delineated team roles. There is a reason why I set up a whole system to import XML data from a 3rd party graph editor with scripting support for conversations in my first two games. Over the two years of production, the ability to visually edit the dialogue was very important, and it allowed my non-tech savvy writers to work with it as well. Trying to define THIS purely in code would have been a disaster:

So, as with any online game dev tutorial, exercise a bit of common sense. It’s just a specific tool meant to be used in specific situations.

Curious about my games?

The project that inspired this blog is HEADLINER, story-driven game where you control public opinion and (potentially) start a riot. Check out the official page here. Better yet, why not follow me on Facebook or Twitter for updates and other game dev nuggets of wisdom?(source:gamasutra