Found interesting articles written by
Steve Longhurst, nothing less than the developer of
Snake EX2 (the game I was playing on the 6600) and
Sky Dive.
Games I’ve Coded – Sky Diver
I enjoyed writing about Triple Pop so much, I’m going to continue straight on with the next game I coded at iomo, Sky Diver. Sky Diver was another white label game for Nokia, this time targeted initially at the 5100, but also later the 3510i. The 5100 is technically very similar to the 7210, it’s another Series 40 v1 device, but is aimed at the ‘outdoor sports’ type person. It has a rugged rubber jacket that’s splash proof and the promo material at the time showed people climbing mountains using it! A game about sky diving was ideally suited to the device.
This time, the game was entirely new, there wasn’t an existing mobile game to base things on. However, if you look closely, you’ll notice a vague similarity to Pilot Wings for the SNES!
At the time, we created designs for games in one or two pages, and it was Glenn Broadway, iomo founder and creative director who visualised the ideas. Indeed, they were mostly his initially, even if they were refinements of existing ideas or games.
Technically, creating a sky diving game for a mobile device actually turned out to be fairly straightforward. My collegue Nick Reed (an amazing programmer who later became technical director of iomo and my boss at Infospace) wrote a few lines of code that demonstrated scaling and rotation on a set of points. By rendering lines between the points it looked like flying down from a height onto an airfield. The MIDP 1.0 specification has basic line drawing methods, but Nokia added an additional API with functions beyond the standard. The early Series 40 devices didn’t have Mode 7 hardware sprite scaling and rotation, but they did have an API with 2D polygon drawing methods. My job was to take the simple idea and along with artist Cameron Kerr, more input from Glenn, and QA from Nokia, flesh it out into the game it became.
Polygon Clipping
You can probably stop reading now if you don’t care about technical details! I didn’t post any code from Triple Pop because basically there wasn’t anything generally useful. In Sky Diver however, there turned out to be an interesting problem that needed to be solved. When the points that described the ground polygons were scaled too much, as happened at low altitudes, the large values passed to the drawLine and drawPolygon methods caused them to become really slow. I imagine there wasn’t any internal clipping performed on the geometry, only pixel clipping to the current screen clip region when attempting to rasterise the line to pixels. This meant if you did drawLine (0,0,10000,10000), it look a long time!
To the rescue came the seminal
Computer Graphics, Principles and Practice by Foley, van Dam, Feiner and Hughes. It goes into great detail about line and polygon clipping, and gives algorithms in Pascal or C (depending upon the edition). I wrote these Java routines directly from the algorithms in the book:
Sutherland-Hodgman Polygon Clipping in Java
Liang-Barsky Polygon Clipping in Java
To use the routines, you call them with arrays of points, and arrays to put the clipped polygon points into.
if(land_type <= Land_Runway || land_type == Land_Ground) {
c = SutherlandHodgmanPolygonClip(num_points,
poly_x,poly_y, // input verts
clip_x,clip_y, // output verts
TOP
);
if(c > 0) {
c = SutherlandHodgmanPolygonClip(c,
clip_x,clip_y, // input verts
poly_x,poly_y, // output verts
LEFT
);
if(c > 0) {
c = SutherlandHodgmanPolygonClip(c,
poly_x,poly_y, // input verts
clip_x,clip_y, // output verts
BOTTOM
);
if(c > 0) {
c = SutherlandHodgmanPolygonClip(c,
clip_x,clip_y, // input verts
poly_x,poly_y, // output verts
RIGHT
);
}
}
}
if(c > 2) {
// Draw the polygon as a series of triangles.
// Here we assume that the polygon is convex, because the triangle
// decomposition for concave polys is much more complex and probably
// more time consuming than the poor performance of fillPolygon!
for(j = 1; j < c-1; j++) {
dg.fillTriangle(poly_x[0],poly_y[0],
poly_x[j],poly_y[j],
poly_x[j+1],poly_y[j+1],
colour);
}
}
} else {
c = LiangBarskyPolygonClip(num_points, // count
poly_x,poly_y, // input verts
clip_x,clip_y); // output verts
if(c > 2) {
dg.drawPolygon(clip_x,0,clip_y,0,c,colour);
}
}
The code above picks the clipping routine to use based on the land type of the current shape being drawn, the comments for the clipping routines explain the best ways to use them. The fillPolygon and fillTriangle methods come from the Nokia DirectGraphics interface, but you could replace them with drawLine calls for wireframe rendering. If you’re looking for some clipping routines and find these useful, let me know with a comment. I might even put together a standalone J2SE demo if anyone shows any interest
SOURCE
Games I’ve Coded – Triple Pop
Triple Pop was the first Java J2ME game I coded at iomo, back in about 2002. It was a white label game for Nokia Series 40 devices, initially the 7210, but it found it’s way onto dozens of similar devices. The 7210 was one of the first colour screen Nokia J2ME devices. Until then, they had the 3410 and 6310i with Java embedded, but these had 96×65 1 bpp screens (that’s 2 colours, black and white, or dark grey and light grey on the phone!). The 7210 had a 128×128 colour display, could run jar files that were up to 64k and had 210k of runtime heap. It’s CPU was actually pretty nippy too, maths and game logic almost never turned out to be bottlenecks, it was always the screen updating that took time. The LCD response time was pretty slow, any attempt at animation over about 10 frames per second blurred terribly.
Triple Pop was already available as a Symbian application for the Series 80 communicator range, and we got the contract to write a Java version. I had the C++ Symbian code available to refer to when writing the Java version, which helped a lot. I lifted the algorithms for the heap of bubbles collapsing and rotating directly from the Symbian code. I still had to write the Java code from scratch, but there was no need to invent everything myself.
I won’t write too much about the game play, a video is worth way more than some words to show you what it’s about.
To be honest, there’s nothing very interesting to say about the development cycle of the game. The concept was simple and an implementation already existed to set the standard, there wasn’t much need for innovation or fancy coding. Early on we didn’t have actual devices, but the emulator turned out to be a pretty accurate model for the real thing, something Nokia sadly didn’t continue in later years! The game didn’t tax the device to any great length, it ran in about 60k of memory, jar size was less than 32k in the end, and it loaded quickly. Looking back, the aspect of development that strikes me the most is the similarity with how I do things today.
My basic development tools in 2003 were SlickEdit (v4 I think then), CVS, Java v1.3, Apache Ant and an obfuscator, at the time I used JODE. Today I use SlickEdit 2009 (v14 in old numbers), Perforce, Java 6 (or 1.6 in relation to 1.3), Ant and Proguard as an obfuscator. Basically the same tools, but there’s one difference. Today I code on top of a middleware framework that is the culmination of 7 years of mobile phone development experience. When I wrote Triple Pop, it was meant for a single class of very similar devices. Today, the codebase of a J2ME title must support hundreds of devices from many manufacturers. The specifics of doing this are the subjects for another time though.
Anyone developing a commercial J2ME application or game today needs to have a framework in place that assists with device fragmentation and porting. This could be an in house system built up over time, or a middleware platform bought from a 3rd party. Triple Pop had no underlying technology of note, it was just over 5000 lines of Java code and some PNG images. Later on, we used a system of pre-processing the source code for different devices and SKUs, but this early approach only scaled so far. Further to that, as iomo was acquired by Infospace and game production really stepped up, we adopted a full featured in house framework developed by Elkware (another Infospace acquisition). Today, at FinBlade, we use Bedrock from Metismo, which allows us to target both J2ME and numerous other systems such as iPhone and Google Android, all from a single source code base.
Mobile development has moved on a lot since 2002. Soon, I hope to write about more games I’ve been involved with, if for no other reason than to have a record for myself. Going back and playing Triple Pop again to make the video above made me think ‘
that’s really quite fun, it’s worth remembering’, so I have
SOURCE
Games I’ve Coded – Snake EX2
My next game in the “Games I’ve Coded” series is Snake EX2, originally available with the Nokia 3300.
From what I remember, I’m going pretty much in chronological order of Nokia embedded ‘white label’ games at the moment. There’s one more game to go for Nokia and one more application that wasn’t a game but more of a handy utility. I wish I could find the time at the moment to write more, and I’d love to get a post in about my companies latest product as soon as it’s available and I can talk about it publicly. I’m probably going to jump around a bit then with games I’ve coded and cherry pick the good ones that will make for some interesting writing.
I’m really glad I can say I wrote a Snake game on mobile. Even today, when I tell almost anyone what I do for a living, they know what Snake is. It’s one of those milestone beacons in the mobile game industry that shines out into the wider media and public consciousness. Of course, I didn’t come up with the Snake idea, and even the code base for Snake EX2 was an iteration of the J2ME version of Snake 2, done by my then colleague Nick Slaven, but at least I can truthfully answer yes when anyone says “You do mobile phone games eh? Like Snake?”.
There nothing very technically interesting to say about the Snake code really. It consists of the usual small number of J2ME essentials, a MIDlet, Canvas, TimerTask, a game engine class and a couple of extras like a custom gauge canvas for picking the difficulty level and two classes for the sound code. The game was designed to use the (then new) Multimedia API for J2ME which was included with the 3300, but it also needed to work on phones without the MMAPI, so it had a fallback using old style Nokia ringtone audio. Total lines of code came to ~5000. As you can imagine, Snake isn’t very heavy on the resources either. 12 midi files for the audio effects and 8 differnet PNG images for the graphics, not including the title screen, were all that was needed.
One thing that I do remember is the way that the game only updated the screen where necessary each frame. These days, it’s pretty common to do a full screen refresh each frame on mobile games, but on the older devices, it was worth being careful about full screen updates. In Snake, only the head, tail and any food that popped in or out needed to be updated each frame. Doing this meant the frame rate would keep to a steady 15 fps no matter how long the snake got.
KEmulator has problems with this game: Game does not update the full screen each frame, so buffer is not cleaned properly. And items always appear in the same place, for some reason.
You might notice there isn’t a background ‘texture’ to the playing area, it’s a plain colour. We originally had a sand like background tile, but when we finally got a real device to test with, the screen quality was quite poor. It couldn’t cope with the background pattern and there was a noticeable pixel crawl that occurred, so we had to get rid of it before the game was finished.
If you search YouTube, you can find various videos of people getting massive scores on Snake games, including EX2. One even shows a nice bug where the food spawns over the snake when it’s really long and fills the screen. It doesn’t seem to crash the game or cause a problem, except for having to keep moving the snake until the food gets free before eating it! Nokia QA must have missed that one.
Games I’ve Coded – Thief Deadly Shadows
Moving forward with the ‘Games I’ve Coded’ articles, the next big game I got my teeth into was Thief: Deadly Shadows. I’d finished off several Nokia ‘white label’ games (Adventure Race being the last), and the next project to come along was commissioned by Eidos Mobile, and based on the Thief license. At iomo, we had a good relationship with Eidos who were very forward looking with the mobile market and were one of the big console/PC publishers to get into it early.
I had actually coded a Thief licensed game for WAP devices not long after I started at iomo. This was before mobiles even had programmable JVMs in them, and we were using a Java server platform from Nokia called the Mobile Entertainment Platform (MEP). Nokia wanted some games content for their MEP system so they could sell it to operators, and we created several original titles. In conjunction with Eidos, we also created a licensed title for them. The Thief brand was more suitable to the WAP click-wait-response style of gameplay, being based on stealth, rather than the more action oriented Tomb Raider. Thief: Constantine’s Sword was a based on puzzle solving and moving around a maze, avoiding guards and traps. It would be a fun bit of digital archeology to see if I can get the code running again one day. While doing a bit of searching on the net, I even came across an old forum thread with some discussion and old marketing promo we put together.
Anyway, back to Thief, sort of! At iomo, we had already created Tomb Raider: The Osiris Codex for Java mobiles, which was part one of a three part series of Tomb Raider games. My colleague Nick Reed had coded the Tomb Raider mobile games, and I think he may even have been on part two or three by the time I started Thief. It’s amazing that the
www.tombraidermobile.com web page is still active after all these years! It even says “Coming soon to your mobile. Episode 3: Tomb Raider: The Elixir of Life”. All three games were very successful in fact, and in later years at InfoSpace, we created a Tomb Raider themed puzzle game called Tomb Raider: Puzzle Paradox. Later still, just after we formed FinBlade, I coded Tomb Raider: Anniversary Mobile, taking the best bits from the first 3 games and re-skinning it with an Aztec theme. If you’re interested in details for the mobile TR games, including all of ours, the excellent Stella’s Tomb Raider Site has all you could need.
The design for Thief was a side on platform game, in the same vein as the Tomb Raider games. This was the first time I had attempted a platform game, so I spent some time looking at the Tomb Raider Mobile source. It featured a 2 plane tile engine, with maps created in a tool called Tile Studio, and a scripting system with text level description files. As part of the build process, the level files were processed into binary data for efficient interpreting at runtime.
Since the artists were familiar with Tile Studio, I also used it for the Thief level maps, but I added a third foreground tile layer that went in front of the character sprites, as you can see with the bush in the screenshot above. I also made the tiles smaller, so more detail could be shown on the levels. The Tomb Raider scripting system was only really designed to be used by a programmer. The levels were designed on paper by a designer, and the sequence of puzzles and traps described in plain English. Nick then wrote the scripts to drive the game engine.
Here’s an small bit of one of the Tomb Raider level scripts. To be fair they were quite verbose, and the syntax was simple, but they contained lots of raw numbers that only a programmer might remember, and the parser was bespoke and difficult to expand with new language features.
# initialise the level
CODE=START
# main level
addblocks=0 dim=25,19 posn=0.00,0.00
# raising block
addblocks=1 tiles=22 dim=1,1 posn=8.00,15.00 cliparea=8.00,14.00-9.00,15.00
ENDCODE
# triggers
CODE=TRIGGERS
if endtimer=0&(!flag0) RUNONCE CROUCH-SHOOT
if flag0 RUNONCE RAISEPLATFORM
ENDCODE
#scripts
SUBCODE=RAISEPLATFORM
moveblocks id=1 movedata=0-8.00,15.00-2.0-8.00,14.00 go=1
cutscene posn=8.50,14.50 time=2.0
ENDCODE
For Thief however, we had extra resources available in the shape of a lead designer, Nik Bowen, who had been hired not long before. I needed to create a scripting language suitable for a non-programmer, and a framework for testing the scripts and levels quickly, without programmer intervention.
Since my game code was in Java, it was only sensible to write the tools in Java, and I used the lexical analyser and parser generator tools JFlex and CUP to write my scripting language processor. If you went to University to study programming, you will almost certainly have taken a course on compiler design which included lexical analysis and parsing. If you’re as old as me, you might even have been taught using the UNIX tools, lex and yacc. You could also write a bespoke parser using the text file reading and string handling mechanisms of your chosen language, but there’s a reason that tools like lex and yacc exist. I think it’s universal law that anyone who blogs about programming mention the “Dragon Book” at some point, so here’s my mention. If you are going to write a parser for a language, you should read it. Although first published in 1986, it’s still relevant today, and is one of those books every self respecting career programmer should have on his bookshelf.
I learned a huge amount from actually writing a domain specific scripting language, rather than picking an existing language. It’s a difficult decision to make, write your own language, or adapt/extend a general purpose one. There was no way I was going to get a Perl, Python, Ruby or other scripting language interpreter in my game runtime. Maybe I could have used a language like Ruby as the basis for my scripting, but I still would have had to learn about how to convert the scripts into the runtime data structures that the game engine would ultimately use, since it wasn’t going to interpret them directly. Getting the chance to put into practice what I’d learned at university was an opportunity not to be missed, and I think it paid off for me.
The script processor for Thief comprised of a very simple lexer, about 100 lines of Flex input. The language definition was a bit bigger, about 700 lines of syntax notation written as the input to the CUP tool, along with 300 lines of Java code embedded in the various helper methods. The frontend of the script was about 2500 lines of Java code, with small 15 classes that defined the different language elements. It was all tied together with the actual runtime code too, with shared interfaces that defined constants and references to localisable strings shared between the scripts and the runtime. Here’s an example of some of the bits from a Thief level script.
# Level script file.
# Anything after a hash on a line is a comment.
# Case is not important.
# Positions are specified as fractional tile coordinates, relative to 0.0,0.0 being the
# very top left of the level. So, 1.5,1.5 specifies the middle of the tile at position 1,1.
# Initialise the level
code=start
# Respawn points for garrett (need to go before the level object, in order for it to reference the respawn id)
respawn id=respawn1 posn=6,7.95 anim=hide:3:right
respawn id=respawn2 posn=14,33.95 anim=hide:3:left
# Dimensions (in tiles) and tile size (in pixels)
level dim=30,43 tilesize=16 id=mission1 number=1
flags=!revealed, !complete, !failed, !shop, chapter_start
nametext=Text_mission1_name introtext=Text_mission1_prologue outrotext=Text_mission1_epilogue
chapternumber=1 chapternametext=Text_Chapter1_Name chaptertext=Text_Chapter1_Intro
respawn_id=respawn1
# Objectives for the mission
# Get Lord Juliens bag
objective id=objective1 descriptiontext=Text_mission1_objective1 flags=active, !complete, !failed
# Garret's start position
character type=garrett id=garrett posn=6,7.95 anim=idle:0:right
# Items
item type=silver_gem posn=1,7.95 flags=!infront,loot
# other characters
# innkeeper should patrol left and right and will need to be pick-pocketed to retrieve the key. A water arrow can also be used to extinguish the torch in this room
item type=jade_gem id=innkeeper_gem posn=0,0 flags=hidden,infront,loot
character type=civilian id=innkeeper
posn=24,16.95
anim=walk:0:left
pocket_id=innkeeper_gem
action=patrolling_left
end0=left:25,16 end1=right:19,16 look=6 stand=15
flags=afraid_of_garrett
# Doors for travelling between areas
# Note the 'room' property. This designates which room (on the map) this door goes *TO*. When this door is looked though,
# that room will be revealed on the in game map
door posn=26, 7:27,7 id=door_A1 to_id=door_A2 flags=locked pick=3:l,r,d room=2
code=triggers
# This displays the name of the mission at the very start
trigger action_id=mission_name when
(test_posn character id=garrett posn=6,7)
endtrigger
# Cutscene triggers
trigger action_id=hiding_info when
(test_posn character id=garrett posn=13,7)
and (test_flags level id=mission1 flags=tutorial)
endtrigger
# Actions that are run by triggers
code=actions
# Mission name
action id=mission_name
cutscene camera_id=garrett camera_move=pan texts=Text_mission1_name texttype=instruction
endaction
It may look complicated, but it essentially boils down to a number of integer arrays that the game engine processes at runtime. What’s important though is that all the elements in those arrays are defined outside the code. The data controls the objects that appear on the levels (all the torches Garrett can put out with his water arrows, guards, other characters, switches, locks, chests, loot, you name it), how they interact (you could unlock a chest to trigger a cutscene that moved the camera to a part of the level to show you where a door was unlocked, etc.), and all the meta elements of the game like the requirements for completing the level. With all this in place, all I had to provide to the level designer was an automated build process that took a level script file, the level tile map data created in Tile Studio, and packaged it into a bundle that could be run in the game simulator. I think at the time we were using one of the Nokia J2ME SDK Simulators, I think it looked like the 3600.
Nik did an awesome job in scripting the 16 levels of the final game. It was released in 2 Episodes, with 8 levels in each. There were all sorts of cunning elements, like having to put out a fire in a fireplace using a water arrow to reveal a hidden door to a section of a level. We put in a section between the levels where Garrett had to run over the rooftops to a fence to sell his loot, and buy more supplies to the next level. The game was also ported widely by the Infospace porting team with versions as small as 64k and in Chinese. It may not have been as flashy as some of the Gameloft platform games that were appearing at the time, I’m pretty proud of how it turned out.
Here’s a gameplay video of the first level, to the point of selling your loot at the Fence. Most of the art assets (sprites, tiles and graphics) were created by Jon Davies, now of Megadev, and Marvin Hill, art director at Infospace, so credit to them too.
SOURCE