First display. Dwarf In Space
At Graftgold we tended to reuse our game system for every game. It would be constantly upgraded to incorporate new technology but the heart of the system would endure. This made it very stable and was made possible be a design that isolated the bits that needed to change for each machine. That was one of the key aims of my new design. I was not sure what game to write so designed a framework that would allow me to rapidly prototype any game.
One area of any game that is fiddly and usually undergoes a great deal of change of screen design. I have had a great deal of experience with Visual Basic and is related technologies so decided it would be fun and beneficial to write a system to allow me to rapidly create forms, or screen layouts that could be defined in XML files. I wanted a range of controls similar to Visual Basic such as text boxes, button, dropdowns and grids.I wanted to be able to add panels in which I could run a 3d or 2d scene. I spent a while drawing diagrams of the structure I wanted.
Main Form. This object defines the screen as a whole and is the parent of every sub object. It owns sub objects such as child screens that divide the main screen into active parts. I wanted these to be switchable.
I also wanted to be able to switch a main screen to another main screen easily. In past games no matter how much time I tried to fix screen design before coding it was always necessary to change things around to get a really fluid feeling.
Form This object defined a sub area of a form , defines its background and owns any sub areas.
Controls. These can be placed on a form to display information or accept user control.
"No matter how good your plans, the data structures change overtime"
I decided to have a parent child hierarchy for this set of objects. I had written really fast XML parsers before so decided it would be a good idea to use xml as the way of inputting screen positioning data. Then I could use standard xml tools to edit the data. I then hit on the idea of using metadata to define the C structures I used to define the display objects. Meta data is data that allows the program to read information about the data structures. C is sadly lacking in metadata so you cannot write general routines to say print out the contents of a structure. Meta data lets you loop through the fields in a structure, decide whether they are text or numeric etc. I drove the parser from the meta data allowing me to write a general routine to load XML data ibt C structures. One of the key fields in the display objects was a unique identifier. I used that to create cross references between xml items. I could then predefine and load complicated cross linked data directly into C and also create all the parent ,child links automatically. This would save page loads of code to load each structure with specific routines that would have to be amended every time I change a structure.
That is one thing I have learnt over the years: No matter how good your plans, the data structures change overtime. You can spend more time applying small changes than writing the original code.
There were a few new system routines I needed first. I decided to write a standard link list routine to handle all the parent/child/sibling relationships . I needed a file handler routine. That is a much better plan than reading files willy nilly in any code. Then you can put a load of exception processing to handle all the possibilities of bad file loads. I also decided to add a simple event system to allow objects to communicate indirectly or directly but controllably by calling an objects event handler. This would allow things like a button press to affect a form change.
The first bit of xml I parsed was a simple text dictionary. Its a good idea to put all text in a game in a loadable file so you can translate it easily. I wanted a simple hierarchy that defined two simple objects, a text group that would contain a list of related items and the text itself. I also though it would be good to cater for different kinds of memory storage. You might want to load data into allocated memory or into preallocated memory. After a while I decided to write a collection called a pointer list for simple memory tables such as the text. This would automatically construct a list of C pointers to the data. This is a sample of one of the XML files
<GROUP NAME=TXTGRP PTRSIZE=30 PTRTYPE=GROUP EXTEND=1 >
<GROUP NAME=BUTTONS PTRSIZE=3 PTRTYPE=TEXT EXTEND=1 >
<TEXT NAME=TXT1 TEXT="UPDATE"></TEXT>
"Occasionally I used it to change code on the fly but that could easily end in tears! "
Its amazing how much code you need to support a game. It took a few months to get this all working. I wrote routines to automatically transfer a structure using metadata to a grid control. That took a bit of thinking but once written allowed me to to display any structure with metadata while the game is running.
That is one of the big drawbacks of Microsoft debugging. They haven't realised that its good to look at your data while the program runs. I like to look at a block of memory and see the bytes that are changing. At Graftgold Andrew Braybrook wrote a little monitor we used to call ABMON. It allowed us to examine a small section of memory as the game ran. We could even type in bytes without stopping the game. That was a boon when it came to tuning up movement patterns or player control. Occasionally I used it to change code on the fly but that could easily end in tears!
I also wrote my safe text routines using my new text object. Each text object knows the length of its text area so can protect against overwriting. Microsoft have a set of safe text routines but I like to keep as compiler neutral as possible. I did interface to their routine for processing an indefinite amount of insertion data into a text string, I just couldn't be bothered to write that one. I needed to get something showing on the screen
so I could test my controls.
"They always seem to leave out the vital bit."
Direct X is one of those things that just has to be overcome at some point. I had already spent many days tearing out my hair to get their demos working and trying to understand their documentation. They always seem to leave out the vital bit. For example I look up drawing triangles to make sure whether the points have to be in a clockwise or anti clockwise order. On the page devoted to drawing triangles it doesn't say. There is an example vertex list of two triangles, the first in clockwise the second in anti clockwise order. I have worked with 3d systems for 30 years but still found it extremely difficult to understand. It was all the little things that happen behind the scenes they forget to mention that caused the confusion. I knew for example that to scale objects in the distance there is a z divide that happens. It just does not tell you where.
My advice to anyone starting out is to seek out some of the better Direct X tutors on the internet that use worked examples to build up a system. These are still sadly lacking in my opinion. Its one thing to be able to display a spinning cube with a single texture all defined and loaded by specific code but quite another to handle all the hundreds you need in a game. How do you you efficiently manage all the different graphics attribute processing , different screen areas, multiple shaders with different variable requirements etc etc?
The more I looked the more I needed to know. Some examples annoyingly state they are only an example and its not how you would do it efficiently, then fail to show you how to do it properly. I knew the only way was to experiment, start with a simple process that I could time and build up complication gradually.
"Black on black"
Then the fun started. All programmers have been there. In the old days you spent ages typing code printed in a magazine to find it didn't work. You then spend ages trying to figure out which bit you typed in wrong.
The equivalent nowadays is to copy all the bits you need for the simplest display and run it expecting a nice little triangle. But all you get is a black on black. With no clue as to what went wrong you stare and stare at the code trying to see what you did wrong. Over many years working with 3d systems and Direct X in particular I know that seeing nothing on the screen can mean so many things:
1. Your code is not running.
2. You are drawing off the visible area ie the camera is looking the wrong way.
3. You are drawing too far into the distance.
4. You are drawing a black object on black.
5. Your polygon is invalid, ie two points are the same.
6. You are looking the wrong side of the polygon.
7. The texture is wrong.
8. You are plotting behind the z of the background.
9. You are not moving the drawn screen to the displayed screen
10. Something has drawn over your object.
"It was so much easier on the Spectrum."
So its an elimination game. You can switch off Z buffering , use colours instead of textures etc. With a bit more coding you can get at the data in a texture to check its not blank.
It was so much easier on the Spectrum. If you had a correct screen address and a non zero pixel data you would see a little pattern of dots on the screen. Even now when I think I have mastered the Direct X interface, when I write a new graphic routine I am usually presented with absolutely nothing from my new code on the screen. It is easy to get downhearted. A few weeks ago my player ship disappeared after a code reorganisation. After hours and hours of work I realised it was nothing to do with the code. I had also changed the order of objects in my loaded data files and unwittingly put the sky object after the player. The sky fills the background with a huge polygon on which is projected a sky box. It overwrote everything on the screen including my player ship.
Bit by bit it all came together. I could load and display my form objects with an optional border graphic and background picture. I adapted the Microsoft text printing sample to sample the font texture properly and I could print text in text boxes. I then proceeded with the more complicated controls. They were all derived from a simple base object and all worked to a pattern. Patterns are very important in coding. If you do similar things in similar ways you make less mistakes. The trouble is after about the fifth object I know how I should have done the first and want to rewrite tem all. Hey, that's all in the fun of programming. I am very critical of my own code, always changing my mind , hence the flexible approach, There comes a time though when you have to be strict and stop changing things. It used to be when your publisher leans on you and demands the beta copy.
It was time to get my first graphic on the screen. I searched the internet for a nice 3d Studio model and find a dwarf warrior that looks suitable complicated. I was familiar with 3d Studio models having an old version of 3d Studio. I adapted some input routines from the internet to read the 3d format and convert to my custom model format. Eventually I got the first model into my testbed and showing on the screen. The model had thousands of polygons but that is what I needed. It would make me write efficient code handling all that data.