Fost - Mr. Robot Art
Not much text this month (I'm sure everyone just wants pictures anyway :) ), as I'm working overdrive on effects. Normally these will appear in ghost hack mode (a section of the game which takes part inside a virtual computer world), but it's easier for me to set them up and test them in a dimmed room from the main game section, so all the screengrabs reflect this - you'll have to use your imagination and picture the effects occuring in a virtual reality world a bit like the matrix.
When coming from a reference point of making something similar to the real world, e.g: the smoke trail from a missile, you always have that refererence point to work to. With ghost hack, the only criteria is that it shouldn't look like the real world :) It's often hard to know when to stop tweaking an effect and several times I've made perfectly fine effects which then were transformed into something completely different after several iterations of tweaking! Moral: save often!
Things are progressing much faster than with effects creation on Starscape. Mark has made sure effects reloading works off several buttons, which speeds things up no end. I actually value that approach to programming games more than I would the solution of writing a dedicated particle systems editor. Text files aren't hard to edit, but if you don't have the ability to see your changes instantly, then it takes an age to create even the most basic of effects.
Poo Bear - Mr. Robot Programming
XML Storage Decisions
We already use XML for some file types in Mr. Robot, although it was more of an experiment in XML integration than something that was implemented in a sensible way. Whilst prototyping aspects of future games I've started to use it more and think about the best way to approach XML use in games.
I've not seen much discussion about what's considered best practice with regards to how xml is used to store data. There's 3 possibilities. E.g. storing data about a 3000 radius red sphere.
Multiple inline attributes in an empty element:
Multiple empty elements with a single inline attribute inside a containing block:
Whilst the use of multiple inline attributes in an empty element is the most tempting implementation, especially if you've come from using block files, it can get very messy if you have a lot and end up on multiple new lines. Once you start using a deditated XML editor rather than a text editor it starts to make a little more sense. Some commercial editors can even fold up container blocks making it easy to navigate and visually isolate data chunks (in fact, if you look at any xml file in the firefox web browser it will do this). So I've decided the last option fits most types of generic data. For single attribute empty elements I also try to stick to using the attribute name 'value' - it just makes things easier to remember. I'll still probably use several inline attributes for anything that won't break a line such as a particle system colour key like: .
Whether this is good practice is anybody's guess, it just seems to be the best compromise between compactness, readability, and parsability by dedicated XML editors, but then XML wasn't designed with games in mind...
XML Document Type Definitions (DTDs) for Games
Using xml files for just about every type of game development file is currently vogue amongst developers. The main reason it seems developers have chosen this method is because it's then easy to use a lightweight, off the shelf file IO system like tinyxml, so you don't have to write your own text file parsing system. Sometimes though, I get the impression that people use xml files just because it's trendy :). On the face of it, they are much more unweildy than something like a blockfile.
//This is a comment
There's a lot of duplicate text for closing tags, and the HTML style commenting system is a bit unweildy. However, as well as versatile off the shelf file IO code, there is one other major advantage to using xml files that I don't often hear game developers talking about - and that's free file validation by using document type definitions. Document type definitions (DTDs) define what elements and values are allowable in a specific xml file type. This means that you don't have to write your own validation code to check for errors; you can use an off the shelf xml file parser that supports DTD validation (whilst tinyxml doesn't support this so it can stay small in size, there are many other xml parsers that do, such as xerces xml. Better still - you just use the built in validation systems of a dedicated xml editor (like the excellent and freeware xmlpad) to validate the file as it is saved out. Virtually all xml editors will also do code completion using the DTD, so it's easy to remember what tokens go where because the editor shows you what options are available at the current position in the file:
DTD based code completion in XMLPad.
Fost says that if he was still working in a big team as an art lead, he'd be pretty excited about this. Common errors that always crop up when text files are edited by non-programmers can be caught in the editing application before the game is even run. Normally this necessitates programmers adding lots of code to check the files on load and pop up suitably helpful and explanatory error messages. Automatic pre-validation of the files results in a massive time saving on both sides.
Writing a DTD is pretty easy too and it can be stored in a shared location; even on a webserver, so when the DTD updates anybody attempting to parse documents automatically uses the latest version.
Here's an example xml file representing some solar system data:
Solar System XML:
The solar system definition contains
line1: xml header
line2: DTD definition - this will be pulled out by an xml editor and used for validation.
A top level container element which wraps all the information.
A element with setup information for the application (I'd probably put this in its own xml file with it's own DTD though).
A element, that contains multiple containers.
In addition, each instance of contains surface sub containers, and optionally an element.
My point in making it this detailed is to show how different structures can be defined in the DTD:
Solar System DTD:
The first line: tells us to expect a 'solsys' element first, which will contain only 'config' and 'bodies' elements in that order.
The 'bodies' tag is defined: ' '
the '+' means allow any number of 'body' sub-elements.
Next we can define sub elements such as 'orbitScale':
this is marked as 'EMPTY' because is has no closing tag (i.e. it's written as rather than )
Even though the tag is empty, it can still contain inline attributes which are useful for storing game data. The following entry in the DTD defines what attrivute names can be used (in the case, I'm using the attribute called 'value' ):
The '#REQUIRED' keyword means this attribute must be present else the file won't validate.
If the attribute contains data from a predefined set, then we can define this here too, as with the '' parameter:
This means you can insert any of the keywords: 'static', 'Mercury-VSOP87', 'Venus-VSOP87', 'elliptical' into the 'value' attribute. If anything else is present, then the file will not validate.
That's pretty much all you need for DTDs, at least as far as game data is concerned. The only other thing that is useful is the ability to define optional elements, by using a question mark. The 'ellipticalorbit' element in 'body' is optional:
Fost - Mr. Robot Art
The Ripple Effect
- click image for flash anim...
For shaders in the game, I didn't really want to go beyond the vertex shader 1.1 spec if possible. Keeping to that means more hardware T&L cards will be supported, but VS1.1 only allows 128 instruction slots. Of course, it will get emulated on the CPU, and for a game like Mr. Robot, we can probably get away with a fair amount of that, but every little helps.
This however proved difficult with the coolant shader. It was already doing the lighting, and texture scrolling, and scaling of the textures in the vertex shader. The coolant object in Mr. Robot is a 1 tile unit cube scaled to match the appropriate size set in the editor, so I use a multiple of the vertex world position to scale the texture coordinates - that way, the texturing is all at the right scale no matter what size you set the water to be. After all that, there wasn't a lot left to play with, but I wanted to have a mess with putting a 'wobble' into the vertices just to make it a tiny bit more interesting.
A pretty simple way to do this I thought, would be to apply a sine wave to the vertex height, based on the vertex horizontal position + time.
The first thing I did was subdivide the top of the coolant object quite a bit (without any vertices to wobble, it wouldn't look very good at all!) Then after much messing around, I finally got something running at the right scale (Initial tests resulted in screen sized tidal waves :( ). Problem was, it was a little too regular. So, the solution to that is more waves: if you apply lots of waves though a mesh, all at different amplitudes, wavelengths and frequencies, you can make a pretty nice irregular wave pattern. I've actually done this before many years ago with multiple octaves of noise for a pre-renderered water animation. Pretty quickly though, I hit the vertex shader instruction limit, and so whilst I was testing, I dropped out some of the point lights (Mr. Robot supports ambient light, a single directional light, and up to 5 point lights per room).
The problem with this kind of thing, is that it's always a matter of adjusting loads of parameters which all affect each other and so something pretty simple ends up taking all day :( Finally, I whittled it down to 3 sine waves - one running the length of the water, one along the width, and a much finer one at 45 degrees. With a bit of tidying up of the HLSL code, I managed to keep it all inside 128 instructions with all the lights turned on.
The code below is what I'm using - projectedVertex is the vertex in camera space ready for output (I think, not sure I've got the terminology right there :? ) and worldSpaceVertex is the vertex in world space. There's a slight issue in that there's also a small amount of horizontal wobble, but it's so small you can barely see it and is fine for the game. I think it's probably caused by using the wrong matrices to work out the output position, or adding a value to the object in camera space - bear in mind that I'm an artist and not a programmer, so I don't really understand what I'm doing :)
//Sine Wave X
tempY = 0.4*worldSpaceVertex.x; //Scale wavelength (big number=small wavenlength)
tempY = sin(g_time + tempY); //can multiply g_time to increase frequency
tempY *= 2; //Scale Amplitude
projectedVertex.y += tempY; //Add result to vertex position
//Sine Wave Z
tempY = 0.4*worldSpaceVertex.z;
tempY = sin(g_time + tempY);
tempY *= 2;
projectedVertex.y += tempY;
//Sine Wave X+Z
tempY = worldSpaceVertex.x + worldSpaceVertex.z;
tempY = sin(g_time + tempY);
tempY *= 1;
projectedVertex.y += tempY;
//END WAVE EFFECT//
- click image for flash anim...
This was a fun little effect to make for the teleporter. I used to love the really simple teleport effect in Lunar Jetman on the Spectrum, and so this is my mini-homage to that. Just a simple point emitter with very slow moving particles so they have some velocity and they can be velocity aligned. then they are just scaled along one axis - which since they are velocity aligned, and all moving away from a point turns the whole system into a big spiky orange ball.
- click image for flash anim...
You'll have to excuse the 'home movie' shaky camera in the flash anim; it's an artefact of scrolling around for the video, whilst the game camera is also trying to smoothly track the player position. Anyway, it should be possible to see what's going on here. It's an 'X-Ray' type effect, along the lines of many recent RTS games that allow you to see your units through buildings. It works by rendering the robot mesh once looking red and partially transparent, but with 'zenable' set to false (so the shader doesn't use the Z buffer), and then again in a second pass using the standard shader (with Z-Buffer enabled). A little messing around with the order in which things are drawn and we can control whether or not the X-Ray effect will be seen on a per-shader basis.
At this point, I'm not 100% sure if we'll be able to use it as I'll need to re-export any models that we don't want to see the effect on. Probably robots, crates and consoles should still obscure the player. Thankfully it's not necessary, as all the rooms are designed so you don't get confused by to much view-obscuring geometry, but it's a nice little feature for tracking exactly where you are.
More Particle Effect Shots
Asimov taking damage from a hostile robot.
Active waypoint looping effect.
Asimov taking damage in shallow coolant.
Poo Bear - Mr. Robot Programming
Lots of work on ghost hack gaming this month. I'm trying to get all the core functionality working so I can play through it all and finalise the design. To that end I'm trying to get the first part of the game fully working and integrated with ghost hacking. We have two modes that I call "reality" and "hacking". It's very important that they connect together properly so you can move easily between them.
- Picking up ghost hack items in the real world and being able to configure them on your avatar.
- Other robots giving you objectives to complete that require you to hack into something, recognizing when you do it and the appropriate dialogue firing.
- Being blocked by a door in reality, performing a hack, the door opening as a result.
The first ~30 rooms introduce various characters and ease you into learning how the game works both in reality and in hacking. This is the bit I want to get completely working. Even though we don't have all the animations, the models, the items or the frontend screens completed it is important to show the core systems running and meshing together. This is a very powerful development technique in an environment where specifications are nebulous. Some people might find it strange, but developers rarely understand how the entire game will work in detail until it is almost complete. This is usually because the game is implementing ideas that are new to the developers. Note that I didn't say the ideas themselves are new, that happens very rarely indeed. Unless we just make Starscape sequels or games based on our old mainstream titles we will be working with ideas and concepts we haven't implemented before. In that situation you really need focus on getting things working quickly so you can review them.
This prototyping technique continues right through development until all the unknowns are implemented and working. In an ideal world you would create all the prototypes at the start and only when you were happy with everything would you begin production at which point there would be no more unknowns at all. The reality (especially on a tight budget) is the prototypes start out big and flakey and then over the course of the development the prototypes become smaller and more focused as the game locks in on its final form. What I'm doing now with hacking will probably be the last prototype phase in this development. I'm not trying to prove whether hacking works; I've already done that in a much rougher earlier prototype.
I now want questions answered like:
- Do all my item ideas work and have I forgotten anything? 'Items' refers the things you use to modify your ghost hacking avatars, like attack programs, defensive upgrades, restoratives, etc.
- Do the systems I've designed to synchronise reality and hacking together work as intended? This includes things like when all the avatars die during a hack and you get thrown back into reality and must then search real space for energon pickups you can trade in to buy their runtime lives back.
One of the assumptions I made is that when you complete your hacking objective you'll have to work your way back to an exit to get out. There was no way of testing what that would really be like unless I had a rough prototype.
I needed to know:
- How long the hack would take.
- How many resources I'd need to get in and out, which corresponds to how much preparation is needed before taking on the hack.
- How thrilling it would be "running" for the exit with a damaged party and limited remaining resources.
- How annoying it would be to get killed next to the exit.
If this assumption is proved wrong then I have two choices:
- Use playtesting to make it easier to get in and out reducing the chance of you being killed near the exit. This means putting things off until the playtesting phase in beta.
- Throwing the player out of hacking mode when his objective is complete.
An auto exit on objective complete has an interesting side effect in that it reduces your journey time by 50% and therefore reduces your random encounters by the same amount. This means the hacking part of the game would take half as long. If that was a problem you could just double the size of the circuit maps, but then they are created by hand using a time consuming editor. This is why we need a prototype now, because we must know how big the hacking maps need to be. Especially as some have already been made ;)
Save & Load
I don't actually want players to have to save their game. Eh? Currently we have in game objects called backup points where you can save your "brain" and restore it if anything goes wrong. A slight twist of logic, but I think it works. So the player makes progress up to the next backup point (or waypoint) and then jumps on it and the game saves automatically. So you don't have multiple saves and you don't need to remember where you got to last time. You just start up the game and there you are.
As you strike out for the next waypoint you will have 3 lives which can be exhausted by falling in water or being caught by enemy robots. If you run out of lives you automatically reset to the last waypoint. You can recover your "life" if it gets low by picking up energon units and if you get stuck you can initiate a local reset of the room you are currently in (at any time, for free).
It's another set of ideas that really need prototyping. I'm trying to prevent people going through a loop of explore->die->reload->repeat. Yet I want them to feel the tension of being down to their last nugget of health and desperately searching for that elusive waypoint. A fine balance to achieve indeed.
The way this is implemented requires a copy of your current game save to be loaded into memory. Then, as you progress, the in-memory save is updated with what you have done. If you die or elect to go back to the last waypoint then the in-memory save is thrown away. If you hit a new waypoint then the in-memory save is written to disk and becomes permanent. The amount of information that needs to be recorded is huge. For example: if you move something from one position to another then that needs recording. Anything and everything you can interact with and change in any way needs recording and it all needs to be put back where it was and in its original state if a reset occurs.
I thought it would be interesting to post a shot of the editor in use just to show how truly awful the game can look whilst we are making it :) . We have found that a really good way for us to work is as follows:
- I spec out a room design, and start to block it in.
- If there are any scenery objects that I require for the room that don't exist yet, I tell Fost, and after we've discussed what it might look like he exports a quick placeholder object of the right size which I use to continue building the level.
- As soon as Fost gets round to it, he exports the finished object, and because we've already defined the object (but used a placeholder visual representation) every room that needs it automatically starts looking good the next time the game is fired up.
This saves a lot of time, because we don't have to go through and re-edit the rooms re-inserting finished art. The flipside is it requires a lot of imagination to visualise what the final room could look like.
The picture below is of the 'Hub' room work in progress. It's the central command area for the entire ship, and all sections are accessed from it. Hopefully, Fost will be able to post a comparison shot next month and we'll get to see what it all is supposed to look like - even I don't know yet! If we manage to ship the editor with the game, everyone will have a far better experience than I have, because they'll be able to build rooms using finished artwork and room will looks exactly the same as how you are building it in the editor.
The Eidolon's Central HUB built from placeholder blocks. Note-In case you hadn't guessed, it's not supposed to look this bad!
Tune in next month for the exciting conclusion to 'building the Hub room' ... ;)
Fost - Mr. Robot Art
Set Design - Final Touches.
- click image for flash anim...
Like a human tube of polyfilla, I've just been concentrating on filling in all the holes in the scenery objects list. As Poo Bear makes rooms, he makes a note for me of anything that he needs. For example - we've been using Storage area doors in the cryo area, so I've made some shiny new doors for cryo (left). I've also been going through the rooms and adding a few little unique bits of scenery - there's more than 200 static (i.e. not counting robots, items or anything that can be moved around) scenery objects in the game now, so it doesn't look too repetitive, but anything that helps break up the look of the backdrops adds that little bit extra to the overall impact of the game's look. Lighting is also proving to be a great way to alter the look of the rooms.
Anyway, enough talk! This month I'm just going to fire scenery artwork and room pictures at you.
I removed the insignia from the shuttle, so I could add it back in using an overlay object. This means I can have a different insignia decal for each shuttle- just another little thing I think is nice to do so that each room in the game world has small touchness that make it unique.
Fat pipes make great dividers for the cryo section.
Just a corridor, but I really love the way the cryo walls pick out light - cryo rooms are the most fun when playing with lighting setups.
Samson sized service corridor.
This month's mini development tip - many applications have a hidden away option to increase the number of files in the recent file history list. I've been through all the apps I use on a regular basis setting that value to the maximum. My memory has never been very good, and I waste a lot of time trying to remember where I left things on the hard-drive so this helps enormously. In particular with the text editor I use for editing shader files/objects lists/config files etc this has been a minor triumph of technology over memory loss :)
- click image for flash anim...
It's great when you can re-use existing systems. This locker model uses the same game systems as the doors. The front is using the door texture scrolling mechanism to 'roll up' like a shutter. Items can be picked up by searching lockers througout the game.
Started work on the inventory items - things Asimov can pick up in the game. There's going to be a ton of items once we get deeper into ghost hack (you can pick up special programs and hacking tools to use in ghost hack). Each item needs an icon that shows up in your inventory, and also I'm adding a 3D model so it can be left on the floor - these aren't really necessary, as everything is picked up in lockers at the moment, but it means the game won't break if someone tries to put an item on the floor. There's already a growing list of ways you can easily break the game because of things you do in the editor, so I'm trying not to so anything that makes the list even longer. We'll have to fix any of those problems before we think the editor can be released, so a little bit of work now is another step towards the editor being public usable.
- click image for flash anim...
Quite a bit of work has being going into the finale of Mr. Robot this month, I did have some images of HEL (the ship's computer) and animation showing him in action, but we decided we should pull them - we've gotten used to being open about what's going into the game, but we should really leave a few surprises in for you! HEL is semi-procedurally animated - I produce an animated control mesh, and sets of objects, and Poo Bear glues it all together with code. I've also been doing a set of scenery objects for the 'Mind Core' section of the ship where the action comes to a head. Again, we want to hold much of that back, but here's the door object I made.
Needless to say, it was a complete and utter nightmare getting this to work :) It uses the existing door code with an edited shader - so Poo Bear doesn't have to do any work. The shader takes the door opening and closing values and uses them for the texture rotation after scaling them to suitable values. The iris door has 9 blades which I lined after finding a diagram in a technical manual for repairing cameras! I've wanted to make a door like this ever since I saw Dallas crawling around in those air ducts in Alien :)
Poo Bear - Mr. Robot Programming
I've talked previously about the power of the LUA scripting language, but sometimes you don't really need that level of sophistication or the program overhead of setting a full LUA instance up in memory. One obvious example is when you are filling out an initialization file for a game entity like the ghost hack enemies. This simple text file contains default starting values for different bad guys, things like name, model to use, animation lists, strength, etc. Some things however, are better expressed as a formula, see below for actual MrRobot examples:
fortitude_formula val = 2 + (level / 2);
energy_inc_formula val = 1 + ((0.5 * die) -2);
To make the game use this formula I could have created a LUA instance and executed it that way but I already had a simple function parser on hand that had less overhead and was cleaner to setup.
Done this way the game can pull these formulas out of the initialization files, save them as a small text string and then when needed they are executed directly via the mini formula parser. The words die, level and val are special keywords the parser understands. Without this kind of functionality a game will become littered with hidden magic formulas that can have a major impact on how a game plays. By exposing them in the initialization files a non-programmer can change them as necessary and we don't need to dig through source code to find them or recompile the game when they change. Obviously there is an efficiency overhead associated with doing this, but if it doesn't impact on framerate then its definitely the best approach. This could have been done in Lua almost as easily, I just want to highlight the power and flexibility of scripting languages in general and data driven design techniques specifically.
Even in these days of broadband, download size is very important. I think the USA is on track for 65% broadband coverage in the next year or two. So there are a lot of modem users still out there. Even with broadband, file size can still put off people who are browsing and aren't necessarily hunting for your game.
When you look at the size of your game installer you usually find a very high proportion of that space is taken up by artwork. It's a rule of thumb, but most textures are often around 256x256 pixels, so they look nice and crisp at fairly high resolutions like 1025x768. Each pixel has an 8 bit red, green, blue and alpha component. We don't always need the alpha part, it is used by the hardware to control transparent portions of the image. So our example texture will take up 262,144 bytes on disk. MrRobot has about 300 textures currently, which is roughly 75MB. Using something like winzip we can get that down to about 15MB with no loss of quality, a 5 to 1 compression. Now instead of saving the images at full quality (using the tga format) we can use a lossy format like jpg. By saving the image out as a jpg you are pre-compressing it and the harder you do it the worse the image looks. As the compression system is vaguely similar to winzip anyway, then you haven't saved much as winzip wont be able to make a jpg much smaller if at all. The only benefit is you can set the compression level per image by hand, so some might be forced smaller without suffering loss of image quality. So you might get up to 6 to 1, but probably with some image quality issues.
An evolution of the jpg format that isn't widely used is j2k, which means jpeg 2000. This system is far superior to jpg and can easily compress our source artwork at a 10 to 1 ratio, from 75MB to 7.5MB with little to no perceived loss of quality in most images. What I normally do is compress everything at 10:1 and then do a run through of all artwork at the end of the project lowering the compression on the 1-2% of images that are highly complex and suffer artifacts.
The power of j2k has a downside which is extremely slow encode and decode times due to the highly complex nature of the algorithms being used. Probably the oldest freely downloadable j2k library is jasper and the creator did a great service by releasing it. The only problem is, speed wasn't a priority in its development and it is very slow.
Encoding time doesn't really matter, because we encode the images once when building the installer. It's decode time that is vital, the image must be decoded back into a flat 32bit image so the graphics card can load it. Or if you're very clever then one of DirectX's compressed formats like DXT3.
All is not lost. A new decoder codec saves the day by being about 40x faster than jasper and unlike all the other big companies making decoders it doesn't cost $10k :) I was also shocked by how easy it was to use compared to jasper, just a couple of lines of code and away it went.
You can see an uncompressed (1 meg PNG) image comparison by clicking below :
The new codec is so fast we don't need to have a decompression on install application. Starscape used to install and then launch a small app that crunched through all the images and it took minutes on low spec hardware. The next version of Starscape will hopefully have a rewritten decompressor app that should just take seconds. I think it is worth keeping that post-install decompression app as Starscape is meant to run on very low spec hardware and has a huge amount of artwork. MrRobot being a fully 3d game, is far more efficient with regards to texture space and also needs a higher minimum spec machine to run. Therefore I'm probably going to leave the textures in their j2k format and decompress them on the fly when loaded. Initial tests showed this made the one-off game start load go from 9sec to 13sec which I think is fine. Further testing will be needed of course, but I think it's worth a slightly slower load to make the install process faster and simpler.
Early Usability Testing
The core game (everything but ghost hack) has now reached a point where some basic usability testing can come in handy. We have a small test group of computer illiterates that we find handy for this kind of thing (parents or grandparents are usually very good depending on their familiarity with computers - obviously, some basic knowledge is required.)
We then sit them in front of the game, and let them go. The important thing is not to guide them. Reinforce in advance that this is not a test of them, but a test of the game, and there are no wrong answers - otherwise you end up with them being overly cautious and not wanting to feel stupid trying things. Then just note down what they do, what buttons they click on first etc. You can even video the whole thing if you have a camera handy. If you come across an interface problem, or a bug, then you can just help them past that point and explain that it's a problem with the game, and carry on.
This initial pass has highlighted some basic issues with the tutorial - mainly a couple of points where the player can become lost, or miss something like a door that has been opened for them. Not too bad, and pretty easy to rectify. It's nice to get a lot of things out of the way before beta.
One thing that has been suprisingly successful is the camera. A couple of people in the group were originally chosen to test Starscape because of their inability to play 3D games. It seems that the fixed camera, whilst obviously a choice we made to make development easier on ourselves, also helps people with atrocious spatial awareness make sense of their in game surroundings. They do have some initial trouble with the 'isometrically' lined up controls - 'up' being 'up-right', but they soon get over that, and it's amusing to see people who have never been able to play Mario 64 jumping around like rabbits after 5 minutes with Mr. Robot. When we get nearer release we will do a larger beta test with people randomly selected from those who bought Starscape. With a large beta using players all over the Internet it is important to have squashed as many bugs as you can beforehand. When people are not actually in the room with you it is a lot harder to properly analyse their input.
Procedurally Animated Models (sort of...)
The game's finale takes place inside the 'mindcore', a set of rooms surrounding the ship's supercomputer: HEL. In designing what HEL should look like, we came up with the idea of an animated head built from lots of small cubes. The vertex data to do that would be huge (we estimated 30 meg+ just for HEL's animations!) so we came up with another idea: Fost creates an animated, low poly 'control mesh'. We then read this in and build a representation of it from lots of cubes. the entire thing is then shunted off to a dynamically allocated vertex buffer. It looks pretty nice, but you'll have to take my word for it, as we've made the decision to leave most of the mindcore art as a surprise for everyone Wink
Super Powered Batch Files
When preparing the installer we need to pull in exactly the right files from all over the development machine while also applying any special processing like image compression. This is more difficult than it sounds as the game probably has ~700 different files and the development system probably has double that in temporary, debugger, build files. With Starscape this was done using some hand written instructions (which were then lost) and some horrible windows batch files.
Once again the power of Lua comes to the rescue, if you download Lua you'll also get a standalone exe that can load lua text files and execute them. This means your batchfiles suddenly have all the power and sophistication of a programming language. I didn't end up using the interpreter that comes with lua as I wanted to add a few extra functions to do some specific things. Very easy to do, just code them up in C++, tell lua about them, build a new exe and the lua textfiles can then refer to these functions by name and pass data around as if they were built into the language. You can do everything a batch file can (as far as I know) and a huge amount more and the files are infinitely easier to read.
Fost - Mr. Robot Art
Another hero object we have used in later areas is the Eidolon shuttle. The Eidolon carries several of these for making short scientific expeditions. (Sorry, Asimov can't fly them off though ;) ). I wanted the shuttle to have a small visual link back to the Starscape universe, and so it is designed to look like an earlier model of the Aegis' shuttles from Starscape. It was fun extrapolating the former 2D design into 3D, but it presented a few problems with the collision objects. Static block objects can only be concave boxes on a half height grid. The shuttle had to be designed around this proportion system, and then split up into 6 separate objects each with their own collision. Takes a little while to assemble it in the editor, but it works nicely. I've named the first one Serenity after our TV favourite :)
Assembled Shuttle in game.
Learning C++ - the copy and paste method!
The bane of a game artist's life is usually the editing tool they use. With indie development, there's even less time for programmers to spend making the tools 'friendly' and so editor work is more often than not a case of becoming familiar with what will crash the editor and making sure you don't accidentally do that, and hitting save every five minutes. I can't fail but appreciate that this suffering is necessary - better Poo Bear works on interesting gameplay than have him waste time wading around in editor code he didn't write!
Still, sometimes there are some incredibly minor fixes that could make my life much easier. To this end, I started learning C++ in the only way I know how - hacking around copying bits of code from one place to the other. My previous knowledge of PHP, maxscript and AMOS basic ;) helped me find my way around, and make some small tweaks to the editor.
It's a really bad idea for a non-programmer to start messing about with production code, but I've limited my efforts to the editor in the vain hope I won't destroy everything :) . So far I've changed the way lights are displayed so you get nice, axis aligned wire loops rather than the wireframe ones we had before. I've also added a zoom feature - again, a very basic thing, but we hadn't needed it before I started lighting the rooms. Some interesting lighting effects can be made using really huge lights placed far away, but they were impossible to find without the ability to zoom out. I've also made the editor save the last room it worked on so you can slip right back into what you were doing quickly, and fixed some small bugs where lights were moved around if you resized the room.
All quite small things, but they make my life that bit easier, and put us a bit further down the path to the possibility of releasing the editor. On that note, I've added help buttons and started a compiled html help file (.chm) to the project. Currently, the editor is not releasable*, so I don't want to get everyone's hopes up. I'm keeping as many notes as possible for the help file just in case it becomes possible.
*That's our opinion at Moonpod anyway - we don't like the idea of releasing the editor 'as is' without putting more work into 'bulletproofing' it.
My remaining task list is choc full of small items. I'm basically filling in the blanks. Poo Bear makes a room, and if there's anything unique he needs, he adds it to my list. Since we added a big robot like Samson, we also needed a big door for him to go through. One of the sections in the game also contains an airlock. the airlock in particular ended up being more work than I initially envisaged (Or, I should say, I added a bit more to it than was strictly necessary!). The materials system we have is very capable, but there's no user friendly interface to it. So even adding simple texture scrolling to an object involves quite a bit of messing with the shader. The airlock has 3 separate door sections, and a copy of those doors offset back slightly and darkened to give the impression of depth (remember, doors are built in Mr. Robot from single polygons and use texture scrolling to slide the door out of the way. This means there's no depth to them, but it can be faked with another copy of the doors.). Lining up all these door sections was very difficult because I had to keep resetting rooms and picking up keys to see them open. This is where Lua scripts turned out to be very useful. Poo Bear showed me how to set up the room to open and close the doors on a timer, so the doors perpertually opened and closed. Great for finding visual discrepancies :)
To cap it off, the Airlock also has a basic shader to turn lights on and off, and a slightly more complicated shader that 'camera maps' a texture onto the surface. this is used on a backdrop rectangle that sits outside the doors. As you move around and the camera pans, the space and stars image appears to be locked to the camera, and therefore looks infinitely far away.
Airlock (Left) and Big, Samson Sized Door(Right) in a test room.
The Vacuum (cleaner) Of Space...!
Mini Flash Animation of Dyson the Cleaning Droid.
Meet Dyson - head of the Eidolon's cleaning crew. Dyson has what you would call a 'walk on part' but he was a lot of fun to come up with. Poo Bear's daughter drew me a little picture of a robot with long 'anglepoise' style bendy arms for cleaning up the space ship. I really liked the concept of a futuristic vacuum cleaner robot :) I also love the design ethos behind the products made by the Dyson company. So I came at this design wondering what the people at Dyson would be making in the future :).
Dyson is probably the last robot to go into the game, unless we decide that rooms need something adding to them during play testing.
Final approved Dyson concept design.
Dyson Game Model
Flip ya for real!
Just some quick little art tips. They probably seem obvious and incredibly minor to most people, but every now and then I discover things that make my life easier.
- Shorcuts in Photoshop: I've no idea what version it turned up in, or if it's always been there, but in the current version of Photoshop you can edit the shortcut keys. During the texturing process, I end up making loads of selection flips and rotations to construct geometric shapes from basic lines. I added shortcuts for FlipY, FlipX and Rotate 90?. It's amazing how small processes can break your flow of creativity. These 3 shortcuts mean I now just mess about with texture alignment to my heart's content - because it's easy to try things out in an instant.
- Never overlap textures: I've made this a golden rull from now on. Sometimes in the past, I've been annoyed how textures won't fit perfectly on a page because of one small part. Sometimes I fix this by re-using the same piece of texture. I'm not talking about texture mirroring here (using the right side of an object mirrored to create the left side), but thinking things like: 'that bit of arm there can be re-used to texture the fingers or hand'. Don't ask me why, it's a mystery, but it just never works! Usually some bit of shading makes the whole thing look fine on one part, and broken on the other. I've stopped doing this, and I'm happier for it!
Relight My Fire!
A continual job on Mr. Robot is lighting the rooms. In theory, I could just use a default ambient light and directional light and save myself some trouble, but I don't think that would really show off the game (plus, it would get a little dull). Besides, I like breaking my own back :)
One thing I've discovered in lighting, is that I can get really nice hue falloffs using two lights in the same position. E.g. one deep orangey-red light with wide range, and a smaller yellowey light. It's obviously double the cost of normal lighting, so I can only really do it in smaller rooms, but I really like the way the hue of the light changes as it falls off.
Although the image has a lot going on, you can probably just make out the lights/ranges and positions:
Poo Bear - Mr. Robot Programming
I've just put the finishing touches on the last section of the ship and I feel like I've just crossed the finishing line of a marathon. I wont say how many separate rooms and corridors and sections the ship has but it's well over a hundred. It would have been easy and quick to just regurgitate different configurations of the same challenge again and again but I decided early on to avoid that at all costs. This is the main reason the game has taken so long to create. The game has a great editor and also makes heavy use of the LUA scripting language; both firsts for us. These tools were essential to hand craft this quantity of unique content, but even with them it was a mountain of work.
Sadly this doesn't mean the game is ready to ship (oh if only that were true!), I still have to setup all the "ghost hacking" battle stages. This is where the robot Asimov must hack into a defended computer system with the help of his comrades. Development is split into phases, you have prototyping, then production, the alpha and finally beta.
Prototyping - is this actually fun? how does the code work? can we build it, create a design document and make the tools?
Production - following the design document go ahead and build everything.
Alpha - bring it all together and get it working properly so you can play through beginning to end and playtest it to hone the fun to its maximum.
Beta - fix all the bugs and get all the ancillary items sorted like installers and websites, etc.
I'd say ghost battles are well into their production phase with the rest of the game now just into the alpha phase. So for the first time I feel I can see the light at the end of the tunnel. Hacking sees you exploring the glowing circuits of various computer brains and secure networks with periodic battles. Ghost battles are turn based and start with each group of adversaries facing off to each other. Asimov and his friends line up on one side and the enemy group into formation on the other. The player then gives orders to Asimov and his friends and then an internal initiative system sees a round kick off with software attack programs flying through the air and I.C.E. breaker attacks smashing into their targets. During the course of the game the hacks get more difficult and Asimov has to power himself up by collecting various upgrades. He also picks up more and more friends for his ghost team along the way.
The LUA scripting has grown into the real backbone of the game code. LUA is a simplified C language that is very easy to use and still allows the author to create very powerful expressive functionality within the game. On its own it cannot interact with the game world so you have to extend the language by providing new commands that allow the script to do things to the game. Getting all the language extensions in took a major time investment, but it has already paid off. It's interesting to compare it to the WarAngels system which went in a lot faster and is much easier to use by non-programmers. It depends what you need in the editing process, with MrRobot each area of the ship is in many ways almost an entirely new game in terms of actual game mechanics. With a mountain of a ship to build I had no choice but to create a powerful scripting system, without which the ship would have had replicated content or been a lot smaller. WarAngels is different and it would have been overkill to do the same thing, adding maybe another 2-3 months onto its schedule for little benefit. In that game the fun comes from exploring the level, finding and using appropriate weapons and ammo, along with the placement, AI and choice of enemy types. Speed and destruction. The right tools for the right job is half the battle.
The command list has grown quite extensive so far:
Hopefully it wont be long until we get the editor in a state players can use it and then they could access exactly the same library of commands when making their own game levels. That would be very cool.
We've just finished some initial testing on the dreaded "built into your motherboard - shared memory" graphics processors that are so prevalent these days. The old ones were terrible, absolutely useless and we had lots of email from people who couldn't understand why no game worked (including ours). The new ones, led by the Intel Graphics Media Accelerator chip (the GMA900) are light years beyond their prehistoric ancestors. Everything works fine and they even support pixel shader 2.0 which is amazing considering how cheap they are, these chips cost pennies and come built-in to bargain basement motherboards. I was so impressed with that particular chip I even tried Doom3 on it and it worked !! Ok I was only running at 640x480 and had everything turned down, but still, an impressive achievement compared to the old Intel eXtreme chips.
Here's a great tip for anyone up against it. The new scientist recently reported the findings of a study looking at how food affects sleep. They found that eating a lot of chilli's every day caused their subjects to require less sleep and remain fully alert longer. It is thought the effects are due to capsaicin, the chemical responsible for peppers' spiciness. It acts on sensors in our brain which control our sleep cycles causing us to spend longer in deep sleep. This mode of sleep usually only lasts for 30mins a night during which you do not dream and it is almost impossible to wake up. Test subjects remained in this state longer. Chilli also cuts the risk of heart disease. So there you go, eat about 30g of chillies a day and get a few extra hours of work done. I tried it and it worked for me.
A Few Room Shots To Keep You Going!
Dyson does some spring cleaning
Asimov ponders what to do. Luckily, the tiny nanomek team are on hand to assist!
Hamish - War Angels
Sorry for the lack of diary updates for those of you who are following the game. I've been working hard converting the game to it's new 3D look over the past few months, so with all the work I've been doing and the lack of substanial screenshot material I didn't manage to start an entry in time. Now that things have settled down and the progress is starting to show I hope I can make an update every month.
Perhaps the biggest advancement I've made on the game in the last few months is from switching to 2D tile-based maps to lightmapped 3D polygonal maps. I was consistently unhappy with the look of my 2D tiles, they were taking a very long time to make and get into the game editor and were taking up alot of disk space. I thought about the limited 3D effects I was already using, then I had an epiphany - why not go the whole way? I did some experimenting with a 3D editor, and after a few weeks I came out with a result that I felt looked alot better, and was alot easier to edit and develop.
I established a good art pipeline with two cheap, independent 3D utilities - Cartography Shop for modelling the levels (placing and texturing all the shapes that make the physical map) and Gile[s] for lightmapping them (Creating a second texture layer over the whole map that is blended over the the top of the original texture map to create lighting and shadows). Both are simple enough for a 3D newbie like me to pick up and plug into my game straight away while complex enough to create decent looking game art.
Before I start making the map I go through a rough planning phase. This is the first time in my game development life that I've actually planned levels, but when you have three programs to run your map through to get it up and running in the game I find it's faster to draw it up first. I already have all the level settings jotted down so I know basically what I'm aiming for to start with, the plan is used mainly to plan the way the gameplay flows, where specific art pieces will go (like the park and the mall) and where certain scripts will be executed. The map will probably change radically while it's being made but this serves as a good starting point.
Constructing the map is a 3-phase process, using three different programs. In Figure 1 you can see one of Cartography Shop's 2D viewports, where I lay out the map geometry. Figure 2 is 3D view of CShop where I set the textures for each polygon and scale/rotate them so they fit to the polygons perfectly. Then it gets exported to Gile[s] where I lightmap it. Lightmapping takes quite a while, doing a full level can take an hour, so I break up a level into 5-10 segments so I can test each piece quickly. In Figure 3 you can see the lit map area in Gile[s]. Finally the lit map is exported from Gile[s] into a format the game can read. I run the game in Editor Mode, where I place all the enemies, scripts and other interactive objects. In Figure 4 you can see me playing the completed map segment.
Ultimately converting the maps to 3D was a big success. Unlike tiles which have hundreds of variations, textures are very easy to modify allowing me to tweak them very easily. Computer-calculated lighting looks alot more natural and consistant than my previous attempts at shading and colouring grey buildings and the perspective of it all looks good in motion as you can see in the video at the end of the post. Here's a comparison shot of the old 2D city park and my current 3D park:
Once the map's been made, I have to populate it with interactive objects; mainly enemies. With action games becoming less abstract and increasingly realistic, designing interesting enemies and challenges becomes increasingly difficult. While this game isn't Rainbow Six I still wanted enemies that had a bit of backstory and seem realistic, at least within the game world. When I started the game I designed my enemies like a strategy game - soldier with 10 weapon variations, tank with 3 turret types, humvee and apc with mounted soldier on top, etc. They were all realistic army units, but many were no fun to fight. Tanks, snipers, machine-gunners and other anti-infantry units could kill you in an instant.
With my latest revision of enemies I've put player fun and variety first, and come up with a new three-enemy set for Level 1. Each one requires a different tactic to defeat, and can be combined together requiring you to use multiple tactics in the same battle. I've also managed to give them a background and purpose in the game world, which won't be readily apparent to the player, but certainly helps make the world feel coherent and detailed to me, which will hopefully show through with the dialogue and story.
Conscripts will be the first type of infantry you fight. They are not true Nazis, but rather people forced into the army when their country was re-conquered by the Nazi army. Not being Aryan they are looked down upon by the real Nazis, and forced into their own divison of the army (identifyable by their blue uniform and yellow V logo) where they are equipped with cheap and often ineffective weaponry. The Nazis use this divison either as meat-shields at the front of an invasion, or in the case of the first level, backwater occupation forces with a low risk of combat. They are not well trained, or often not trained at all, and therefore very weak and cowardly. They will often try and run away when you kill the rest of their squad.
Gameplay wise they are the pefect enemy to start the game with. Easy and fun to kill. There are four or five variations of the troops, with riot gear like shields, batons or grenade launchers. Most troops can be fought in the same manner however - keep your distance, and kill them before they can get close enough to hit you.
The patrol bot was developed to aid Nazi conscript occupation forces in subduing civil unrest and rioting. It can be programmed to autonomously patrol the streets attacking percieved threats, instilling fear and obedience in the citizens of conquered cities. It functions well against rioting civilians, with light armour and an area-of-effect grenade launcher (although it can be equipped with other weapons). Its threat to you is minimal however, and will be taken down easily with high-calibre weapons or explosives.
One enemy type alone doesn't keep the player interested for long, so I made this enemy to compliment the soldiers on Level 1. It is relatively fast so strafing this enemy is more effective than running. It also introduces the player to the concept of armour types early - your team-mates will point out that grenades will destroy them much quicker than bullets will.
Deployable Missile Turret
This deployable missile turret shoots two guided rockets at once, and is used against tanks and low-flying aircraft. Their heat-seeking guidance system won't work on people however, so if you fight them alone they can be taken out with relative ease.
I was previously using machine gunners as mounted enemies for the first level, but these proved to be much more interesting. Missiles are slower than bullets but more deadly, so the player must pick them out of the crowd and dodge them on top of whatever else they're doing. And once you kill them, you can get on their turret and use it yourself. Letting the player use a big gun early on in the game definitely helps sell them on it.
On the programming side of things, I've recently had to write an external scripting system for special in-game events and dialogue. It had to be flexible enough to use for any sort of scene I needed to program in game, and easy enough for script translators to go through and change/add/remove all the dialog. The scripts are all written in an external text file then parsed into the game when it loads up. Here's an example script I've been using to test:
Say Captain #Sup doods#
Say Rayne #Hello#
Say Captain #I'm walking to this spot over here#
Move Captain TestZone
ZoneWait Captain TestZone
Say Captain #I have arrived#
say Rayne #Great work!#
the 'Say' command will make an in-game message box pop up, with the specified character portrait and it will display the specified message. 'Wait' will wait for a certain amount of milliseconds. With these two commands I can create dialog between characters. Aswell as being able make conversations, the script can currently move characters to places with the 'Move' command.
In the game there will be an invisible trigger area set to start the script - in this case 'TestScript'. Other areas like 'TestZone' and characters like 'Captain' and 'Rayne' are also defined in the in-game editor. When the script is started, it will go through and execute each command in order. With simple conditions like 'Zonewait' which waits for an object to reach the specified zone, I have quite a powerful mini-programming language for me, a scriptwriter or a translator to develop the ingame story with.
I've decided to show a short video of the game if possible each month. I'll start off with a much longer preview of the first map (with a few of the more expensive weapons). Right-click the picture to download (18 meg):