Table of Contents
March 2015 blog archive
This page contains all the blog posts from march 2015. To read the most recent blog posts, click here.
29/03 - UI patch part I
The new alpha with the first part of the UI updates is now available. All screens have been converted for the most part. Generally it's only card popups and dialog boxes that are still on the old system. There are two exceptions to this however : both the deck editor and the combat screen still have elements of the old system.
In case of the deck editor, the way cards are prepared and rendered hasn't been changed. The original system for this part of the deck editor already has good performance, and right now it's not at all certain that moving this to the new system is going to improve things all the time. There will be cases where rendering cards under the new system will speed things up, but at the same time, there will be cases where the opposite is true. On top of that, the screen will use more memory.
The combat screen hasn't been changed in any way. The plan was to update the UI elements and leave everything else untouched (as was done with the deck editor), but this screen is very complex, and basically uses its own system to prepare and render things, in an attempt to make it as optimized as possible. There's still room for improvement in a few areas, but there's also the unpredictable issue regarding performance that the deck editor might suffer from under the new system. The problem likely won't be as severe as the deck editor, but in any case, this screen needs to be built up from scratch to make sure it's as fast as possible.
So what's this problem then? It has to do with preparing cards. Various screens have to show cards (opening hand, combat, deck editor) in various sizes, but generally these cards are build up in the same manner. I have one seperate renderer that any screen can call upon, that can make such card images. It's then up to the screen to decide how and where it will render those images.
These card images always have a border, sometimes in two colors if it concerns dual-race cards, which is a simple thing to render. Cards can have attack/defense stats or card costs that need to be shown as well, which are normally created by the text renderering. I've made a seperate text renderer just for this, which if much faster than the regular one. Finally, there's the card portrait itself, and in all cases, its needs to be scaled, and this is the slowest part in creating these images.
The opening hand screen no longer renders card images the old way. Everything is the same, except that the step where the card portrait gets rendered is completely skipped, so only the card border and stats get created. Then this screen takes the full-size (i.e. not scaled) card portrait and uploads it seperately to the graphics card. When things get rendered to the screen, the card portrait gets rendered first, and scaled in real-time, then the border gets rendered on top of it. There's still a scaling step, but the difference is that this scaling is no longer a pixel operation, but is performed by the graphics card, which is much faster.
There is a drawback to this way of work however. Under the old system, where a complete card image gets made, only that card image gets uploaded to the graphics card. Under the new system, the border gets uploaded (and it will take up the same amount of memory as the full card image under the old system since it's the same size), but on top of that, the card portrait needs to be uploaded as wel, and this image is in most cases much larger than the card border. As a result, the amount of memory that's used to store a single card image (border + portrait seperately) is more than double than what it used to be under the old system. For the opening hand screen, with its low number of cards, this is absolutely no problem. But the deck editor can easily show more than 100 cards on the screen at once, and here this starts becoming a problem. The combat screen can show 40+ cards (after the global aura, boosts, deckmods overhaul), which is still a lot more than the opening hand screen. Increased memory use isn't the only problem. I've mentioned before that uploading images to the graphics card can be slow, and is affected by the size of the image that gets uploaded. Thus the more stuff that needs to be uploaded, or the more frequently that needs to happen, the slower a screen will become. In case of the combat screen, not all cards need to be updated at the same frequency, so card images can be grouped to make the process of uploading images as fast as possible, but on the deck editor, such a setup isn't possible.
Part II of the UI overhaul will start by looking at the combat screen to see where i can still make improvements. Keeping the challenges i've mentioned above in mind, it's possible that the new combat screen will be a mix of the new and old systems.
Once the combat screen is updated, i'll start on card popups and dialog boxes, and then the UI overhaul is complete. The deck editor will remain untouched, for now. The performance is okay, but not stellar - the problem is that there's no guarantee that the new UI system would improve it. I might even come up with a completely seperate system, just for the deck editor, but for now the current setup will have to do.
Before i start on part II however, i'll add in the TM cards.
22/03 - more UI stuff
I'm still working on the UI, which is not entirely unexpected, but at this point i'm considering splitting the work in two parts and taking break to add in the TM cards.
Currently, all the screens that are primarily made up out of regular UI elements have been updated (deck list, battle setup, flagship editor). I also updated the menu and loader screens, as well as the game over screen (which is still a placeholder), and started work on the opening hand screen. Some of these screens still have elements of the old system, such as the card popup and dialog boxes of various kinds.
The code that generates dialog boxes isn't tied to a single screen, instead it's capable of generating boxes for any screen that needs them. I don't know yet how i'll update this system so that it can be easily integrated into the current UI, rather than sitting on top of it as a completely seperate element as is the case now. There's reasons to stick with either solution, but i'll look into it once all screens are done.
The cardpopup will still look the same for the most part, except for the look of the buttons. What will change, is the way this popup is prepared and rendered, which should hopefully speed up the creation of the popup greatly, especially for android devices. Like the dialog box, this is a piece of seperate code that handles all cardpopups in the game.
The remaining screens are those that mix UI elements with complex, screen-specific imagery : the deck editor, and the combat screen. There's still room for performance improvements on both screens, but in both cases, this will take a fair bit of work. The plan is to do this in two steps : first, i'll move all regular UI elements (buttons, labels, etc) to the new system, then i'll update the non-UI elements (card images, etc). This second step will likely happen in a seperate patch, alongside the dialog box and card popup updates.
Finally, there are some minor game-wide changes that can only be done when everything is moved to the new UI system. Some of these changes can be only be done when everything i've mentioned above is complete, some can be added in sooner. In any case, the overall performance of the updated screens should improve greatly, even without these game-wide updates.
At this point in the game's development, the most important thing is still getting all the cards from HDx in the game. So i rather split the UI overhaul in two parts, add the TM card set, and then finish the UI update. This will also give me a bit of variety in the work that i've been doing lately, and i can get some feedback on the first part of the overhaul from alpha testers.
There's still a bit of work left to do before this first part can be released however, so i can't tell yet when a new HD3 alpha would be out.
Working on and with this new UI system made me realize something however : none of this is going to work for a flash version of the game. I've mentioned before that i started off HD3 by mimicking the way i set up games for flash, especially when it came to rendering things. That way, when creating a flash version of the game, there would only be minor things that would have to be rewritten from scratch. Gradually, i changed this system as it was too slow, but in doing so i also created a system that can't be easily ported to flash. The current UI, while ideal for HD3 in java, would slow down a flash game to the point where it's unplayable. I estimate that about 90% of the code that deals with game mechanics, can be ported to flash without needing any changes, but almost everything that deals with rendering will have to be rewritten. The advantage is that i can create a completely seperate render system for a flash version, but at the cost of this taking a huge amount of time.
So my options are :
- don't make a flash version, and instead focus on the desktop/android version. This isn't fair towards all the old fans that don't care about desktop or android.
- make a flash lite version. Theoretically this would take less work than a full version, but what can i remove? Since most of the game mechanics can be easily ported over to flash, the time gains might be minimal, and the most complex screens graphics-wise are the deck editor and combat screen, which are vital. Perhaps some of the secondary features can be left out, such as everything related to online play.
- make a proper flash version. This will take months, and thus has to wait until the game is in beta, else it would slow down things too much, even up to the point that a beta might not even make it this year. This also implies that this flash version needs to be updated whenever the java version is updated, which will slow down continuous development on the game.
The html5 option looks the most interesting at this very moment, but having a lite flash version can also be a good way to advertise your game and get as many people as possible to at least try it out.
15/03 - UI rendering
Last week, i mentioned that the new UI system basically moves from rendering several large images (which take time to prepare or update), to rendering large amounts of tiny images. This results in less time being spent on preparing the variable elements on the various screens in the game, since those elements are now much smaller (and thus contain less pixels).
Meanwhile, i've completed the decklist screen (and the battle setup screen is nearing completion as well). When this screen shows the max amount of deck entries at once, it's rendering almost 250 objects (up from about 15 under the old system). Isn't this going to affect performance? As of yet, the performance of realtime rendering is still about the same as under the old system - this means that it takes the game (on my relatively old PC) less than 1 millisecond to render all this stuff.
LibGDX, the framework i'm using to make HD3, comes with a spritebatch system, which is a powerful piece of code that makes it very easy to render images on the screen for 2D games. Behind the scenes, a fair bit of stuff happens to make all of this work. Technically a 2D game is still a 3D game, but the camera and the 3D objects (which are all flat rectangles with bits of image painted onto them) are set up such, so that there's no discernable depth.
A powerful system like this does need to be used carefully. It's easy to increase rendering times if you try to render too much stuff at once without grouping that stuff a bit. When you tell a spritebatch to render something, it doesn't do so right away, it will wait until the next time you tell it to render something else (or until you tell it that you're done sending it commands) to actually prepare the 3D geometry upon which your imagery will be painted. It does this because there's a good chance that multiple images can be added together into one 3D object, but the requirement here is that these images use the same texture. If you want to draw 10 images onto the screen, but each of these images is located on another texture, the spritebatch ends up creating 10 different 3D objects - one plat plane for each image. If all these images were located on the same large texture, a single 3D object will be created instead, and this improves performance when these objects actually get rendered.
Placing all images you'll ever need on a single texture is not always possible - the larger the texture, the more time it will take to upload it to the graphics card in case something on it was changed. Not all graphics cards and chips can accept really large textures either. For most things in HD3, under this new system, textures are low in number, and greatly vary in size. If a screen needs a bunch of texts for buttons, all those texts go on the same, large texture, but if the same screen needs an image that changes very often, it will be placed all by itself on a texture that's as small as possible.
Having your images on a small number of textures improves performance in general, but the order in which you command the spritebatch to draw them still matters. If you have 10 images, of which 5 are on texture A, and 5 on texture B, and you tell the spritebatch to render one from A, then one from B, and so on, there will still be 10 seperate pieces of geometry created, even though you only used 2 textures. If those 10 images must absolutely be drawn in that specific order, it might be interesting to look at how the textures themselves are set up. But if the order doesn't matter, it instead becomes a good idea to help the spritebatch a bit and tell it to render all 5 images from texture A, then all those from texture B, resulting in only 2 pieces of 3D geometry being created.
With 250 elements, some of which must be rendered in a specific order, trying to set up the ideal order for the spritebatch manually, simply is too much work. Therefor, every element that needs to be rendered, also remembers what texture it's located on, and what layer it needs to go on. Before i tell the spritebatch to actually start rendering stuff, there's a bit of code that loops through all elements, and sorts them per layer, and per source texture. As a result, with 250 images spread over a total of 7 layers and residing on 5 different source textures, i can limit the maximum number of pieces of geometry to 35 - in practice, this screen actually ends up getting drawn in only 10 pieces.
It might still take a while until everything related to this UI overhaul is complete. Next to moving all the screens to the new system, there are several global, seperate systems that need to be updated as well. For example, the dialog boxes that can appear on various screens are not controlled by the active screen, instead there's one seperate piece of code that creates dialog boxes for all screens. For the time being this system is still using the old UI setup, but eventually it needs to be updated as well.
08/03 - UI overhaul
The update with the MT card set was released last monday, and since then i've been working on a new UI for HD3.
I originally wanted to get started on something else first, but as with most planned updates, it involved a couple changes to existing screens. I can do those other updates under the current UI system, but that would mean i'd be adding stuff to existing screens, which would make a UI overhaul in the future more complex.
The UI overhaul is something that will take quite some time. It's not overly complex, but many areas of the game rely on it.
Changes to the UI are needed for multiple reasons. Primarily because i've reached almost the best possible performance with the current UI, and it's still not good enough. The new UI will also be more flexible, giving me more control over the layout of the various screens in HD3, and it should scale much better as well, meaning that a very complex screen isn't going to become that much slower or complex to render it compared to a simple screen.
The new UI can also more easily change various settings about it (opacity of background elements, foreground elements and color detail seperately for instance).
The current UI system is not too different from the one in HDx. The idea with HDx was to create a flexible system that could build up a screen out of several basic components (buttons, textlabels, containers, etc). The way things are rendered in my flash games differ from how its done in HD3. I tried to mimic the HDx setup in general, mainly to make it easier to create a flash version of HD3. Early on already, it became clear that this setup was too slow, so i changed the way several screens worked, but within the original UI system there wasn't much room for performance improvements.
The new UI still builds up layouts out of the same basic elements, but these elements themselves are built out of even smaller, simpler components.
To render something on the screen there basically 3 steps involved. First you need to have the image you want to render available to the game. It could be on a file that's included with the game and that gets loaded into memory (such as the card images), or it can be entirely created in-game (such as the nebulas in the background of all screens). Drawing straight from memory onto the screen doesn't work, so in the second step, these images need to be uploaded to the graphics card. The image, made up out of pixels, becomes a texture in this process. Finally, this texture, or a part of it can be made visible on screen. This last step can be complex as well, but LibGDX provides a spritebatch system which makes this easy.
The current UI would create an image of the element thats needed (an entire button, or an entire dialog box with buttons and labels, etc). All these different images (some of which can be relatively large) were all placed together and uploaded as a whole, resulting in one large texture with all the components a screen needed. Finally, the different components were rendered on screen in the correct locations. The problem with this setup, is that the steps which are slow (creating and manipulating pixels, as well as uploading) occured relatively often, while the step that's fast (drawing to screen) didn't happen often at all. The new system does the opposite. A button no longer gets drawn in memory, since the components out which this button exist are already present in memory (they have been loaded from file, or created, at the start of the game). In many cases, these components also don't need to be uploaded to the graphics card for every screen, since it's there already (again, done at the start of the game). Drawing to screen has become more complex, since all the different components this single button is made up of, get drawn seperately, in a specific order. But since this draw step is fast, this added complexity doesn't slow down the game noticable.
In the end, the time gained by not manipulating pixels and uploading them is much more than the time lost as a result of having to draw more stuff on the screen. Some early performance tests are looking very promising. I can easily render 50 times as many seperate images on the screen as currently without any noticable slow-down, and that's before any optimizations.
Below is a sketch of what the decklist screen will look like with the new UI. This is the first screen i'll work on, as it's relatively simple, but still complex enough to allow me to test out all features the new UI system will need.
With this sketch it's also a bit easier to show the difference in what actually gets rendered on the screen. Under the old system, the top bar, with one text label and 3 buttons, was drawn in pixels as one single image, which then needed to be uploaded. Under the new system, this entire bar is made up out of 22 elements, and only the non-default elements had to be draw and uploaded. Over this entire screen, its clear that the total number of elements will be large, but at the same time, there's less stuff to be uploaded. The top bar has 3 buttons of the same size, but only the contents of each button is different. On top of that, other screens will also use the same size buttons. Thus the button already exists and doesn't need to be drawn or uploaded, only the contents needs to.
A sketch as the image above allows me to measure the size and position of the different elements. The new system is a bit more complex, in that there are now more elements that need to be drawn, but at the same time it provides me with more control. Changing the size or text of a single button is now going to take less work.
Implementing the new decklist screen is about halfway done. This first screen will take relatively long, since i also have to add in all the supporting code for the new UI. The next screen doesn't have to add the supporting code anymore, so from there on, things will move quicker.
01/03 - MT card set
The card and abilities of the MT set have been put into the game and are going through testing. Early next week, a new version of the HD3 alpha, containing these cards, will be released.
Overall, there are few changes compared to HDx in the cards themselves, but several have had their names updated. The biggest new element of this update is probably a new passive, called 'randomstrike'. This ability was created for another game mode, where it plays a big role. Due to the nature of this ability, i originally wasn't planning on adding it to any of the existing cards. Seeing how MT cards often have random elements in their abilities, it turned out to be a good fit for an MT ship.
So what does randomstrike do? It's similar to multistrike in that it allows the ship with this passive to attack multiple times in a combat phase. Unlike multistrike, which has a minimum value of 2, randomstrike can have a minimum of 1. For every attack, a ship with randomstrike will choose a random ship target, and only when there are no ships left, will it attack the base. A ship with randomstrike is thus basically going to spread its damage around, randomly. While this increases the odds of such a ship getting hit by all kinds of retaliation effects, and it not having a guaranteed way to dealing with its blocker, it can actually be quite dangerous. As with other multi-attack ships (multistrike, cerberus, hydra), abilities that boost the attack of such ships are extremely effective. A lucky, singly randomstrike with high attack can deal with several small ships in one combat phase. If that ship is then in the left most slot on the board, it will attack before any of its allies and possibly remove blockers, allowing those allies to attack the base.
The game mode where this ability is going to play an important role, is the same one where global auras will also be doing so. A few of the mechanics of this game mode still need to be sorted out, and both global auras and combat boosts need updating before i can get started on it. There are a couple other things that are important and urgent, so i can't say yet if any of the requirements for this game mode will actually make it in V 3.05. The most important thing is still getting all the HDx cards in the game, and i'm aiming to get the remaining sets done within 3 months, which still leaves quite some time to work on other (smaller) stuff in between adding cards.