Wednesday, May 13, 2020

Task Music

More work on Taskforce today. I've written lots more music for it this time. There are separate tracks for different events in the game; the start of a mission, the end (with victory), the end (with failure), a background track, a track when you have one unit left (perhaps sad, desperate music), a track when the enemy has one unit left (the verge of victory), a track when you've completed your objective and must get to the exit (excitement?).

So, lots of possibility. I've currently got 21 tracks written, but with 32 missions and up to 7 tracks per mission, there's an awful lot of options. Today I've written a track called 'spider angst' which, one of the 'sad, desperate' tracks, which is a variation of the main spider theme. The spider theme is actually a rather groovy tune with a simple chord structure like the Bomb the Bass Megablast track (itself a blatant rip-off of John Carpenter). The spider mission is based on a city so I thought that something urban and hip-hoppy would suit. Almost all of the other music is rock-blues, variations on the main theme.

I've experimentally boosted the Sniper Rifle damage to 32, as this seems to be one of the weaker weapons. The Pistol, Carbine, Machine Gun, and Shotgun all feel well balanced. The Knife feels a little weak, but I'm hesitant to make it stronger than the Carbine... it shouldn't really be so, even if the risk and effort to use it is greater... I'm unsure though. At the moment it's the same strength as the Pistol, and, like that weapon, can be used one handed, yet the Pistol always seems to be a better option as it can, at least, shoot (well, you can throw the Knife) and it only takes 20% Action Points to shoot it at close range; the Knife takes 25%.

Tuesday, May 12, 2020

Leaps, and Bounds

Compared to the previous day, yesterday was brilliant; I managed to create new 'door' system for the game in 90 minutes, about as fast as possible. Now doors are simply blocks which are swapped when opened. I'm sure this is how it worked in Hilt II, and it certainly simplifies things. I've also fixed lots of graphic problems, little things due to the look of certain objects. I spent a few hours yesterday editing all of the 30 or so maps to set them in line with the new block format.

I'm gradually getting tired of this project, after 6 or 7 weeks of non-stop work, certainly no more than a 90 minute respite in that time. I can't waste too much of my life on it, yet, I am pleased with the game. The new graphics system is now in and appears to work. Andrew's highlighting of the old, flawed, graphics system, and certainly his idea of shatterable windows, have really improved the game in ways that wouldn't have been done without his help. Here is a look:

Any blocks are now wholly shown or not, rather than shown in faces and fragments. The visible parts, like the walls, are effectively hollow tubes, which is necessary for efficiency (no point in showing internal walls) and also neatness, as these would show dotted lines on the joins otherwise. It is this that's taken me all week and needed the creating of the 400-or-so new graphics.

It was a far bridge; and it looks like I will not now make the deadline for a public demo, so Taskforce will not be part of the Steam Summer Games Festival. Even if I rushed through a public demo today (I really need a week of testing it before such folly) it would probably not be approved by the Steam team in time. The Fest might also disrupt the launch of the game so I might put that back until July.

Today I've created some new windows which can't be shot through, just in case I need them, and made windows flagged as 'indestructible' in the maps refuse to shatter. I've tested a few levels, created the new Teuton Arcanum logo for the soldier's backpacks and tweaked many settings - I made the armour thinner for units too as units can be hard to kill. The thing about this is that the computer soldiers and yours are identical, as are the weapons and damage system, so if they are easier to kill, so are you. The only difference perhaps is then the relative strength of your troops vs. the other enemies in the game, but it will take less shots to kill soldiers now... so that might pace up the game a little.

I wanted to get fire to spread down and up stairs too but it wouldn't work as expected... it seems to spread too far. It's easy to toy with things here. I could spread smoke in upper floors, for example, but I'm hesitant to start tweaking things now... 16 years since the game first appeared.

Today is the first quiet-ish day in about 10 days during which I've not left the house and barely left this room. Last Wednesday and Friday in particular were about 14 hours long with only 30 minutes snatched here an there. My enthusiasm is boundless but I need some sort of rest now. I barely slept last night and had strange nightmares about being distant and alienated by friends and family when I did.

The Steam Festival deadline forced me to push hard, but I can't make that, so now I'll need to impose a new deadline to stop myself working on this forever. On we push.

One day, I will feel like an artist again rather than a computer slave.

Sunday, May 10, 2020

Mountains

Today has been one of the longest and most arduous and frustrating days of programming I can remember. I started with doing something with the sprites. I failed to find a good way to find a local function pointer. I'm sure it's possible but I just gave up and used a switch... this sort of thing is about the alchemy of the language and it's something I've never done before.

The hard part though was what I expected to be the easiest. I started by adding the code to hide or show adjoining walls to blocks, very simple logic, and this just refused to work. After a lot of experiments, mostly hiding north and south walls, revealing the east/west ones which should have been culled, so I could peer inside, I decided that the map was expecting a block to the right or below (east/south) that wasn't there yet but would be, so I reverted to using 'discovery' rather than 'visibility'. Visibility is whether the block is actually visible, and discovery is whether your team has discovered it, so that is a bit-mask...

That was after I realised that I was checking the block bit-mask rather than the block type/class bit-mask, but I digress, after an hour or two I started to add a new part to add new walls when some were revealed by explosions or other block changes, then I realised that the discovery problem wasn't that at all. I could sense the 'top' code sniggering at my attempts, because all I needed to do was emulate it. Eventually I got it working, but then realised that, like the 'top' code (the code for rendering the tops of blocks which had been there for years) I really needed to either delete or restore the faces of neighbouring blocks there and then, so it would update based on neighbours, and their current visibility or not is not important: if they are visible now, they and all of their visible neighbours will be correct, and invisible ones will be corrected when shown.

The code looked really messy by this stage because the blocks knew about their place in the world via ugly global coordinates which needed to reference a global level object. What I really needed is some simple pointers to neighbours; north, south etc. and as it happens, this is what the above and below blocks used to have for, yes, the 'top' rendering, but I deleted them, wanting a more global view. Bah!

So, at 4pm or so, I added these pointers back, restoring and simplifying everything into simple lines. Then; it all crashed. I just couldn't get the game to run past the equipment screen. I flagged everything new off and it still crashed. I was in a panic. I couldn't remember what I'd switched on or off or why... so I followed standard procedure: keep turning off until it works, then gradually turn on until it doesn't.

I traced it down to the 'top' printing, something that worked fine a week ago and has been stable for years... I couldn't work out why. There was a possible null pointer, but that should never, it seemed, ever be null. But it was. I made it print when it was... and where. The numbers traced the outline of the equipment screen map... it took a lot more tracking, over an hour, to find that the map was erased from the bottom up, which nullified the pointer below. The thing is, that should have always happened, for years... I just could not and still cannot work out why it ever worked before!

After that, I had pointers to the six faces. It was relatively easy to put everything in and it looks much neater and is much easier to read too, and no nasty co-ordinates. The only downside is the doors... the tiny 1% that is causing a problem.

The doors, for some reason, are not merely two blocks, but one with an open/closed switch. This causes all sorts of sillyness; the doors have to change height from 2M to zero whether open or closed, and change opacity, and many of the class level descriptions of them need to be local just to allow them to change this stuff... all annoying... it's not like the doors even look like one block or have any fancy effects... they just vanish and, visually, appear to transform into a floor. I don't know why I did it that way. Perhaps, I will find out because I must now change these because the status about occluding side walls is too big to be made local; that (like height, really) needs to be class-level information. I think a new structure is needed for doors, merely a two pointers to two block types for open and closed. That should be enough for any door switch to know what to do.

At least now, I can accept humility, and expect that this job, an hour at most, 20 minutes if lucky, could take all day or more... but I have to do it. It has to be as good as I can. It has to be right, bug free, perfect, with every part doing exactly the correct thing. Every error or anomaly is ruthlessly traced and understood in its entirety. This is why programming drives me crazy.

Arduous Texturing

A few of the longest and most tiring days I've ever spent programming. I'm desperate to get my new graphics system into Taskforce, and began by modelling the 300 or so objects and tiles in the game, splitting these into faces as appropriate. The point of this is to split each object into main, north, east, south, west, and top parts so that anmy can be switched on or off as needed. Here's a window in development:

This has taken two and a bit long and intense days without pauses, and now I have 456 newly textured 3D objects, all ready to include. Most of yesterday was spent checking and experimenting. Each block has a lot of extra data: its height, the names and locations of each of those face 'faires' (I call my classes of sprite fairies, a nod to the elfen nomenclature of these computer objects), and lots of flags to tell the game about the object, such as whether you can see past it ('yes' for floors or windows), walk past it ('yes' for floors, not walls or sharp objects) and other things.

There were about 100 or so errors of all sorts, accidental typing errors, incorrect texture numbers, missing or wrongly placed faces, confusing east and west or north and south etc. This testing and correction is an important phase.

The key word about the system is occlusion. If an object, say a full block, occludes the block to its east, then the west face of that east block is not printed. For plain walls this works great. For windows or thin objects, they can't really occlude their partner because this might switch off the bigger face for something like that wall, but ideally it should occlude the identically sized window face. For windows it hardly matters but for the large concave sewer objects, it does because these are big faces and very common in a level.

The solution is to make these faces occlude too, but keep them in specific map areas, so that the windows (or sewers) don't ever touch a face that could be occluded. Sewer walls are closed systems, they only need to touch each other. This restricts and complicates the map design a bit, people suddenly can't put a sewer in a normal wall because it would look wrong, but in practice sewers only touch themselves anyway.

I'll program this today.

I gave some thought to optimisation and created a new class of sprite which is small (just 8 variables), and printed objects that haven't been rotated. This was/is faster but had/has problems. Objects need to be printed in a certain order, from back to front, so that any transparency works. If you print a window first, the program won't later print what is more distant; every point on the screen is sorted by something called a z-buffer to detect exactly that, it's an effective way of avoid printing distant things behind walls, but would stop printing behind windows. Besides, windows are semi-transparent so the thing would need to be coloured somehow. The only solution is to print the background first, but if my new class of object means printing it separately, it has to be printed either before or after the full objects... so no matter how well it works, it won't integrate with them, only, yes, in this tiny special circumstance of windows... but the game does have windows and glass, and really, the soldiers, bullets and complex things like that need to be visible behind windows.

I could keep these faster sprites for text or mouse pointers and other things, but those objects are super-fast to print anyway because they are not transformed. Then I thought of a special class of complex object, just for the flames or particle effects that appear on the top, but even then there are layering issues, and it would mean a lot of detangling with the current sprites.

I could add a switch into the sprites that forces them to ignore rotations, that should speed the printing of the common map blocks (the downside is the speed check of the test for the switch, will this beat the 8 or so multiplications?). I could also, perhaps, remove acceleration... I don't think anything in this game accelerates.

The sprite structures might be large, but a linked list of 90,000 is the same speed to parse no matter how big, and the size, at most, might be 30Mb, which easily fits in a modern computer.

A full day of programming today, and I have to re-map every mission in the game because the block lists have changed. In looks, the game looks almost identical to how it did last week, but the resolution has doubled and all of the textures are new. The game has an always had a very clean, Paul Verhoven, sort of look I'm sure it would look better on a new and fancy screen.

Wednesday, May 06, 2020

Texture Design for Taskforce

This project seems as endless as the Covid-19 saga. It's a strange circumstance that just about the only way I could complete this mammoth task is in circumstances like we have now.

I awoke a 6am, determined to start work at 7am, and the plan worked. This is probably my longest ever day as a programmer, or a painter: 7:30 till 8:00, 30 minute break, 9:00 to 10:30, 30 minute break, 11:00 to 12:30, lunch. 13:30 to 15:00, break for one hour, 16:00 to 18:00, evening meal, 19:00 to 19:55.

Step one of four is now complete, I've designed new textures for all of the scenery. This job is at least as meticulous as it is artistic, probably more meticulous than artistic. I'm designing sheets like this:

These broadly mirror the existing artwork but at double the quality. I have 10 sheets to make, filled with objects from floor tiles to road signs, to book shelves, to wire fences, doors, windows. These are a bit like the 'decals' that I used to float off a sheet when making Airfix models. These shapes will cover every object in the game. This is one of the biggest of the four jobs (applying them might be bigger), but in some ways the easiest, as it involves mimicking what is already there.

Tomorrow, stage 2, which is creating the 3D models that will accept these. The models already exist, but I now need to slice them into 6 bits: one for top, and each of the four sides (if the models touch the sides, that is, if not, then I can leave them).

I thought today of potential problems. Although this is the ideal and best way to render this game, it will involve a huge amount of game sprites, each with hardly any polygons, often just 2 for the floor tiles. Most of the walls have 6 sprites, but again, just two polygons per sprite. This might lead to slowdowns... modern graphics are best with lots of polygons and minimum computer power, but this game demands the opposite because each object is printed after careful thought.

The map is 50x50x6, so there could be over 90,000 sprites active at once (lots more for weapons, soldiers and explosions). That's huge! Each sprite is capable of moving, rotating, accelerating, and all in a linked list. Parsing a 90,000 long linked list might lead to significant delays, and that is done at least every time the screen is printed - more than 50 times a second. This is worrying, but I can take heart from the fact that the game now has up to 30,000, and seems to work fine.

In an emergency I can go back and use the current, inferior looking but working, version. I always seem to be pushing limits. My music software, Prometheus, back in 2002 when I made it, I knew that computers needed 10 years to be fast enough to run it. My 2001 game The Heart of Aorkhan was similarly vast. My PC of the day had no hope of even rendering it (it was a 3D version of my Amiga game Blade, or Hilt, a huge maze)... but I knew that computers would one day. Of course, in my case now, I need this game working next week, not next decade.

I'm now exhausted and will now rest. I haven't finished before 8pm in weeks. Tomorrow will be another long day. I can't wait to see and try the finished game though. To think, I was supposed to be working on the music this week. The public demo will have no music, if it launches next week as hoped.

Tuesday, May 05, 2020

Step 16 of 300

A long and tiring day, but, it seems, the start of many. There was always a serious problem with Taskforce in the way it rendered the scenery. Each map block inherently had some blank spaces, for internal walls, when these simply joined to other walls. Everything works fine like this until you start blowing up walls, then the holes/nothingness there is visible and looks like an error of some sort.

Andrew drew attention to this yesterday, and yes, it looks like a bug and ugly. In effect, it is a bug of sorts, a limitation. Here's one of Andrew's screenshots. The wall is missing like some odd dimensional mirror:

At the time I'd experimented with simply making all walls, even internal ones, visible from all sides but that's very inefficient (rendering things that are not seen) and looks ugly, because polygons should join seamlessly.

I'd always disliked this, but, I thought, it was fast because it was ugly... but even this isn't totally correct, because some hidden surfaces are rendered, and the occasional ugly look was actually very common. In some ways I didn't mind because blow up things should perhaps look mangled, yet, this issue is the one that now bothers me most about Taskforce. Until now I'd resigned to the fact that there wasn't much I could do about it, unless I wanted to redesign the graphics engine.

Yet, my quest for doing things well and aiming for the best option means that today I have decided to redesign the graphics engine.

The problem isn't trivial but isn't that complex either. Most internal surfaces are hidden, but should appear when exposed. So blocks need a series of flags that specify if they cover each of their sides (north, south, east, west). Some blocks, like solid walls, will cover all of that wall, and so the neighbour block there won't need to render that face. Faces can be switched on or off as needed, depending on the status of the neighbour.

Actually, this is already part of the engine, for tops, because the tops of blocks are not rendered if a floor is above them. That caused obvious flimmering (ugliness) so I was forced to deal with it. If only I'd thought back then, I could have made these changes back in 2004.

The offshoot with this is that now, every map block (there are 300) needs chopping up into faces: main (floor/middle), top, north, south, east, west. Only walls really have all bits, and they can be reused, but I don't have those components now... it means a lot of remaking 3D data and a lot of retexturing, which is very slow and tedious on my rather rubbish Visual Basic texturer.

If I'm going to retexture all of the graphics (and I am) I might as well make new, higher resolution textures too, so I'm doing that too. The programming work will be easy once I have these data; these blocks... but it will be several days until I do. Every process is very slow. Fortunately, I generated most of the textures in Genetica, which means that I can render them in higher resolution with a click.

Of the 300 blocks, I've made 16 so far. The first 50 or so are simple floors, so easy to do. Oddly, I split the original floors between lots of weird texture files that has walls mixed in. That's a real pain because it means the new 'inner' blasted walls won't fit anywhere, so I have to change the actual texture layout too.

It's exhausting and laborious work, but at the end, hopefully in a week, the game should look better. Yesterday I felt great, that I was on the home straight for this game, but now I'm at the bottom of a mountain again. On we climb.

Sunday, May 03, 2020

Teuton Arcanum

A manically busy few days, as ever, working on Taskforce. The amount of work on a computer game is immense. It's no wonder that I practically had a nervous breakdown working on it last time, and the work just seems to grow. Yesterday, I almost thought I was near the end, but I still had a lot to do. My main job was to read and edit the main mission text as one, an overall view. After two days, I still haven't done that, but have completed a few other jobs.

I've finalised the lighting for two missions, and developed a backstory for the game. I wanted something with depth and went back to an old idea I had, decades old, for a sci-fi series about some crusading knights (which in my case included a Shaolin Monk) who stumble across an alien computer which they mistake for an angel. Before I got too far into this; this isn't my backstory, but it does involve knights.

The Taskforce backstory is about 'Teuton Arcanum', or to give it the full title: 'Teuton Arcanum Special Knight Force', a secret society of knights which are a bit like the Freemasons but with a central base of operations and a military wing. The story goes as follows:

It is the 9th century, and Charlemagne, keen to spread culture and preserve his new Holy Roman Empire, creates an order of elite guards to protect his new great library, a cultural archive as extensive as the Great Library of Alexandria, and replete with holy relics and treasures. This organisation is called Teuton Arcanum, and consists initially of nine knights. To this day the organisation is administered by the 'Nine Unknown Knights'; unknown because even the nine do not know the true identity of the other knights - historically they would wear full plate armour during the meetings. It is an independent secret society which seeks and recruits the best of humanity to help the world and preserve order and global culture, a sort of chivalrous fraternal organisation.

The order is known as the Teuton Arcanum Special Knight Force, or Taskforce, and after being initially based in Aachen in Germany, and then St Gallen in Switzerland, is now based in an underground city beneath the Swiss Alps called 'The Cathedral'. Each of the Nine Knights controls a different department:

1. Military is the one the player commands in Taskforce, taking control of Knight Force 1. This is the active military and adventure wing of Teuton Arcanum. Any job in the real world that needs doing use this. Recruits are generally from any country's army or from an athletic background.
2. Philosophical, The Taskforce theoretical division, responsible for ideas, mathematics, culture.
3. Archival. The Knight's Clerical; this department is responsible for storing and preserving the knowledge and treasures. The archive is called The Labyrinth and is administered by a supercomputer.
4. Esoteric. Responsible for investigation and observance of the religious and magical.
5. Political. The political department monitors and influences global events on a country level, and has a network of agents, diplomats, lobbyists and influencers.
6. Active Scientific Operations. Originally known as the Knights Alchemical, this department is the active experimental wing of the Taskforce organisation, responsible for inventing, building, and testing. Leonardo da Vinci was one notable member.
7. Sentinel. The military wing responsible for guarding Taskforce property.
8. Financial. The financial guild monitors and regulates the Taskforce finances and commercial exploitation of any inventions.
9. The Dark Order. An independent monastic order. All members take a lifetime vow of silence and live exclusively in The Cathedral. They monitor other Taskforce members with their unique network, and chronicle the activities of the Teuton Arcanum.

Taskforce recruit members by invitation. Throughout history many notable figures have been part of Taskforce, thus, the knights are an organisation of infinite depth and possibility.

Anyway, before I write too much on this. I spent yesterday adding lots to the game. Now you can left and right click on icons, which allows me to remove one option from the menu; this is good, simplicity is always my aim (yet, with depth).

Today I've added the ability to shoot though windows after a suggestion from Andrew. This wasn't even possible until I added the 'cannot step on' flag because height determined where you could walk. Now height effectively determines where you can hide or shoot, so you can have windows of zero height that can be fired though as though they were air. Detecting a bullet passing though them and transforming the block was really easy, just one line of code, but the visual effect was rather poor, and I needed a smashing window sound effect... all complexity. Well, now this feature is in.

I feel I have so much to work on and write. I will end this blog post with the new Taskforce logo, the Arcanum Knot, a star of nine points for the Nine Unknown Knights which control the world.

Friday, May 01, 2020

Morgane Armed, and Synaesthesia Queued

A tiring and somewhat frustrating day. I started with regular monthly backups, then relaunched A Walk in the Countryside and queued up my new Synaesthesia album. I'm pleased I did this... working on it was fun and particularly artistic. It set me a mood to check though everything in Taskforce from the sky, seeing the whole project at once.

After that I decided that I wanted my villain, October Morgane, to walk and shoot. It felt wrong to shoot an unarmed villain in any mission! Not only unarmed, this dummy was very dummy-like. He just stood there and rotated. I've given him legs and a pistol. Amusingly, he was 20% bigger than he should have been at first, evoking images of Sark from Tron.

This process took a long time. I had to find the 'Executive' object and basically copy most of the texture from him, all except the face, and then copy the face from the dummy Morgane. Everything seemed to go wrong; little things here and there. Then I revisited the final mission of the game. This is the most linear of all missions. Regular blog readers will be aware of my love of the non-linear in missions, so I spend an hour or two revamping this... then playing it...

...but it didn't work. For a finale, a climax, the linear helps because it builds to a specific point, a showdown. If you could watch Star Wars in any order, it might be fun, but you really need the Death Star to explode at the end, not in the middle or the start. Also, this is the conclusion of the whole game, so should (and does) feature a cameo from everyone in the game, ending in a climactic confrontation with the super-villain. With a few cosmetic changes, I restored the original mission.

Andrew reported a bug that I should have detected myself; that Config files are overwritten by Steam because they, naturally, change when playing, yet their initial state is shipped with the game. The problem here is that storing them is important to keep the user's mission progress, so I've got round it by having two; a start config for the first run and a subsequent one for any runs after that.

I've also tried a bit of music (the music will be, generally, a bluesy, dystopian rock), and experimented with new sound effects. The ones in the game so far sound a little crude and Amiga-like. I can do better now - if I have time.

I'll conclude with a picture of the final Synaesthesia cover. It will be released on May 29th: