Conceptual: Stargellas Revenge

Premise

You take on the role of Stargella, a lonely star fighter pilot just returning home to the beautiful world of Freyja0 after a long patrol in deep space aboard the carrier ship Hofvarpnir1. Sadly in your absence, the evil Viekasiekian Empire has begun laying waste to your luscious planet! Deploying all fighters, as a group of imperial Triremes2 begin encircling the carrier,  the tides turn in the enemies favour. Soon you find yourself the sole survivor to reach Freyja alive, as all remaining hands go down with the Hofvarpnir.

Far from fearing a single star fighter in their midst, you must exploit that Viekasiek pride in order  to liberate your planet from the clutches of Emperor Zurick. Battling across the polar ice caps, over the sea, and into the forests of Freyja, you must push the Viekasiekian forces back into space: facing hordes of enemy fighters along the way. Among these include the heavy Ballista and Scuta, as well as lighter Velites3 and scout pods that make up the invasion force. Finally punching through the fleet in orbit, for a final show down against the emperor.

Game Play

The game is meant to be played in a 2D-esque top down point of view, utilising the mouse to manoeuvre across the screen. At it’s heart, is the intention to keep the action alive, blending an array of attachable/ejectable weapons and combat styles with a large amount of adversaries. My idea for a game, you can play additively as an arcade classic but with a pace that better befits the modern style. It’s aimed at folks like myself, who can still sit down and play Centipede or Tetris all day long with a grin, but would like a bit more spice.

It is meant to be more or less, ‘traditional’, in the sense that power ups drift across screen to be collected, and fairly simple on the graphical spectrum.

Current specs call for about 11 enemy craft and 3 more usable by the player5. The players ship is basically given a capacitance based on its size: larger equals more guns and harder to kill. Depending on the class of ship5, will also limit its ability to bring that heavier ordinance to bear upon the Viekasiekian slime.

  • The light fighter given at the start, being designed as a simple but agile craft, is meant to reflect an association with nature. It is obviously limited to only a few weapons because of its small size, but has a regenerative armour skin around a highly effective power plant, that makes for a long lasting craft with some serious skill. It gives extra advantage to players focused on not getting hit all the time, and favouring a few lasers backed by a heavier weapon for dispatched more powerful foes.
  • Medium class, being a more conventional ship of the line gained after a a certain amount of game play. Trading the lighter vessels regenerative skin, for a deflector shield and larger weapons bays, every hit on the shields will reduce the power available to laser weapons; thus off setting the greater capability to carry heavier missile and cannon than smaller craft. It’s meant to be a middle of the line way of playing, that rewards those who can balance its abilities during furious combat and still come out on top of the scrap heap.
  • Where as the heavy class, is basically the big bruiser of the bunch. It’s meant to be an unlock for scoring a good bit of points during the course of play, yet still balanced enough so that even the light fighter from the start can still stand a chance at winning the same fights as the heavy. Combing a large weapons payload with enough armour to last a while, it makes up for needing ‘armour patches’ during a long engagement, by being able to smash through anything that can’t kill it. Think about a dump truck turned into a war marchine lol.

 Weapons can be equipped when found, or jettisoned to make room for others. The hit list includes various strength of laser, that balance energy use to power consumption<6, as well as several class of heavier particle beam and ballistic cannon style weapons. My favourite being the missile types, hehe.

Each ship can only carry X slots in weapons with so much ammo, so one has to balance out what you have collected, when it’s fired, when it’s dropped, and do it all tactically during the regular course of game play. Weapons come in several principal varieties based on the kind of ammunition they utilise, making it simpler for the player to calculate a weapons value in the present situation.

  • Energy
    • Drains part of your energy gauge with every shot, but other wise never runs out of ammunition.
    • Types:
      • Blue Laser
        • Low output for short range combat, aimed to minimise energy drain whilst dealing with cannon fodder.
      • Green Laser
        • Typical energy weapon offering moderate damage to energy consumption. It’s a staple weapon but lacks serious punch.
      • Red Laser
        • Packs a hard punch but requires plenty of energy for each shot. Best suited for destroying targets that you can actually hit.
      • Particle Cannon
        • Fires a stream of charged paricles, consuming a large portion of energy in exchange for a solid knock down punch. It’s the plasma cannons younger brother ;).
      • Plasma Cannon
        • Very powerful but sucks up energy like a thirsty vampire. Ideal for quickly dispatching Viekasekian scum.
      • Overcharger
        • Drains all available energy and unleashes a devastating shock wave, dealing a proportionate level of damage to anything caught within the waves radius. A weapon of last resort!
  • Missiles
    • Uses up so much missile ammo per shot, but only a nominal amount of energy drain per firing. Some offer a form of lock, fire, and forget capability.
    • Types:
      • Micro Missiles
        • A small cluster of homing missiles, that gives chase to any craft in their line of fire. Not very powerful but amazingly handy in a brawl.
      • Heavy Missiles
        • Less intelligent than micro missiles, but capable of dealing strong damage to watever it manages to hit.
      • Spread Bombs
        • The tactical nuke of your arsenal. It fires straight ahead and explodes, dealing massive damage to anything within its corona. Best used as a weapon of last resort or against a tight group of enemies.
      • Zip Mines
        • Explodes a small zero point charge whenever a craft comes within a short radius of the “Zip” mine. They gradually float off screen, making it hazardous to player and enemy alike. This is your only rear firing weapon.
    • Shells
    • Requires “Shells” for ammunition and packs a strong wallop with low energy drain.
    • Types:
      • Auto Cannon (AC)
        • a
      • Rotary Cannon (RC)
        • A multi-barreled, large bore Gatling gun. Fires less powerful shells than the AC, but offers a more rapid rate of fire. Can quickly burn through smaller craft and shells alike, but it also jams with frequent use. Fire it in short bursts.
      • Cluster Cannon (CC)
        • In effect, a giant shotgun. Deals massive damage to anything up close but is practically useless for more distant targets.

Technical

Stargellas Revenge in it’s own right, is only the equal of about 6-12 months worth of coding, leaving most of the effort to graphics creation. An early prototype was built in C++, around SDL for graphics and Xerces for data serialisation tasks. Soon however, I realised that it would be worth my while to make it more general, so that much of the games insides could be redeployed for other game projects7.

This makes the game much more time consuming, particularly when you consider its a ‘side’ project, but the advantages are worth the delay. One reason I like it, is it allows me to flesh out the systems resource, multiplayer, AI, and various other infrastructure tasks without having to do it while coding around a much more complex game.

Most likely, it’ll be the test bed for a custom rendering system8 focused on stressing the API. The overall design of the games internal, is designed to be pluggable9 enough to allow easy access to some very professional strength rendering technologies, as well as being able to hot swap as much of the componentry as needed. Thus allowing the graphical quality to be reduced on systems where the better tools, are sadly, unavailable… without having to give up on them where so available10. The main reason for this being, I want to be able to play Stargella on my laptop11, as well as the 3D games on my desktop!


Footnotes:
0 Freyja is a goddess in Norse mythology, associated with attributes appropriate for describing Stargellas home world.
1 Hófvarpnir another reference to Norse mythology.
2 The triremis being a type of Roman warship.
3 These are all references to Roman military weapons and armour. In particular watch out for the Celeres defending Zurick.
4 It’s a fairly consistent theme, that names of Viekasiekian fighters stem from the Roman military, where as those assoicated with Stargella, have roots in Norse and Germanic mythologies.

5 Will probably be named after Valkyries.
6 Blue = low drain / damage; Green = medium; Red = kick ass and slurp power.
8 Think W3D level of complexity rather than COD6 graphics, but than again, this is a game inspired by games built during the 1970s.
9 I only intend to do OpenGL for most things, doing an equalivulent in DirectX 9/11 is left as an exercise to another geek, or a bored weekend.
10 You can have very high quality graphics under Windows NT, GNU/Linux, and Apple stuff: but FreeBSD is rather lacking in ease of deployment for games :-(.
11 FreeBSD.

Ugh, it’s been a long and unpleasant day! Never the less, I’ve almost got the MSVC builds sorted to where I want them. Basically why unix builds are shared libraries and windows builds are static libraries, has to do with the respective linkers.

At least on FreeBSD i386, the (GNU) linker doesn’t complain about the common and sys modules referencing one another, you could say it has more of a view that the shared lib is a chunk of code and all is fine as long as it all resolves enough in the end. I generally prefer dynamic linking over static, although I have nothing against static libraries internal to a project; when it comes to Windows  however, I’m particularly found of Microsoft’s SxS technology.

While the GNU stuff on my laptop is hapy enough to obey, the link tool provided by MSVC however, won’t cooperate with that model of behaviour for shared libs (DLLs), only static libraries. Other then the increasingly becoming stuff that belongs together, the common and sys modules were merged into a single ‘core’ module, and tonight, prepped to better handle compiler specifics as well. Secondary is that, simply put link makes shared libraries a bit more typing then need be. Every other sane OS/Compiler pair I’ve encountered, has the lovely habit of assuming that you wrote a function in a library, and might want to share it with other programs. Visual C++ on the other hand,  presents several ways of doing it: that all basically amount to telling the linker which things an application may slurp up from it. Basically resorting to writing a “.def” file, or in wrapping up function definitions with a __declspec(export) attributes, and the correct __declspec(export) or __declspec(import) attributes at their declarations.

Microsoft’s way of doing things is more flexible, but one might fairly argue that the inverse behavour (e.g. export anything not specially marked) would have been better.

Generally I like MSVC, I think it’s better then GCC, if you are willing to put up with the major lack of C99 compliance and lack of stdint.h (I use one written by Paul Hsieh). The main downside is the tools tend to be a bit, eh, stupider then GNU brew, and the best parts of the system are like wise fairly specific to both MSVC and Windows NT. Personally I would enjoy a professional edition of the MS’s offerings, because it would net access to their 64-bit C/C++ compiler and much stronger profiling tools, that are simply missing from the express editions.

The sad part, is that Visual Studio is the only software package I have seen Microsoft release in my entire life that, that’s worth buying…. lol. Not even their operating systems can say that much, from where I sit.

Overloaded and still bit shifting

Ugh, I’m freaking tired. Started the day off computing what changes would be needed for setting up nmake based builds of Stargella, and everything has been on a snow ball since then.

I spent a considerable amount of time cursing at the MSDN Library over some very shotty docs, and realising that despite the overall quality of MSVC, the actual build tools behind it, has to amount to the stupidest ones I’ve ever seen. Although to be fair, the very first C compiler probably was worse, but this isn’t the ’70s :-P.

The depreciation of Code::Blocks for building things, and switching to appropriate make systems should mate more smoothly to my work flow. It also pisses me off that after all these years, the best tools for the job haven’t improved much. Unlike the typical morons^H^H^H^H^H^Hprogrammers I’ve had to suffer, I also know how to cook up a build set that shouldn’t be an almighty pain in the neck, just to use on another computer then my own work station. Applying basics of computer science to software construction, many hours; having to use tools that quadruple your work load, priceless!

As soon as I battle test one last makefile for MS’s nmake, all should be ready for committing to the repo. Then I can worry about the next goal, a proper merge of the common and system modules into a central core, shuffling the Windows builds to using DLLs (to match the unix builds), and integrate PCC into the unix build stack. (For ease of compiling dependencies, only MSVC is supported on Windows: MinGW users are on their own).

During the course of the day, I’ve also done plenty of the server admin loop, and have serviced more interupts today, then my processor sees in a week of abuse.

and all while carrying on several conversations, hahaa!

Bug smashing on the stack, hehe

Ok, I’ve spent some time longer then expected working on my games net code, mostly because I both needed one nights sleep this week, and wanted proper IPv4/IPv6 support going on. Sunday I basically finished principal work on the net module, and completed a pair of test cases: a really simple client and server program. After that went smooth, I had planned to complete the finishing touches.

The problem: the server example segfaulted. Now those who know me, I consider it a plight upon my honour as a programmer, for any code that I’ve written to crash without due cause (i.e. not my fault). So I spent work on Monday taking a break: refining code quality and then porting it from unix to windows. During the nights final testing runs after that however, I had not solved the mysterious crash yet, and got the same results. I switched over to my laptop and recompiled with debugging symbols, only to find that my program worked as normal, only dying with a segmentation violation once main() had completed, and the programs shutdown now “Beyond” my control.

My first thought of course, was “Fuck, I’ve probably screwed my stack”[1], a quick Google suggested I was right. I also noted that turning on GCCs stack protection option prevented the crash, so did manually adding a pointer to about 5 bytes of extra character data to the stack. Everything to me, looked like the the return address from main was being clobbered, or imagine invoking a buggy function that tries to return to somewhere other then where you called it from. Before going to bed, I narrowed it down to the interface for accept(). Further testing showed that omitting the request for data and just claiming the new socket descriptor, caused the crash to end but still, some funky problems with an invalid socket. Inspection of the operation also showed that the changes were well within the buffers boundary, yet it as still causing the crash. So I finished the remaining stuff (i.e. free()ing memory) and went to bed.

Having failed to figure it out this afternoon, and starting to get quite drowsy, I played a trump card and installed Valgrind. It’s one of those uber sexy tools you dream of like driving a Ferrari, but don’t always find a way to get a hold of lol. For developers in general, I would say that Valgrind is the closet thing to a killer app for Linux developers, as you are ever going to get. In my problem case however, Valgrind wasn’t able to reveal the source of the problem, only that the problem was indeed, writing to memory it I shouldn’t be screwing with o/.

So putting down Valgrind and GDB, and turning to my favourite debugging tool: the human mind. It was like someone threw on the lights, once I saw the problem. Man, it’s wonderful what a good nights sleep can do!

Many data structures in Stargella are intentionally designed so that they can be allocated on the stack or heap as needed, in order to conserve on unnecessary dynamic memory allocation overhead, in so far as is possible. So the example server/client code, of course allocated its per socket data structures right inside main(). Because there is no real promise of source level compatibility between systems, the networking module is implemented as a header file, having function prototypes and a data structure representing a socket; which contains an opaque pointer to implementation specific details, itself defined in unix.c and windows.c, along with the actual implementations of the network functions. Because of that,the behaviour of accept() can’t be emulated. Net_Accept() takes two pointers as parameters, first to a socket that has been through Net_Listen(), and secondly to another socket that will be initialised with the new connection, and Net_Accept() then returns an appropriate boolean value.

All the stuff interesting to the operating systems sockets API, is accessed through that aforementioned  pointer, e.g s->sock->whatever. What was the big all flugging problem? The mock up of Net_Accept(), was originally written to just return the file descriptor from accept(), allowing me to make sure that Net_Listen() actually worked correctly. Then I adjusted it to handle setting up the data of the new socket, in order to test the IPv4/IPv6 indifference and rewrite the client/server examples using Net_Send() and Net_Recv(), and that’s when the crashes started.

I forgot to allocate memory for the sub structure before writing to the fields in it, resulting in some nasty results. When I say that I don’t mind manual memory management, I forget to mention, that programming while deprived of sleep, is never a good idea, with or without garbage collection ^_^.

Now that the net code is virtually complete, I can hook it into my Raven Shield server admin tool, which will make sure to iron out any missing kinks, before it gets committed to my game. Hehehe.

My games net module is almost complete under unix, and in theory should be able to handle both IPv4 and IPv6 communication fine; not that I have much to test the latter with. Windows support will need a bit more tweaking, and then it’ll be possible to plug it into my Raven Shield admin quiet easily.

Pardoning interruptions, I’ve spent about 6 hours of my day working in straight C, followed by about 15-20 minutes for a little rest. For some sickening reason, my weekends almost always fall into the category of working all day, eating dinner, then working until dawn lol.

Doing things in C, I find more time consuming then more dynamic languages, chiefly because of how much testing I (try to) do, coupled with how much lower-level stuff one has to keep in mind. Having to deal with memory management issues, is not a problem for me, although I do admit that garbage collected languages can be very enjoyable. To be honest, I find the portability problems of doing anything interesting, to be a greater drawback then managing memory; e.g. by design Python is not very portable in comparison to C, but it more then portable enough for anything you’re likely to bump into on a PC, and can do ‘more’ with less bother, for an acceptable level of portability. They are very different languages at heart, and their designs reflect it strongly. A lot of people (including myself) call Cs portability a myth, and it is in the sense of what most people want (especially me), I doubt is possible without a more modern rendition of the language (NOT Java or C++). Where C truly excels at portability, well I reckon you’ll just have to study more assembly language to understand the value of it.

Now if only I had something better to do, then spend all my time behind a computer screen, monkeying around with GCC on one side, and MSVC on the other 8=).

In being dragged across the grocery store yet again! I spent some time contemplating what I was thinking about last night, as I was finishing up part of my games net code. Wouldn’t it be practical, to just implement a simple Virtual File System? It would make adapting the code base to different uses easier, since pathes and I/O could then be defined through a set of VFS_routines, but on the downside, making it pluggable would push greater overhead on all those I/O routines at every use.

The zpkg, system input/output, and network modules present very similar interfaces. Main differences being that zpkg doesn’t have write support (an unneeded non-trivial feature), and seeking between positions in a socket, just doesn’t make the same sense as with local files. If a virtual file system layer was built on top of it, it would be rather easy to define a “Plugin” data structure providing the necessary function pointers as needed, and simply use a hash table to handle the mappings between paths. Of course that leads to the bugger of a look up operation o/.

Really, most of the places where it matters wouldn’t impact game play, since most I/O can be divided between startup phase, loading stuff, client/server communication, and shutdown phase; the chatter between client and server obviously being implemented directly on top of the networking module, and therefore a moot point. It would make it possible for the resource loading code to become more flexible at run time; i.e. being able to load game assets both out of zpkg files and local system files without a recompile or a  restrictive version of the VFS.

I think it would be worth while, as an added plus, it would even allow splitting the path argument to Zpkg_Open, and pulling out the interesting bits into the VFS adapter function, which would be replacing that feature of the zpkg module.

For today however, my primary goal is to port the networking code (almost) completed last night, from the BSD Sockets API over to the Windows Sockets API. That way I can replace the less appropriate network code in my RvS admin program with it, and save having to complicate its design to make the most of Qts networking API. All while improving my games code base ^_^.

Although WinSock was based on the old Berkeley interface, Winsock has arguably grown more over the last decade, then the Unix interface has over the last 20 years. Not that there was much need beyond adding IPv6 capability, which the common Unix interface already grew ages ago. I personally dislike both the Berkeley and Windows interfaces immensely, why? Because in my humble opinion, the proper way would have been something like:

int s;

if (s = open("/net/tcp/host:port", O_CREAT | O_RDRW | O_EXLOCK)) == -1) {
perror("Unable to open a connection to host:port");
}

/* do usual stuff here, like read() or write() */



where /net would be an arbitrary mount point for a special file system, in which file system operations reflect their corresponding network operations. Flags for system calls like open() and fcntl() could have been suitably extended to cope, and others like accept() implemented as needed. In the light of things like FUSE, it would be even more interesting to do it that way today, then it would have been in the 1980s.

Instead of that simple form, whenever we want to create a socket: we have to setup suitable socket-specific data structures, which and how many depending on the operations to be conducted; common practice is to zero over the most important (sockaddr_in / sockaddr_in6) structures before using them, and leave it to the compilers optimizer whether it actually happens at run time; look up in the system manuals what pre processor definitions correspond to type of network connection we want (let’s say TCP over IP) for the socket() call; initialise the field structures, using the same pre pre processor flags, and even converting details like the port # into suitable formats, all by ourselves. After which we might finally get around to doing the socket I/O ourselves, pardoning any intervening system calls needed for your particular task.

/*
 * Assumes open flags in previous theoretical example corresponded to a connect
 * operation, rather then a bind() and listen() operation. Like wise for the
* sake of terseness, I'm "Skipping" support for real.host.names rather then IPs.
 */

int s;
struct sockaddr_in addr;

memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (inet_pton(AF_INET, "xxx.xxx.xxx.xxx", &addr.sin_addr) != 1) {
/* handle AF_INET, address parsing, or unknown errors here.
* error is indicated by return value.
*/
return;
}

if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("Unable to create socket");
goto CLEANUP;
}
/* use system calls and a data structures as needed to setup things as desired */

if (connect(s, (const struct sockaddr *)&addr,
   sizeof(struct sockaddr_in)) == -1)
{
perror("Unable to connect socket");
goto CLEANUP;
}

/* do I/O here: send/recev, or read/write */

CLEANUP:
shutdown(s, SHUT_RDWR);
close(s);

I reckon the Berkeley interface was the right choice, for portability between systems (including non-unix ones; making it easy to write stuff like WinSock), and probably easier to graft onto the 4.3BSD kernel, but it’s damn inconvenient for a UNIX programmer. That ain’t changed after about 25-30 years.

Oh wells, at least it works pretty darn near every where, give or take a few kinks.

Feeling inspired

As always I’ve got plenty of loops open, always have, probably always will… I hate sitting idle. While I like time for R&R, I prefer to stay fairly busy. Right now I’m focusing on

I feel inspired in a way, to throsh along with work on my game projects, it’s been a bit since I’ve had time to work onit, but the SYSIO sub system is almost complete, once that’s done, I’ll try to unify the ZPKG and SYSIO interfaces and work on using DevIL for texture loading code. When I pause for a moment and think about the sources before me, I can see what it could become, and all I need is the time and strength to do it.

Today I also thunk up the most perfect unit test for epi-sum, and one monster data set to test an internal library against. Overall, our EPI implementation isn’t designed for to compete with C/C++ runtime speed, in fact, language selection was chosen with it as an after thought. The thing is though, while it still can keep pace with stuff like apt-get or PBIs, I want it to be faster then any valid competition :-D. It’s also good geek fun to see where algorithms can be adjusted for savings. An extra bonus, since the ECA code is under a BSD style license, I can also ‘barrow’ the best parts for other projects, hehe.

When it comes to optimization, I generally “Skip it” whereever possible, and I rarely use the corresponding compiler flags either. The place where I focus my attention on, is doing things in a good way: data structures and algorithms that fit well, solve the problem, and that scales with it. You could say, my focus is on finding the best solutions that don’t shoot you in the foot, nor complicate trying to understand wtf the code actually does. If a real bottleneck enters the picture, then I dig into the code monkies bag and start fine tuning things.

The price of pissing me off.

A word of warning, this post contains quite a bit of profanity after the jump break

After being up until well past 0400 last night, setting up a decent SCons build set on FreeBSD, for testing— its usefulness to this project. I started setting up the required config tweaks today on the Windows machine.

When suddenly, I found a odd difference between how the same SCons versions behave on FreeBSD/unix and Windows, in fact, this kind of thing is why I’ve given up on the more popular CMake.

lib = os.path.join('#', outdir)
#
# For some really mother fucking stupid reason, Glob('*.$OBJSUFFIX') works
# on FreeBSD scons 1.2.0_20091224 but not on the Win32 scons 1.2.0_d20091224
# from the installer. So we have to use this fucking method, which will require
# us to wrap it in exceptions in case OBJSUFFIX is None or missing totally on 
# platform X.Y.Z. from fucking hell -- I fucking hate software build tools.
#
src = None
try:
    src = os.path.join('#', outdir, '*'+str(env['OBJSUFFIX']))
except:
    print("Fatal error: I can't make libs from object files without a file "
          + "extension. TERMINATING THIS SCONSCRIPT")
    import sys
    sys.exit(127)

env.StaticLibrary(lib, Glob(src))



# edit: an explanation of why subst() isn’t used in place of the [] look up: once you violate the consistency part, I’m not going to trust that there will be an $OBJSUFFIX to subst() on.

I was going to make most of this code a simple library function for the sake of code reuse, instead of having a virtual copy/paste of the same few SConscript files between all my games source modules—after this, I’ll stick to having one of those comment blocks in each source modules SConscript file as appropriate.

Generally I like SCons, it’s rather similar to what I’ve invisioned as the “Perfect build tool”, even though SCons still requires about 3 x the amount of work for Stargellas build system then tmk should. However, SCons is here today, tmk won’t be for a long time. What annoys me, is that SCons is still just as bad as all the other build tools out there.

For crying out loud people, it is the year twenty first fscking century…. and asking some consistency of our modern build tools, still demands limiting ourselves to the 1970s era make tool from PWB/UNIX.


Being stuck with walking around the supermarket (baah, humbug!), I tried to devote my trains of thought to Stargella. For me, it is kind of a difficult project; much more complex then most of the things I’ve worked on.

In thinking about how to structure the rendering code, I started to think more on the issue of dealing with the data sets to be rendered, which basically means sprites (2d), models (3d), and rendering the level (2d/3d), and I want as much of the code to be shared between several game projects, which makes baking the lasagna a bit involved. Since my current focus is on the 2D oriented, Stargella, I find it wiser to concentrate on sprites then three dimensional models. At first I was thinking, it would be ideal to represent animations for sprites, as a simple image stack; but I don’t want to go through all that for unanimated sprites, which would still require a singular stack frame. The fix to that is simple, only use stacks for holding the animation details! Then I was thinking, gee, wouldn’t it be cool, if we could attach some type of script or shader program to be run, so a level of progmmability could be used in implementing special effects. For example, using program to stake out the centre of a starship, split it into segments and have them drift away from one another, while interleaving it with an explosion-like image or particle effect. Simple enough to do from C I’m sure, but I would much rather have it be apart of the game data, then the game code. I’m not sure if that would be doable from mating with GLSL files, or if it would mean binding a script with the sprite. Either way, as far as general game scripting goes, it should have some level of access to the graphic stuff as a matter of completeness.

For now, I think I’ll concentrate on resource handling. It should be easy enough, just create dynamic arrays as needed (e.g. of loaded textures), and each time a new texture is loaded, assign it an unique identifier that indexes into the array; …

Honestly, I don’t have a problem with programming in C, other then it can be time consuming at times o/. But, because I have to learn OpenGL along the way, it is, shall we say a freaking lot of docs to parse.

While I’m more familiar with Direct3D then OpenGL, even if you can still get a good bang for you buck out of a DirectX SDK without having to stoop to C++, I’m not willing to write a DirectX backend for my game. Obviously, I want to avoid using glThis and glThat all over the game code, but ahem, the issue of shaders enter the picture. Short of making a definitive choice at compile time, that would have to live for the projects entitiy, the only way to support runtime choice, would also require writing both HLSL (DirectX) and GLSL (OpenGL) code, and that’s a headache I won’t put up with!  As much as I favour the idea of nVidia’s Cg, it is not available on enough platforms, and implementing it where needed, to much trouble.

If people other then me want to play the game, they can buy a graphics card made in the 21st century and install its drivers >_>.

—- this post has been interrupted so many damn rat fucking times by family, that it is unfinished and will likely always remain so. This is one of many reasons why I fucking hate my life.

Ahh, Stargella moves foreward

I’ve just made a forum posting, starting an open query for any artistic talents interesting in helping to contact me. My main concern at the moment is working out the games design bible while finishing off the Georgia drivers guide >_>.

Most of the code for Stargella is going to be reused for the later first person shooter and ‘mech projects (which may just get released years before the new MechWarrior lol). While the shooter is going to be a 3D affair, and the ‘mech combat game is undecided, the star fighter game (Stargella) is fairly straight forward: 2D is the only way to go. At least without getting sued for recreating Star Fox, if I dared try it in 3D lol. At its heart, Stargella is about having fun, the kind of fun that existed before the move into 3D games. I largely missed the big classics like Battlezone and Asteroids, only getting to play them in later years, but Galaga was a game I did play as a child. Its always been something I’ve found missing, no modern incarnation I’ve had access to just itches the right spot, that’s where Stargella comes in: it’s gotta be fast and furious, like an nail biting round of Centipede. Yet it’s got to something you can actually play and survive with some mastery, like Asteroids (one of my great favourites btw). Most of the games I played growing up, were side scrollers like Super Mario Brothers and Sonic the Hedgehog, so I remember the mechanics quite easily.

Graphics are my achilles heel however, because while I can code what I want, making it ‘look’ that the way I want, is limited by the models that can be created for the game to display. In fact, I’m actually thinking of drawing most of the ships for Stargella, and scanning them into the computer. Really it has been a long time since I’ve done free hand drawing, it feels more natural to me then the computer: I can work FASTER!!!

For Stargella, I very much know what kind of look I want, the question is can I get graphics that match it without the whole thing looking like the early arcade games, lol. I reckon that I could always hash things out in a modelling program and get a head start on code needed for the 3D titles, but I feel that is just over kill for a game like Stargella.