2014-10-17

System in action

This is a little preview of the current working state of my system Fate.

I'm starting with some source code put together from the last example. I use Sublime Text for writing since it allows for syntax highlights and code snippets and other nice things.



The source is saved inside a resource folder in a Unity project. I can open the visual editor to make sure that everything compiles, then I'm ready to build an executable.



Unity does its thing and then the game is ready to play.



When the game starts up the first thing that the system does is copy the source code from the project into a folder on the local drive. This copy contains the exact same source text files, and it is what will be read into the game in place of the original. In other words this makes the source of the game available to be modded if the player wants.



Next the system reads the files from this directory and compiles the source code into a game. If this process fails there will be an ugly error like this.



As you can see, these warning messages aren't always very specific, so I have a lot of work to do to make debugging reasonable. Generally though, the default game source *should* be bug free. One challenge here is that a lot of the source is compiled up front, but some things can obviously only be evaluated during the game, so run time issues may pop up with the same error.

If all goes well we are taken to the game's title screen. All of the values here (author, title, brief description) are exposed in the source code via content functions. This makes the system pretty flexible and generic, but right now it's a little too generic visually.



I can exit out of the game and modify the source code with this line:
content("sensitiveContent", "true")
This marks the game as containing restricted material. Now when we start the game we will get a disclaimer with a rating and content details that we set.



Back on the title page we can navigate to the about page that shows other data we can specify about the game. One cool thing that I'm not showing here is that the number of contributions by a contributor are counted, and under the credits contributors are sorted by most contributions to least.



Anyway onto the game itself. Once we press New Game from the main menu, we enter the first passage, Start.



There are a good amount of options available to adjust the text for readability.



A game could be entirely choice based, world based or a mixture of the two. When mixing the two (which is pretty much what I'm doing) you make choices until you reach end points where you are then free to explore the world. World exploration/interaction is done with a horizontal infinitely scrollable list of nouns and then actions on those nouns.



Once items are picked up they get held in a separate list just for inventory. This was an important addition I made during the rewrite since it helps to keep the main list of nouns less crowded while playing.



We can save our progress and the save goes into a saves directory beside the source folder. I currently don't have undo/redo exposed in the interface, but the history system is able to go from wherever you are all the way to back Start. All choices are included in game saves.



If we quit and reload, we automatically return to where we left off by loading the most recent save. Otherwise saves are accessible via a simple menu from within the game.



And finally once we reach an end point specified with control("end") our game is auto-saved and we can return to the home screen when ready. (ignore that bit about the world menu still being displayed >_>)



So there you have a quick run down of the system. I can't even really measure all the work that has gone into this, but I really think it was worth it. I still have some important things to do before I can release a playable demo for desktop platforms. Android is quite a headache due to resolution issues and iOS is a pie in the sky. My current focus is on writing Something, so I guess my next post will be about that.

2014-10-06

story map

Last time I talked about the syntax I'm using to write stuff. In this post I'll show some micro examples along with images of the story map representation.

Lets start with a basic example using the following source.



I guess you could say I was kinda *inspired* by Twine again. I couldn't think of a better way to represent the basic information of going between passages, so, what more can I say.


Moving on, here is an example using a display() passage. It works a lot like <<display>> would, basically adding one passage in it's place when evaluated at run time.



I use display() a lot, so I decided to highlight those passages in the map for faster recognition.


In this next example I use some implicit links and display()s.



They also got unique colors to help them stand out. I don't use them all of the time, but when I need them they are super helpful to have.


Now onto the world portion of things. This source code sets up a basic world structure with five different nouns and a couple verbs. Notice that a Start passage is still required since it is always the entry point of a game.




The nouns act kind of like a layer beneath passages. Each parent noun draws a white line to it's children. The green lines connect the actions on nouns to the passage responses of those actions. These links get pretty crowded, so I'm still not entirely happy with the way this is setup. For now though, it works.


Now an example with more stuff going on.



This time in Start I use control() to make the captain the player. With that set, the icon for the captain changes along with many of the other nouns. The treasure chest is taken by the captain at some point, so it gets represented as a pickup. All of the places where the captain moves get a container icon, since these locations could be rooms, vehicles or anything really. The Isle is still the default static icon because it never moves and never holds the player directly. Static objects are mostly useful for grouping nouns together, but don't need to serve any purpose in game. Finally the demon has the red dynamic icon since it does move around.

All of the little icons help add useful information that otherwise aren't represented in the source code.

Since this is all in the Scene view of the Unity editor I decided to add another perspective of the world to help understand what is going on.


From a top view we get a floor plan of the world at it's default state. It's much easier to see which object is inside of another this way. I've found that I don't need to make diagrams of this stuff anymore since it is easily represented here. The connecting lines are in the way in this image, but they can be toggled off.

And so that's the story map.

2014-10-02

syntax

The way I'd like to write games is simple. Write some text, then view it in a node map and repeat. The rewrite of Fate was mostly so that I could do just that.

The first thing I needed to do was formalize a syntax for writing that could handle the type of games I'd like to make. I started with tweecode as a base. Passages mark collections of text, and they look like they would with Twine.


Links between passages are done with familiar double brackets:


I didn't want to keep the Macro syntax: <<set $thing = 8>> , so I slimmed it down like this: set($thing = 8) but I kept the $ character prefix on variables as an act of habit.

One interesting feature I had to figure out how to represent are implicit links:


The query() part sets the value of 'passage' to 8 before executing a query to find the best passage to display. So to define passages that are queried:


Basically the criteria() function binds the passage to it's arguments. To save a little writing I setup the ability to stack multiple passage responses under a single passage declaration.


Then there is the world system (although it's not really that amazing of a system). I opted for familiarity in the declaration of passages, nouns and verbs.


The noun() call is done where tags would be in tweecode. Notice that the noun() function for 'Room' has 'House' as an argument. It basically sets up the default hierarchy of the two objects; the room is a child of the house. The body of these declarations are automatically mapped as descriptions that respond to an examine action.

Actions are declared in a similar way.


Verbs that shouldn't always be available can use a require() function.


require() was necessary in addition to criteria() since responses to verbs may need to be tied to criteria since they are essentially passages.


Moving objects around is done with a move() function


I skipped a lot of functionality (print, display, if/else etc), but that is a quick look at the basics of how I'm writing Something in Fate.