Creators of Caveman Craig, Teka Teki, and more.. 

(Late) September’s Etc


Christmas is quickly approaching, and Tim and I have a long long list of things to do before CC2 is ready.
For those who have pre-ordered, a big thank you for supporting us and giving us the extra push to get this out as soon as we can! We know you’re going to love the game.

Not much has happened from a content standpoint in CC2’s development since my last entry. For the past few weeks I have been working primarily on the save function (which now works completely minus any kinks I have yet to discover!) that I went over with some technical details in my previous entry, and changing the spawning / difficulty curve for dinosaur threats. In the first BETA some testers found that they would suddenly get wiped out by up to 40 velociraptors later on in the game, an unrealistic number given the size of their tribe. The randomness of the director made it difficult to control the difficulty of each level. I have since changed the algorithm so that there is a more specific and intelligent method of spawning dinosaurs and other threats. This also allowed me to easily govern the types and numbers of threats in each level, and the enemy tribe’s growth rate.

Testing each level has lead me to discover that each level isn’t just ‘harder’ – different factors require you to play the game in a different way which really adds to the replay value and progression of the game. For example, in the second level there are less velociraptors and more pterodactyls – pterodactyls don’t hurt much but they tire your cavemen out. The level is also a lot larger and so your gatherers must travel further to get meat. This will affect your choice of XP rewards to use, and your micro management of each cavemen – when they sleep, which tasks they prioritise, and so on.

At this point there are 4 standard conquest levels. You must play each one to unlock the next. Along the way you will also unlock new gametypes, XP rewards, while facing new threats and tribe leaders. Some XP rewards are unlocked as you progress through the game, others are unlocked by getting certain achievements or reaching certain highscores in the unlockable gametypes. In Classic / Survival mode you can play as any tribe leader that you have conquered.

Very soon I will be beginning work on the “Classic / Survival” mode. This is the “build your tribe as big as you can” gametype you all know and love from Caveman Craig 1. While this is the next biggest gametype after conquest, most of the coding is already done and it’s just a case of stripping down the code and changing the way dinosaurs and such spawn.

As for the other guys..
Ricky is working hard on the soundtrack and I would say we’re at least 50% there. His musical diversity is really showing here with each level having a very different orchestration to fit the terrain type. Grassy levels have a very chilled out, slide guitar, country feel to it. In the snow you’ll hear metallic, electronic sounds layered with caveman chants. The highlight is most definitely the main theme – it will empower you and prepare you for battle! Think Halo.

Tim’s biggest job now is to complete the animations for the enemy tribes and prepare the frontend/menu. Past that, there are some rewards left to create, and some gaps to fill.

Greg has mostly completed his work for the game, being the stunning backgrounds and scenery in each level, as well as some trivial reward images and such.

Once this is all done, the other game types should come together very quickly and we’ll be looking at a finished product!

-Rhys

The Horrors of Saving

Just before we released our private BETA almost 2 weeks ago, Tim requested that I prepare a ‘save’ option so that testers can save the game to play later, but also send the save files to me if there were glitches so that I can see what’s going on. It sounded like an essential feature for our first round of BETA releases.

Unfortunately, Game Maker’s in-built “game_save” function just wouldn’t do. While we used it for Caveman Craig and the Special Edition, there was a lot of additional coding that had to be done to re-instate some data that’s lost during the game save. Namely, data lists (ds_list functions) and instance ID’s.

In CC: Classic and CC: SE, I used a simple ‘switch’ that told the game that a game had just loaded, which tries to ‘guess’ the contents of DS lists, to avoid errors, etc. It was as simple as:

global.justLoaded=true;
game_save("myfile.sav");
global.justLoaded=false;

The variable is quickly switched to false after the game saves, so that no other object thinks the game has just loaded when in fact it had just saved. But when the game is loaded, the switch was missed, and so it gives all the objects a chance to ‘work their crap out’ to avoid errors. It was messy, but it worked.

Not so for Caveman Craig 2, which has twists and turns in the code everywhere you look that the game_save function just doesn’t account for. I released the BETA without a save script, and made a note of looking at this as soon as we got back to work.

There is a lot to do, but I think I’ve finalised my concept for a custom save script. The simple part is as follows:

When saving the game, I use this code:

with(all) event_user(15);

This tells every instance in the entire game to execute its 15th user event. If the object has nothing that it needs to ‘tell’ the save file (like the cursor object or something), I simply leave this event blank. Otherwise, the object writes code to the save file which involves creating a clone of itself, with all the variables set correctly.

The save file is then executed as a script when loading, which creates all the instances and sets their variables to as they were when the game was saved.

Seems pretty simple and solid, right? WELL. The tricky part is in the fact that instance ID’s change between games (from what I could tell, game maker’s “game_save” function does not preserve instance IDs). Caveman & dinosaurs interact a lot, and there are a lot of variables which contain IDs of instances with some significance to the object. Example, if a raptor is eating Craig, Craig has “raptorID” set to the Id of the raptor eating him. The raptor also has “targetID” set to Craig’s ID. In using game_save and game_load, this gets lost and suddenly Craig has no idea who’s eating him, and the raptor has no idea who he’s eating, resulting in way too many errors to try and work around.

So I came up with the idea for an “ID Translation List”. With this concept, there are two DS lists. An A list and a B list. The A list contains every ID of every instance in the game as it was when the game was saved. The B list contains the new ID of each instance when the game is loaded. Because the file is compiled as a script, and executed as a script, it can work this out in 2 parts.

Firstly, in the game save script I created, it creates some of its own lines of code in the save file before getting every instance to add theirs:

file_text_write_string(global.saveFile,"global.idTranslationA = ds_list_create();
global.idTranslationB = ds_list_create();

ds_list_add(global.idTranslationA,-4);
ds_list_add(global.idTranslationB,-4);
");

This creates the 2 lists, but also adds “-4″ (the special term ‘noone’ which does not change) to avoid errors when, for example, Craig is not being eaten by any raptor at all.

Additionally, the script now calls the user events from all instances twice. Once with the variable “idTranslate” set to false, and again with it set to true. This is to place the code into the file in the right order, as follows:

-> create each instance with basic variables
-> add each instance’s old and new ID into the translation list
then
-> set each instance’s ID variables such as ‘targetID’ or ‘raptorID’ correctly by using the translation list

It looks like this:if global.idTranslate=false
{
file_text_write_string(global.saveFile,"
_"+string(id)+" = instance_create("+string(x)+","+string(y)+","+string(object_index)+")

ds_list_add(global.idTranslationA,"+string(id)+");
ds_list_add(global.idTranslationB,_"+string(id)+".id);

_"+string(id)+".myHealth="+string(myHealth)+"
_"+string(id)+".myFood="+string(myFood)+"
_"+string(id)+".myStatus="+string(myStatus)+"
_"+string(id)+".hasspear="+string(hasspear)+"
_"+string(id)+".superclub="+string(superclub)+"

_"+string(id)+".sprite_index="+string(sprite_index)+"
_"+string(id)+".image_index="+string(image_index)+"
_"+string(id)+".image_speed="+string(image_index)+"

");
}
else
{
//Uses the translation list to set ID variables like targetID
file_text_write_string(global.saveFile,"
_"+string(id)+".targetID=ds_list_find_value(global.idTranslationB,ds_list_find_index(global.idTranslationA,"+string(targetID)+"));
_"+string(id)+".harvestID=ds_list_find_value(global.idTranslationB,ds_list_find_index(global.idTranslationA,"+string(harvestID)+"));
_"+string(id)+".raptorID=ds_list_find_value(global.idTranslationB,ds_list_find_index(global.idTranslationA,"+string(raptorID)+"));
_"+string(id)+".prevrockID=ds_list_find_value(global.idTranslationB,ds_list_find_index(global.idTranslationA,"+string(prevrockID)+"));
_"+string(id)+".tokenID=ds_list_find_value(global.idTranslationB,ds_list_find_index(global.idTranslationA,"+string(tokenID)+"));
");

}

This script is for Craig, by the way.
So far I have only tested interaction with Craig and an Othneilia + his carcass, and it seems to work correctly. There is a LOT of work and testing to be done, but I’m confident this is going to be the most solid way of saving and loading in Caveman Craig 2.

-Rhys

My week off.

Hi all!
As you all know, a week ago we announced the CC2 pre-order deal and launched our new flashy Caveman Craig website. Simulteanously, we released our first BETA version to some private testers.

Tim and I had worked during every pocket of time we got to get these two milestones ready as soon as possibly possible. It was with great excitement that we found ourselves at the top of the final stretch as of last Saturday evening.

Having worked on the game at every chance I got during the past month or two, I decided to have a week “off”. It came to my attention that I had not played enough games recently, so I made that a priority.
Limbo - the non-hawaiin type
After being blown away by the demo, I bought Playdead’s “Limbo” and played through within hours. The animation and graphics are stunning, sure, but the music and sound’s contribution to the atmosphere got me the most. The puzzles were challenging but not frustrating – for some I was so sure I was missing an element to the puzzle that would make it a little more possible, but eventually something always clicked in my lateral thinking mind.

Mostly, Limbo just got me thinking more about game design, and also some of the old games my brothers & I used to play. “Another World”, on Mega Drive/Genesis, was a christmas present when I was a very young child. I was terrible at it, and I think most of us thought it was a pretty B grade game as none of us had heard of it, and, what the hell man, no dialog or colourful sprites or bloopy sound effects. Retrospectively I think it’s one of the more respected games that I grew up with. Also, I never finished it.
The frankly adorable first boss
Next up was “Sixty Five Million and One B.C”, a really good plot-driven platformer, created in Game Maker by snailfox. The game did originally have a price tag but is now free – a very generous move by snailfox, although it left me feeling sorry that I never bought the game to support him originally.

65m&1bc is actually really funny. There’s great dialogue that makes fun of the game and doesn’t take itself too seriously. The feel of the prehistoric forests and mountain ranges are just really friendly and light. The puzzles are challenging and clever, although sometimes it feels unpolished and I did come across some annoying glitches. Some of the music, art, and feel of the game really inspired me when working on Caveman Craig and I’ll always hold this game in high regard.

The last two games I played this week were America’s Army 2 and Call of Duty: United Offensive. That’s right, the very first Call of Duty (with an expansion pack that we don’t utilise). Tim and I spent many hours playing 1 on 1 over the LAN with our sniper rifles or MP40’s. Just recently we had an opportunity to relive those times all over again with some friends, and it was all rather exciting and with a welcomed slower pace from the later games in the COD series. It’s also funny seeing some of the sprites and ideas that are still unchanged in CoD: Black Ops.

I went through high school playing America’s Army at every chance I got. I was obsessed with this game – clan wars and all. Returning to this game after years of dulling my brain with newer renditions of Call of Duty and Grand Theft Auto meant it took a few days to get used to the slow, tactical pace of this game. In COD, jumping like a maniac is your key to survival. In America’s Army (and real life..), jumping is the worst thing you can do in a firefight. You lose your aim and you become useless for about 2 seconds while you get your gear back in place – 2 seconds, while your firefight lasts about 1.
AA's maps are tactical and well thought out
AA is free, and brilliant. I’m not so sure about the current AA3 version, as I’ve heard it’s still very glitchy. I’ve been playing AA2, which is now dereliect with only a few servers. But it’s worth it!

And that, friends, has been my past week.
And now, back to CC2 =)

Regards,
Rhys

Home 2011 September