The Lost Gamestate…

Persisting state of things in an adventure is a really hard thing to crack. Is it coincidence that persisting and resisting sound the same?

I waited some time to implement this because I needed to find out first how the bridging between the Objective C and the Lua code sorted out. Maybe I needed to store the state in anoyher way? And I didn’t had any experience with a dynamic language like Lua. But as I gained more experience with Lua I thought I was ready to implement the save games routines.

But still… The choices you have to make are pretty hard because design mistakes like this will hunt you throughout the development of the game. I looked at various adventure projects currently in development and tried to find out how they had solved this or how they will solve this problem. Some of them solved this by serializing the state if the objects as they were loaded in memory. This is very commonly used in managed languages as Java and C#. In fact,every serious programming language has it’s own way of storing this. Objective C uses NSCoding to make the objects persist-able. I used this technique on earlier games I made but I hated the hard labour you had to put into it. You have to explicitly tell the system what to serialize and not to serialize. And with a complex hierarchy like adventure objects it can become a mess. So I tried to avoid this entirely.

I started this project with Objective C for the graphics and heavy lifting. Lua (a great embedded language)  is used to write the behaviour of my game and manages all the state present in the adventure.

objective-cfree-vector-lua_081531_lua

My first thought was storing each Lua call like versioning systems do. Every time something happens the Lua call will be stored and when the game needs reloading all Lua calls will be executed in the order they were executed before. The big problem with this is that the entire history of calls are getting longer and it can hurt performance in the long run.

The savegames in this scenario will mark several branching points.

This could be a viable solution but besides the pros there are a lot of cons

Pros:

  • Only one big Lua State to manage
  • Very accurate tracking of every possible state in the game
  • Not much coding to do except loading and replaying

Cons:

  • Increasing loading and execution time before starting room
  • Need to store the lua call immediately in memory or database
  • Stores stuff that might not be necessary to be stored.

Most of the solutions I encountered were storing the state of a subset of the Lua objects at specific intervals. This seemed a better approach to me as I had already chosen to make one Lua script per room. Lua fetches all object states when the room is entered and if it’s not present a template will be set.

Right now I can differentiate between 4 kinds of state objects:

  1. RoomState : Stores all the stuff that happens in the room the player is in.
  2. PlayerState : The player (Playable Character) moves between rooms and will be loaded beforehand (to see which room he is and will be his starting point).
  3. NpcState : Some Npc’s (Non Playable Characters) will and can move across different rooms, and they will be added and loaded according their currentroom property.
  4. GlobalState : All event data that needs to be accessible at any time. This will for example be events setting a state variabele that are triggered while having a dialog with a npc and some other dialog depends on that state

The next part of the solution is in which format I can store the lua state. That decision was easy: Json is superefficient because the way lua tables are initialized is json without quotes. I found a very basic json implementation that worked without much fuss. Look at the difference between Lua table creation and it’s Json format :

local room = {
    name="museum",
    objectElevatorDoor={
        standingLocation="{20,2}",
        buttonlocation="{21,3}"
    }
}
{
   "name":"museum",
   "objectElevatorDoor":{
      "standingLocation":"{20,2}",
      "buttonlocation":"{21,3}"
   }
}

It’s basically replacing the equal sign for an semicolon sign and wrap the props in quotes and you have the Json format basically.

jsonlogo

I used this Basic Json parser that parses json to tables and tables to json. The only problem I had was that the parser tried to serialize the functions too.  This could lead to crashes because I could not load the function back from the database.

I wondered if I could seperate the data from the functions. And yes, this can be done really nicely with the use of Lua metatables. A metatable can be seen as an extension point when set on a table. A very good tutorial on how this works can be found here. The structure I came up looks like this:

function common.EntityFactory.createRoom(roomName)
    local room={};
    room = {
        name=roomName
    }
    return room;
end

function common.makePersistable(tableToSetMetatableOn)
    setmetatable(tableToSetMetatableOn,
        {
            __index = function(table, key)
                if key == "persist" then
                    return function()
                        jsonToPrint = json.encode(table);
                        print("LUA JSON FOR room : " .. jsonToPrint);
                        luaController.persist_room(table.name,jsonToPrint);
                    end
                end
            end
        }
    )
end

The showed function is the ability for the object to persist itself.  The luaController is a user data object that calls the Objective C method to persist the Json string.

This defined metatable with the persist function can be set on the player at any time. That way I could create some ObjectOriented approach to handle these kind of things.

common.makePersistable(currentRoom);

The last thing I needed to figure out was how to store this. I chose SSLite because this is a well supported choice on different platforms (android needs to be supported too). I made a nice wrapper for crud operations.

SQLite370.svg

When a save-game is created by the player the intermediate and temporary json records are copied to a different table. It will get an additional timestamp, title and a save image that consist of a freeze frame screenshot. Well this is the plan, that part is not implemented yet. But I have to start somewhere don’t I?

Archived: Uncategorised

Lua Scripting

I started off early with Lua scripting. This was mainly because the Ray Wenderlich RPG samples were using it and this gave me a head start and a direction. I think Lua is a beautiful scripting language, and it has real potential (see the Love2D framework).

It’s what I can teach my 9 year old son. So it’s pretty nice.

I am still in pre-production and I wanted to make coding the actor (NPC and player) actions as easy as possible. If you settle to early for something simple to progress quickly, it can be really cumbersome when you need to make a lot of changes to rooms and actors.

I made a pickup animation sequence completely in Objective C, but I knew this was wrong.
If I had to change or extends this I had to change about 40 lines of code and it wasn’t flexibal.
This was wrong because the behavior of actors is data but in the form of scripts. I have one script per room.
As you can see this is much nicer and flexible :

local seqOpen = cs.SequenceFactory.new("dave");
seqOpen.walkTo("{6,5}");
seqOpen.animationBackAndForth("pickupsideways");
seqOpen.addInventory("hammer");
seqOpen.wait("0.8");
seqOpen.script("passHammerToDave");
seqOpen.start();

This script will :

  • Walk the main character to the item.
  • He will kneel to pick it up and will rise again. This is a back and forth animation
  • Add the item to the inventory of the player
  • Wait for about a second and run a lua method called passHammerToDave that alters the state of the character. Dave will ‘own’ the item now.

Now it passes all these actions to the CCActionSequence that is supported by the Cocos2D framework. The seqOpen will be passed as an array of commands to the Objective C bridging code, and this will execute this in sequence as CCAction’s! Many actions in cocos2d are finite time actions, that means that walking to a certain tile with the help of an A* (Astar) algorithm does not fit easily into an action. So I splitted all separate CCAction sequences and let every sequence end with an action to fire an event to a sort of action manager class that starts the next sequence.

This looks like this :

    NSMutableArray *preppedActions = [NSMutableArray array];

    for (NSString * scriptingLine in luaStringTableArray) {
        if ([scriptingLine hasPrefix:@"walkto"]) {
            id blockToExecute = [CCActionCallBlock actionWithBlock:^{
                CCLOG(@"scripted walkto reported");

                NSString * coords = [LuaUtility firstArgFromScriptLine:scriptingLine];
                player.moving = YES;
                [player moveTowardsTileCoordWithAi:CGPointFromString(coords)];
            }];
            [preppedActions addObject:blockToExecute];
        }else if([scriptingLine hasPrefix:@"wait"]){
            NSString *delay = [LuaUtility firstArgFromScriptLine:scriptingLine];
            CCTime timedDelay = [delay floatValue];
            id actionDelay = [CCActionDelay actionWithDuration:timedDelay];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"waiting finished"];
            }];

            id sequenceToExecute = [CCActionSequence actionOne:actionDelay two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        }
        else if([scriptingLine hasPrefix:@"animate"]){
            NSString *animationName = [LuaUtility firstArgFromScriptLine:scriptingLine];

            id blockToStartAnimation;
            if([scriptingLine hasPrefix:@"animateonce"]){
                blockToStartAnimation = [CCActionCallBlock actionWithBlock:^{
                    [player startOneTimeAnimation:animationName];
                }];
            }else if ([scriptingLine hasPrefix:@"animatebackandforth"]){
                blockToStartAnimation = [CCActionCallBlock actionWithBlock:^{
                    [player startBackAndForthAnimation:animationName];
                }];
            }

            if(blockToStartAnimation){
                CGFloat animationDuration = [player animationDuration:animationName];
                id delayFromPickingUpAnimation = [CCActionDelay actionWithDuration:animationDuration];
                id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                    [player.characterAnimationManager eventReportedOn:player event:@"animation finished"];
                }];

                id sequenceToExecute = [CCActionSequence actions:blockToStartAnimation,delayFromPickingUpAnimation, blockToFireEvent,nil];
                [preppedActions addObject:sequenceToExecute];
            } else{
                CCLOG(@"WARN : syntax of the animate command was not correct, it needs to be animateonce or animatebackandforth it was %@",scriptingLine);
            }

        }else if([scriptingLine hasPrefix:@"script"]){
            id blockToExecute = [CCActionCallBlock actionWithBlock:^{
                [luaScriptProcessor runVoidScript:[LuaUtility firstArgFromScriptLine:scriptingLine]];
            }];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"script finished"];
            }];
            id sequenceToExecute = [CCActionSequence actionOne:blockToExecute two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        } else if([scriptingLine hasPrefix:@"move"]){
            id moveAnInch = [CCActionMoveBy actionWithDuration:0.2f position:CGPointMake(20,0)];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"script finished"];
            }];
            id sequenceToExecute = [CCActionSequence actionOne:moveAnInch two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        }  else if([scriptingLine hasPrefix:@"playsound"]){
            id blockToPlaySound = [CCActionCallBlock actionWithBlock:^{
                [[AudioManager sharedManager] playSoundEffect:[LuaUtility firstArgFromScriptLine:scriptingLine]];
            }];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"script finished"];
            }];

            id sequenceToExecute = [CCActionSequence actionOne:blockToPlaySound two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        }
        else if([scriptingLine hasPrefix:@"addinventory"]){
            id blockToAddInventory = [CCActionCallBlock actionWithBlock:^{
                NSString *sceneItemName = [LuaUtility firstArgFromScriptLine:scriptingLine];
                [[InventoryManager sharedManager] addInventoryItemByName:sceneItemName];
                [tilemapTool removeObjectFromMap:sceneItemName];
            }];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"script finished"];
            }];

            id sequenceToExecute = [CCActionSequence actionOne:blockToAddInventory two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        }


        else if([scriptingLine hasPrefix:@"gotoscene"]){
            id blockToGotoScene = [CCActionCallBlock actionWithBlock:^{
                //TODO Pass specific roomid in case of roomchange
                NSString *roomId = [LuaUtility firstArgFromScriptLine:scriptingLine];
                SwitchRoomScreen *scene = [[SwitchRoomScreen alloc] init];
                [[CCDirector sharedDirector] pushScene:scene];
            }];
            [preppedActions addObject:blockToGotoScene];
        } else if([scriptingLine hasPrefix:@"tileon"]){
            id blockToPutTileOn = [CCActionCallBlock actionWithBlock:^{
                NSString *tileCoords = [LuaUtility firstArgFromScriptLine:scriptingLine];
                CCTiledMapLayer *wallLayer = [tilemapTool.tileMap layerNamed:@"collisiontiles"];
                [wallLayer setTileGID:1 at:CGPointFromString(tileCoords)];
            }];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"script finished"];
            }];
            id sequenceToExecute = [CCActionSequence actionOne:blockToPutTileOn two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        } else if([scriptingLine hasPrefix:@"tileoff"]){
            id blockToPutTileOn = [CCActionCallBlock actionWithBlock:^{
                NSString *tileCoords = [LuaUtility firstArgFromScriptLine:scriptingLine];
                CCTiledMapLayer *wallLayer = [tilemapTool.tileMap layerNamed:@"collisiontiles"];
                [wallLayer setTileGID:0 at:CGPointFromString(tileCoords)];
            }];
            id blockToFireEvent = [CCActionCallBlock actionWithBlock:^{
                [player.characterAnimationManager eventReportedOn:player event:@"script finished"];
            }];
            id sequenceToExecute = [CCActionSequence actionOne:blockToPutTileOn two:blockToFireEvent];
            [preppedActions addObject:sequenceToExecute];
        }
    }

    [player.characterAnimationManager loadActionsFromArray:preppedActions];
    [player.characterAnimationManager startAnimations:player];
    player.characterAnimationManager.continuous = continuous;

A lot of code, for sure. But this is what I need to do once… Maybe the code needs some cleaning up, but for now it’s ok. It does the job well. Every action will be perfectly in sequence because each action will fire an event to the characterAnimationManager to signal that the next sequence should be executed.

The next scripts will show the scripting for opening the elevator door and going to another room :

local seqOpen = cs.SequenceFactory.new("dave");
sequence.walkTo(room.objectElevatorDoor.buttonlocation);
sequence.animationOnce("reachcentre");
sequence.playSound("button.caf");
sequence.wait("0.2");
sequence.playSound("slidedoors.caf");
sequence.switchCollision(room.objectElevatorDoor.standingLocation, "off");
sequence.script("openElevatorDoor");

The script does the following steps:

  • The player walks to the button location that is defined in the room he is in.
  • The player will reach for the button when it uses the verb “use” on the control panel
  • Button sound plays (this is alway an asynchronous event)
  • The sound for sliding the elevator is played
  • The elevator has some tile locations that needs to be blocked or unblocked when doors close or open up.
  • The sequence runs the open elevator door animations that is called via lua via function ‘openElevatorDoor’

Well lets see these both scripts in action! (trust me… it’s quite short) :

Scripting from franzzle on Vimeo.

Archived: Uncategorised

App Icon Evolution

Is it too early to look at an icon? I think you need to start early, trying different designs and get into grips with a certain look… It’s these kind of things that, if you wait too long for it to make and when you are trying to finish the game, you will not make a proper icon. Those final crunch days are gruesome because bugs need to be squashed, menu’s have to be made, a settings screen you forgot and maybe the gameplay still lacks some finesse? Eventually  you will not have the time to make it anyway!

One other thing is that you need to know how long your icon could last. Does it bore you? Does it grow on you? Does it stand out? I am on to my third icon now, and it could be the final one.

The icon below was a really early icon I created just to try to lay out the composition and to get off the default Spritebuilder icon, Dave was standing against the wall ready to be fusilladed by german WWII soldiers. I you think this looks familiar, it is! Because a part of the cartoon is actually stolen from the political cartoon for the Peking Olympics

iPad-old@2x

The idea was that Dave would transported back to the present day with a kind of transporter beam. I knew this was only a working icon and I would make a complete overhaul of it. But the transporter thingy, stuck with me though!


itunesIconCharacterWithTimemachine-ipad

A long period after that I thought that the Time Machine had a shape that could be fitted into an icon. So I made a Hires character and put that in the time machine. This was a first draft and the dave character was not recognizable on small icons. The colors were completely off and it did not have the pixelated look I was looking for.

iPad

So I came up with this icon. I still use it today. The character is the Dave character as he will walk around in the game. The colours are bright and playful. The transporter twinkling stars makes it as if Dave is actually being transported back in time! Maybe I should tweak the shadowing a bit?

Well, that’s it for now!

 

Archived: Uncategorised

Created a build number script to The Lost Adventures title screen

I was sick of guessing how recent the installed version of The Lost Adventures was on my iDevices. So I made an Xcode pre-build script that writes the Git commit number plus a date/time  to a simple txt file.

This is picked up and shown on the main title screen.

IMG_1512

I thought I did more commits last year… But maybe I didn’t commit at the start of the project…? That could be… Vacation….? Anyway, nice…!

 

Archived: Uncategorised

Screenshot Sunday : When you gotta go, you gotta go

One of the rooms in The Lost Adventures will be the mens toilets. If I tell What Dave needs to do here I would  spoil one of the puzzles of the game. No spoilers here !.

You can obviously try to “use” the toilet, but supporting this action would take me hours of animating those 9 frames to sit down and what to think about those frames for pulling the chord to flush?

But who knows? When I have some more common animations for Dave, maybe….

Oh and do you see that white crosshair? I was watching the GUI of the Fate of Atlantis and this was still missing in my adventure game. The default action will be the “Walk to” action (not a button on the screen, but still an action). When you hover over the items, the label of a POI (Point of Interest) will be shown.

This presented a problem on the iPad though… Your hand blocks the visibility of the label, so I need to place the label to the left or right. Or I will place the label-bar to the top especially for the iPad.

tolietSceenshot

Enough tasks left to improve though. I am still in the preproduction stage (and this is actually good!!). Polishing a game and making content  is much harder and more tedious! Luckily all rooms are in draft now, to support the entire story for Level 1.

When the work on the adventure engine is finished and I have made one playable level, I will be in production stage. One of the main task is passing the list of actions to the Lua scripting engine.

I have greatly improved the way the scripting works. The drawback of an earlier approach meant timing the various actions exactly before the next scripted action started. I needed to solve this because the time taken by walking through the room was not predictable. Now the character can walk to a certain tile, then proceed to a new action like picking up an item (this is calculated by number of frames * frame-delay). These walking and animation actions are handled completely in sequence. Playing a sound can be a simultaneous action. The next blog post will be entirely about this nifty system.

Archived: Uncategorised

Ambient Adventure Music

One of the problems as a hobby Developer is in-game-music. This is a tough nut to crack for any developer. A proper musician will cost you a lot of money.

Luckily there are some solutions to this problem. Generative music is one good example. Recently some good tools have been made available. One of them is Ujam. It’s amazing to see how quickly you can make a decent sounding beat or melody. It converts you voice into a melody and after that you can choose an arrangement based on music style. It’s made completely in flash, so won’t work on iOS devices.

I have also tried Noatikl2 and Mixtikl but they are too hard to use and have a steep learning curve, and I have some more things to do. For an adventure it has to sound decent enough.The most important thing is that it should not distract or annoy the player.

Another possibility making music is whistling the tune, converting it to midi and make it into a song in Garageband.

Here a list of commercial tools that can do such a thing :

Free tools

  • Whistlemagic (can’t provide a good link, windows only)

iOS tools (all Paid, but not)

One tools fits in both categories and it’s my favorite (for the moment).

screen640x640

Casio Chordana Composer is absolutely fabulous. It used a short melody (keyboard,whistle or voice) as seed and generates a song after you have chosen an arrangement and music style. The best thing is that it doesn’t sound like it’s generated at all!

The following music was generated with Chordana, played and recorded this midi file with Roland’s iOS Sound Canvas (it’s quite an expense app but worth it). Well enjoy the music…

Archived: Uncategorised

Animated assets from the very beginning

It is fun to see how I thought about asset creation before I started.  I made a lot of stuff with 3D Studio Max and Blender for earlier games. A lot of the assets for Blooneycounter were made with the help of Blender. So it was logical to make some of the stuff with those tools. I knew that animations were hard to do and I though I could make a pixelartsy look with the right shaders. I never made any animations so I didn’t know how to do that.

I made a character that had a good bone setup with the MakeHuman tool. This is completely free and you can tweak the model before exporting. I picked up some nice walking animations from Carnegie Mellon University site. And after some time you have a walking figure. Exporting the frames gave the following animated character:walkLeft

The good thing about modeling is that you can render it from any angle for free :

walkUpBut the thing is…. It looks crap… And even how I tried my best. It looks darkish, awkward and everybody knows it was a 3D model.

 

So I decided to ditch the Blender way of doing stuff, and decided to hand animate frame by frame. And although making frames this way is sometimes time-consuming, it looks bright, nice and pixelated. Above animations are rendered at 60FPS… way to much for pixel art. Usually any animation has about 9 frames. My characters are 70×150 and it’s very doable.

I bought character animation fundamentals to help me understand posing and acting characterscharacter

My animations are improving steadily and I love how it looks. I created a falling animation in less than 4 hours, and that’s okay. I plan to make about 20 animations for the first level. I already created about 12, so still 8 to go.

These are the ones left (for the first level):

  1. Putting up glasses
  2. Throwing a flashing grenade
  3. Dog animation
  4. Hand animations (no spoilers)
  5. Reach high animation
  6. Reach low animation
  7. Sit and eat animation
  8. Vaporize animation

 

 

Archived: Uncategorised

Picking up stuff… It’s a lot of work really

Any adventure game would be boring without any believable animation. This takes some time though, but with the help of some excellent tools it’s doable. I create my animation frames with Gimp (and a layers export plugin found here) and refine and play the animation with Asesprite. I add the frames to Texture packer and it’s ready to put it to use in the game.

Well let’s stop talking and show some video of picking up a hammer for example….!

Picking up animation from franzzle on Vimeo.

Off course this is only picking up from the floor.

Imagine the list :

  • Picking up as seen from behind on the floor
  • Picking up as seen from the front on the floor
  • Picking up as seen from behind from high places
  • Picking up as seen from behind from mid height places
  • etc…

Luckily… some of the mid height animations can also be put to use as push button animations.

Archived: Uncategorised

Create a nice little Christmas App

Every year we play a presents game with Christmas. The game goes like this:

  • Throw a dice.
  • The rolled dice number means a specific action should be made, like pickup a present, open present etc.
  • The second round will make the actions more diverse, like ‘trade the present with your neighbor’.

But as you will all have experienced one way or the other, the dices get lost. There is some cheating etc.. So the game I created is a “wheel of fortune” kinda game. All the actions are represented as slices of the wheel.. It’s better to show you a vid of the resulting game I guess.

Archived: Uncategorised

Thinking about a dialogsystem

Almost every adventure and every RPG has some kind of dialog system. The best known example of this is Indiana Jones and the Fate of Atlantis.

The dialog at the end where they are at the heart of Atlantis must have been a nightmare to make. There are so many paths indiana could follow through,with only one path leading to a survival. Thinking about how to make such a system, I thought i’d had a look what’s available on the web. Not much at first, so I almost thought about making my own crummy system. But eventually I found and chose something, although it’s a Windows application.

It’s always good to think about what’s available to you in the framework. Twine gives us json and every can be tied together with javascript.
I looked at Twine a free online creator of those dialog trees (http://twinery.org). It has Windows, OSX and Linux. So that’s very nice and it’s free.
Javascript support is there on ios, but the API is not nice because it assumes you are making iOS UI kind of stuff. I think this is a bummer.

On Ray Wenderlich I found some RPG samples that used Lua, that gave me some head start how to make such a dialog system. But because I am a one man coding army, I thought I needed a graphical way of creating those dialogs and testing those apartly from the game (testing takes about 60% of your alotted dev time!). Writing dialog is also a creative process and If you don’t have a tool to write the dialogs it will become cumbersome to do.

chatmapper

Eventually I found Chatmapper , a commercial dialog editor (http://www.chatmapper.com). I was surprised it used Lua for scripting. This all seemed to fit nicely with the samples I saw on Wenderlich. So I gave it a go. It has very good support for various format, json, xml etc.. What is nice is that it also imports a project from xml, so If any transformation needed to be done on anything on the project file, it could be imported and will work just fine. It is very stable and mature and oh it’s used on the most recent  Leasure Suit Larry game. So it will be capable of more than my needs.

Archived: Uncategorised