Sunday, May 10, 2020

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.