Treasure Tomb Development Diary

I have decided to keep a diary of the Treasure Tomb development for posterity, like the Alien Flux one before it somewhere on the java-gaming.org forums. It might be an amusing read for you, or enlightening. Mostly though, it’s my public trail of shame. Can’t quit on this game if you have to see a daily progress, eh?

28th June 2007

So: where are we with development for starters?

With the guts of Monster Mash ripped out and a quick package name refactor, I’ve got a basic game framework set up in Eclipse that launches and has a title screen, register screen, nag screen, hiscores screen, options screen, help screen, and credits screen. Of course all of the graphics and layouts are from Monster Mash (I just scribble over the top of the title with “TREASURE TOMB” using the Gimp) and it’s for Chaz to sort out later. But there we have it - the cradle in which a game sits.

Currently tapping M on the title screen brings us to the Map Editor. I’ve decided to do the editor completely before I do any game development, as it’s by far and away the most work involved in this project.

The map in this game is rather big. 1024x1024 tiles, to be precise, which is a lot to fit in memory at any one time when you also consider that each tile may also have an item on it (like a munchable dot, or a jewel, or monster spawner). Not only that but some of the map squares have special actions associated with them: teleports have a destination; script tiles fire off a “script”; and switches fire off a sequence of changes to the map. Furthermore, in the editor, we want to be able to turn switches on and off and see which tiles have been affected on the screen with some sort of indicator.

Were I to implement that naively and have each coordinate on the map represented by, say, some TileInfo class which contained the floor tile, item tile, any special action, and a flag, I’d need to create an array of 1,048,576 of them, and each one would take up 8 bytes overhead and 16 bytes of object data. That’s 24 megs! Not to mention the 4mb just for the array pointing at them. I don’t really fancy using half of my entire heap just to store the ingame map - not to mention the fact it’d make serialization slow and probably very bulky - so I’ve already decided to optimise this data structure.

The map now consists of two short[] arrays which point at indexed Tile instances; that’s the floor and item layers. Now it only takes 4 megs for the entire tile storage. There’s another 4 megs that points at optional ExtendedInfo instances - so mostly null. An ExtendedInfo, when present, is where I can bung everything else when necessary, like tile actions, flags, etc. So that’s more or less got map storage down to just over 8 megs, much better. And serialization will be lightning fast.

The editor is proving extremely difficult to write because I’m doing it properly - one of the most important things I’ve implemented is a multiple undo feature. This is quite tricky to implement especially when drawing one tile can affect its four neighbours (the wall tiles automatically adjust to get the edges right). But it works! Hurrah.

Also implemented is setting Teleports and destinations - just to test that part was working ok.

Tomorrow comes the much more extremely difficult design and implementation of the switch editor. Why so difficult, you ask? Well, firstly, because I want to be able to undo switch edits. And secondly because I want to be able to flip switches in the editor - both on and off. In the game, they cannot be flipped off. However, they can be flipped in any order, and the bit which recalculates walls has to be able to cope. And Undo. Gah. It’s making my brain hurt just thinking about it.

Cas :slight_smile:

http://matzon.dk/brian/Random%20junk/pixorstfu.gif
:-*

Cas, speaking of game editor dev, have you considered using JavaFX for it? Compared to Swing dev, JavaFX seems to bring a lot productivity. The issues I suspect for now about it are:

  • It’s still in alpha/beta stage, so how to you manage risk associated to language/API changes?
  • JavaFX is not purely OO since it allows you to write procedural code and you can, if you want, write a lot of classes in the same file. So for dev design it might become an issue when you develop large programs and developers are not well disciplined.

Patience! No screenies worth seeing yet coz Chaz is working on the new website and I’m just working on the editor. Give it a week or two.

@TheAnalogKid - can’t use JavaFX, because I’m still not even using Swing or AWT. Maybe when we stop doing the mini retro games series and I start embedding entire VMs with my games I’ll be able to play with that stuff.

28 June 2007

All right, I wussed out on doing the horribly difficult switch editor coding and instead implemented cut, copy, and paste functions with some delightfully poorly drawn icons. And it all works properly with Undo as well which is nice. Nice use of glLineStipple here to draw the animated selection rectangle.

Also in is scrolling if the mouse is attempted to move beyond the edges of the screen. I think the last two things I’ll bother putting in today are wiring up Ctrl-X/C/V for the cut, copy and paste functions, and scrolling the minimap. The game map is so big it won’t even fit on the screen when in minimap mode! In fact the minimap is still 7x7 big - blimey. Hopefully should be able to fit in a lot of adventurin’ in there :slight_smile:

Chaz is working on the new website at the mo so he hasn’t done any new graphics yet for the game.

Also in is scrolling if the mouse is attempted to move beyond the edges of the screen.

I like dragging the canvas with RMB (and eventually ctrl as x10 multiplier).

Dev diary - great idea :slight_smile: It’d be nice to hear from the other developments going on too.

Kev

I’ll consider writing a dev diary when the calm will come back after my house move. The thing a want to say for now is that I’m developing/prototyping a game based on Tetris. The game offers more various gameplay concepts than Tetris does. And, its based on Slick! :slight_smile: Stay tuned…

29 June 2007

So all the Ctrl-X/C/V stuff is wired in now (and Ctrl-Z for undo). I don’t know why I didn’t put it in before, but it’s now in my base class library, and I can now wire up any key combination to any GUI element, like in a more traditional sort of GUI framework.

Did some more tweakage in the editor.

30 June 2007

Nursing a bastard between the eyes today from a colossal lager binge last night out in Durham with my pseudocousin Amy, I decided to avoid doing anything especially difficult and instead work on the “adventure scripting” part of the game.

Every now and again you will have to solve some sort of adventure style puzzle in the game - this will usually involve doing some sort of little mini-quest to find some item and take it somewhere, or perhaps discover the letters to a secret code to unlock something, or whatever. To this end, I’ve got a Script class which contains a number of States. Each State has a block of text which I’ll display on the screen and a number of Choices, and each Choice will do one thing such as set some state variable, give or take an item from the player’s inventory, or allow the player to input some text.

When a Script gets “executed”, I’ll scan through the States to find the first one that matches the player’s inventory and start there. Then every time they make a choice I’ll do the same thing again against their inventory and any internal state set (just a Map of key-value string pairs basically). I think that’ll be complicated enough for my needs.

In more classical hard-work-avoidance I knocked up a screen to let me type in a script ID when a script tile is placed. Tweaked my screen handling system so that I can now designate a screen as a “dialog”, which just draws it on top of any existing screen but disables all its buttons etc. Don’t know why I didn’t do that a long time ago.

Glad to see this diary going. I always enjoyed the Alien Flux one and I still anticipate learning alot from you! :slight_smile:

Bill

Meh, there’s not much to learn… mostly it’s just hard bloody slog and tedium :confused:

2 July 2007

Continuing along with the theme of avoiding hard things to do, I put minimap scrolling in this morning. You can drag the minimap around with the right mouse button, and also you can scroll the aperture around with the cursor keys and if you try to go off the edge of the screen it scrolls the minimap instead. Nice and easy, but still took me an hour to do for some reason. I think I am just horribly slow.

Chaz has just finished updating the website with a new super-retro look as we further consolidate our image and brand of pixelly goodness. Gone is the Puppyinvaders applet, which we suspect caused a lot more trouble for people than it was worth (slow page loading, crashes, etc). This means he’s free to start doing game graphics, so he’s started on doing the little icons for the toolbar in the editor.

Oh by the way, Tomas Andrle of Catnap Games has just released an updated version of Devastro, a LWJGL+Java game reminiscent of Cannon Fodder. We’ll be putting a front page link to Devastro on our front page shortly, because we like it! In fact I think it might be the third only studio to have released a LWJGL game other than Puppygames and Oddlabs.

Added information into extended tile info to show that a tile is a teleport destination. I store a List of Points which are the locations of the teleport tiles that can take you to a particular tile. Now the editor draws red lines between teleports and their destinations.

Started on the switch editing part of the map editor now finally, the Really Hard Bit. First stop is to make tiles that are currently “transient” - ie. changes made by switches being toggled on - visible with a glowing border around them so you can see they’re not actually part of the base map.

Music today: Beck - Loser, Led Zepellin I, II and III and Houses of the Holy.

[quote=“princec,post:1,topic:30245”]
Very true, that’s why I keep my zipper zipped!

I like the new website. Wouldn’t call it overly retro tho. It’s quite bold and vector flavored with a touch of destructivism. So, it’s sorta modern actually.

3 July 2007

Found this morning that Chaz has completely done all the GUI widgets for the editor, and it looks really slick and nice now. Hey, I might even show you a screenshot!

Put in compression to the MapStorage class when it’s serialized. A saved map on disk was 5MB; now it’s 5KB. Of course that’ll grow somewhat as we actually design some real maps. In case you want to know how that’s done:


/**
 * Override standard object writing so we can gzip the stream for MapStorage
 * @param stream
 * @throws IOException
 */
private void writeObject(ObjectOutputStream stream) throws IOException {
	stream.defaultWriteObject();
	GZIPOutputStream gzos = new GZIPOutputStream(stream);
	ObjectOutputStream oos = new ObjectOutputStream(gzos);
	oos.writeObject(map);
	oos.flush();
	gzos.finish();
}

/**
 * Override standard objecr reading to read the zipped MapStorage
 * @param stream
 * @throws IOException
 * @throws ClassNotFoundException
 */
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
	stream.defaultReadObject();
	GZIPInputStream gzis = new GZIPInputStream(stream);
	ObjectInputStream ois = new ObjectInputStream(gzis);
	map = (MapStorage) ois.readObject();
}

Those two methods are in the GameMap class, which implements all the required functionality to edit the map and play the game. The actual map data is held in a class called MapStorage in a transient member variable called map. You have to make it transient otherwise stream.defaultWriteObject() will write it as normal. MapStorage extends another class called MapClip which only contains the tile layers - MapStorage contains all the aforementioned ExtendedInfo stuff.

Massive refactoring operation today. All the code was piled in ever more fiddly nested inner classes inside the editor screen. Now I’ve broken it all out. It’s a little tider and easier to navigate. Technically totally unnecessary, but I just felt like doing it. I’m not entirely happy with the code design even now but this is an operation in making money rather than making elegant code. The only reason I refactored it in the first place is because we know we’re going to be using this map editing tool again and I want it to be easy to rip out and fiddle with.

Did a few other tweaks at Chaz’s behest. All in all quite a good day.

Music today: Led Zeppelin IV, Mr Bungle, Boards of Canada

4 July 2007

Finally took the bull by the horns tackled switch editing. Why does everyone else find this stuff so easy? Not much to report, except it works! I am so l33t etc etc. The switch changes are highlighted by glowing red boxes round the affected tiles. You can toggle switches on and off in normal draw mode at any time and in any order. This will make it easy for me to create some fiendish tile logic puzzles.

I’ll spend the rest of the day tidying things up and then make meself dinner. In particular a few things need attending to such as:

[] Set the map start point, where the player beams in at the start of a brand new game
[
] Yes/No/Cancel “Would you like to save changes?” dialog when quitting the editor if dirtied or attempting to load a map
[*] I think I need to have the ability to create “permanent entities” on the map - ie. a gidrah that lies dormant until made visible, then which doesn’t go away until destroyed. I can’t be bothered to do it yet, because Chaz hasn’t drawn me any gidrah sprites so far, but it won’t be hard to put in.

The new Eclipse 3.3 I’m using misbehaved twice today, crashing after a couple of 100% CPU stints and exiting without warning. Grr.

Music: Mr. Nogatco - Nogatco Road, The Herbaliser - Blow Your Headphones, Weezer - Blue Album, Rush - A Farewell to Kings, Willy Mason - Where The Humans Eat

5 July 2007

Done:

[] Confirmation dialog on attempting to quit dirty editor. Created a new DialogScreen general screen sort of class with variably visible OK, CANCEL, YES and NO buttons on it and a title and message box. Might well come in handy elsewhere.
[
] Fixed a pair of crash bugs in the editor when trying to edit switches
[] Start point now set when you place the Start tile. Previous Start tile is automatically removed. I did this by adding an onDraw(map, x, y) method to the Tile class, called whenever a Tile is drawn on the map. The only Tile to override this method is the Start tile. I can’t tell really whether it would be better design to “hack” it or whether this nice neat object-orientated method is nicer.
[
] You can no longer draw on a two-tile border around the entire map, which prevents a small glitch with wall calculation from occurring.

We can now start doing the exciting stuff and actually writing the game! Chaz has sent me a little test gidrah that can animate movement in four directions, and I’ll just use that to test the player with, along with a bullet from Ultratron.

So: the player spawns, flashes for a couple of seconds invulnerability, and… jerks around the screen like it’s got electrodes stuck to its feet. But only… sometimes. How curious. I move the little guy around and sometimes it does it, sometimes it doesn’t. Eventually I notice it only seems to do it for a little bit just after he spawns. Then I notice that it comes back again after a while. Most perplexing.

A few System.out.printlns() reveal this bit of code in the MapRenderer (which draws the tiles) to be the culprit:


// Determine the offset in pixels
int ox = x & 31;
int oy = y & 31;

This works fine in the editor, and indeed, for all positive values of x and y, but in the very bottom left corner of the map, where I’m spawning the player right now, the bottom left corner of what’s being rendered falls into negative coordinates and the & operator doesn’t quite work as expected! Easily fixed:


// Determine the offset in pixels
int ox = x % 32;
int oy = y % 32;

Yay! A game is born! I put player bullets in too, so you can run around shooting. I tried to add a particle trail to the bullets - just for the hell of it, it looks awful because I’ve got no particle sprites and Chaz is the particle monkey - but discovered a horrible problem. When the map scrolls, the particles stay where they are on the screen! Curses!

The thing is, the map doesn’t actually scroll as such, it’s just told to render from a different origin. All the entities on the map just position their sprites relative to that origin like this:


screenX = mapX - TreasureTomb.getGameState().getPlayer().getMapX() + SCREEN_OFFSET + offsetX;
screenY = mapY - TreasureTomb.getGameState().getPlayer().getMapY() + SCREEN_OFFSET + offsetY;

where SCREEN_OFFSET accounts for the fact that there’s 10 tiles fits on a screen so I offset everything by 16 pixels so there’s an actual middle tile where the player is. The player is always the first entity to get ticked, so all the other entities choose screen locations relative to the player.

Except of course, the particles don’t, because they’re generic particles from my other games. Bugger. I’ll have to sleep on the problem. It can’t be hard to fix, but I don’t want to hack it if I can help it.

Music: Led Zeppelin, Boards of Canada, Dan The Automator - Wanna buy a monkey?, 2 Many DJs - As Heard on Radio Soulwax pt 2

6 July 2006

All the player movement is in now, and absolutely perfect it is too. I’ve also nipped out and finally bought a gamepad and wired that in - much better! Must get round to putting it into Titan Attacks and Ultratron too.

I’ve put in a little shower of sparks when the player’s bullets strikes a wall, and ripped a couple of sound effects out of Ultratron for now (might even keep them - I like 'em). I’ve also fixed the particle problem (and all of the special effects) by adding a setOffset() method to the Effect base class. This takes a ReadablePoint which every frame I update with the offset required to get things to display on the screen in the right place. One last niggle remains, that everything lags behind the scrolling by one frame.

Chaz has discovered that old problem with premultiplied alpha in PNGs coming to haunt us again - around the edges of some of his more subtly glowing sprites there’s a nasty fringe. We’re trying to figure out how to get rid of it as I type. He’s done a few more proper tiles too. Nearly ready for a screenshot! Maybe tomorrow.

Oh, and another thing: Chaz was complaining that all his sprites looked crap in the game. He showed me a screenshot and sure enough they did indeed look crap. Fortunately I recognised the symptoms - texture compression! I don’t use texture compression in my games because it generally looks a bit wrong for most of our smoothly drawn 2D stuff, but Chaz had accidentally overridden the settings in his control panel to use “Maximum Performance”. So: beware! If you think our graphics look a bit naff, maybe you’ve set this too.

Also done:

[] Eating dots!
[
] Eating jewels! Except there’s no gidrahs to pause yet (when you eat a jewel, the gidrahs stop moving for a few seconds)
[] Picking up keys and using them in locks
[
] Teleporting
[] Flicking switches
[
] Arrows - stand on these and you get whisked off in the direction they’re pointing

Music: Led Zeppelin (again!), Faith No More - Introduce Yourself, 2 Many DJs, David Bowie - Various old stuff

7 July 2006

Chaz has produced a player sprite which is pretty cute, but a little dark. Might have to brighten it up a bit.

At last, the gidrahs live! The spawner tiles now churn out a regular stream of particulary stupid and cute little robots for the player to blast. It feels like a complete game now. Right now they have absolutely no brains whatsoever but I have been researching Pac-Man ghost AI and there are four brains to choose from. My “research”* led me here. Seeing as I’m on a bit of a roll tonight I might code them in the wee hours and surprise Chaz when he wakes up tomorrow.

As the game progresses, I want it to get a bit more frantic and challenging. To this end, there’s the notion of the game’s current “level”. The game itself is played on one enormous map so there aren’t actually any levels like in Ultratron or Titan for me to get this value from. Instead, I’m going to tune it to being the number of treasures that the player has collected, and one or two other variables.

Little things done:

[] Wired in a bunch of sound effects for little events like eating dots, etc. Game feels more “complete” with sound.
[
] Put little bonus labels in when you score points
[] Put the “bravery” meter in. When you move, you get more bravery points, which in turn leads to more points when you shoot a gidrah - up to 50 points each kill. If you sit still, your bravery drops to zero, at which point you earn nothing for shooting the gidrahs.
[
] Started attempting to fix the particle lag by giving all the tickable things a tick() method and then calling another method, update(), to update their sprite locations separately

Music: Cujo - Adventures in Foam, Kruder and Dorfmeister

[size=0]* Everyone knows that “research” these days means Googling

8 July 2007

Played a bit of Time Bandit again today on STeeM, the Atari ST emulator. I noticed that the player is not always fixed in the centre of the screen as it is in my game. You move up to two spaces in the direction you’re heading. Unfortunately this means you can see even less of what’s coming up! I think I’m going to try some experiments with the view position so that the player can see more of what’s coming up rather than less.

I tuned joypad axis control as well so that it’s a little less sensitive to diagonals. Here’s the code:


float yAxis = controller.getAxisValue(1);
float xAxis = controller.getAxisValue(0);
upDown |= yAxis <= -0.5f;
downDown |= yAxis >= 0.5f;
rightDown |= xAxis >= 0.5f;
leftDown |= xAxis <= -0.5f;

// Tune diagonals
if ((upDown || downDown) && (leftDown || rightDown)) {
	float dist = xAxis * xAxis + yAxis * yAxis;
	if (dist < 1.0f) {
		// Don't allow diagonal.
		if (Math.abs(xAxis) > Math.abs(yAxis)) {
			upDown = false;
			downDown = false;
		} else {
			leftDown = false;
			rightDown = false;
		}
	}
}

It can be tuned by tweaking that 1.0f value in there. Seems to have made it slightly better to control. However, the controls still feel rather sensitive. I think I shall implement a small delay in starting moving from a standstill - really small, like 2 frames, and see how that feels.

Screenshots are imminent. Just got to get Chaz to do the HUD.

Charlotte tried to add me as a “friend” on Facebook. LOL. As if.

[] Fixed a bug in the map renderer which caused strange tiles to appear out of nowhere.
[
] Added teleport beam out and beam in sounds. Also give the player 2 seconds of immunity when teleporting.

Music: Jurassic 5 - Quality Control

Don’t forget to factor the pov (joypad) stuff in. This way people won’t have to press the digital/analog button, which doesn’t work reliable with Saitek pads.