Gaming Your Way

May contain nuts.

I AM NOT YOUR F1 BUTTON!

Code won the game.

This only makes sense if you've read last week's post about FSMs. At some time during clicking and dragging states and trying to fit my idea into the corset of the FSM, I figured I need to write my own actions to make things worthwhile. So I started to write my own action. The problem is once you start writing your own, you need to find a point to stop and expose values to the FSM (that can then fetch these and pass to the next action ...).

With this working quite well, I came to the point where I needed to pass more than a single string or float, but my own class with data (or I had to pass a set of values) and suddenly the beauty of this new toy (the FSM and it's supposed easiness) started to fall apart. Years of coding took over the show, brain cells kicked into crunch mode and in an act of fury I deleted the FSMs from the game. A good deal of hours fiddling and working against instinct paid it's price and code once again won the game.

A few hours later the door control was coded and working, multi language ready, too:

 


Tooltips and control hints up and running and talking to each other via SendMessage, so no links in code are needed.

The interface for using the tooltips is unified and based on "Items" that carry a name, a set of actions and "results" (inspired by classic adventure games). So the Control panel right of the door has the "Item" component attached, it is also linked to the door (to request the door's state). In the image above the door's state is "locked" and the action for the control panel is "unlock door". The result is a new door state: "closed" and a changed action on the control panel "open door", plus the control hint is being updated.


I need more time...

Of course opening a door using a code (or hacking it if you don't have the code yet) takes time, this is also handled by the item, allowing to set a time these action needs to be performed - from 1 sec to a few minutes (it also handles if the time should reset if you leave before the task is performed).

Searching items is done as well, so if you search one of the blue boxes you find the key code for the door and can use it.

Next on the list are guards and the security cameras with these in place the map will be more or less playable and can be dressed for a quick game.

But that's for next week's post.

-- Oliver / nGFX

Strangely addictive

I've been toying with playmaker (a visual state machine) for while now and I'm still not quite sure what to think of it. On one hand it can make things incredibly easy, on the other hand it can be a huge pain in the ass to get things done.

Let's take one of the easier examples: a simple door.


Ingame door, developer art :).

All the basic FSM tutorials consist of the same basic parts: a door, a trigger and a set of animations to open/close the door. Of course you could also code the opening/closing animation... I deal with that later. Let's take a look at the FSM for this door (not as basic, though).


Even in this image there's trouble ahead.

The tutorials get along with four states: closed, opening, open, closing. When the state is closed the FSM listens to the trigger and when it is fired it goes to "opening". The "opening" state simply plays the animation and continues to the "open" state. The open state then listens for the trigger and if fired goes to" closing". Viola.

The problem is that in my case I have some more conditions to check and I want to paste some initial values as well. A door can be open, closed or locked. Additionally, if the door is open, it should test if the should stay open, and if the door is looked which key is required.

The FSM above could be done in a way better organized way, but this is the very first working draft...

...and to be honest, will be replaced by code.

I find a strange attraction in the thought to be able to do things visually and it's always worth a try, but at some point one has to admit that it would be easier to just code it the darn thing. The FSM works great, but it took me a good while to get my head into it - and there we have the result of years of coding: I have an idea how to code this right from "I need a door" and for me it is a lot of work to leave this path and break things down into parts I can built as FSM. This time the FSM lost, it may win next time.

You can't make an omelette without breaking an egg

(from: Some Like It Hot)

Even though the title is a quote from a movie, it also is very true for development. As mentioned last post I was about to rewrite (again) parts of the game to make it easier to maintain and debug.

One of the bigger changes is that I moved states from code to a visual finite state machine (FSM). Honestly it was one of the better ideas I had since I started with a game I have virtually no "knowledge" of (because I really don't like racing games). As a result I killed about 2/3 of the code in my "RaceController", reducing it to (currently) ~300 lines of code.


Early version of the RaceController FSM.

The final version is a bit more complex, though. To be true this doesn't count in the code needed for the FSM, but *my.* code is a lot shorter now.

For the AI code however it is something different and I found it a fine line between using the FSM and handle things through code. I had to decide whether to make "Reached waypoint, what now?" a simple method call or a state. The AI is done in code now as most events coming in just alter target values that are dealt with in the main loop of the AI.

In any case this makes the AI a tad more robust when dealing with corners, speed and lanes. For example there is a value that keeps track of the lane the car is on (0 being the inner lane, 1 the outer and 0.5 the middle of the road). When the AI decides it wants to change the lane from 0 to 1 (because in corners the inner lane is faster) it sets the fTargetLane to 1 instead of fLane (the variable that holds the current lane we're on). Before easing the lane value the AI can now check if there is room to change the lane (another car blocking the way) and delay easing. Same goes for speed and steering.

Easing between current and target value also allows to add some "personality" to the AI, but that's stuff for a later post.

"All right, driver, once around the park, slowly, and keep your eyes on the road."
(again, Some Like It Hot)

-- Oliver / nGFX