utorak, 14. veljače 2017.

Refit discount

Time to address some leftovers. Proper refit cost calculation got implemented and scene building code got simplified.

Previously, refit cost was equal to full construction cost. On one hand it was not a big issue since refit and construction points are generated in parallel so there was never a situation where rebuilding ships was more profitable then refitting. But the idea behind whole feature was to have small refit changes result in lower refit cost while major role changes require more investment. In order to achieve that ship designs are now decomposed and compared component by component with following rules in order that would minimize cost:
  • Refitting to same equipment type and level is free.
  • Refitting to same equipment type but higher level has discount on full new item cost. Discount is 80% for 1 level difference and falls exponentially.
  • Refitting to 5 levels higher item of same type or to entirely different type receives no discount.
Items which don't have explicit cost (armor, sensors, reactor and thrusters) are priced at certain portion of hull cost. Unless hull is being upgraded too, then they are free. I may change that in the future with something like if hull receives 80% discount then armor and other items would have 20% discount. Reasoning behind that would be that upgrading hull partially includes retrofitting those parts too.

Scene building improvement is one of the under the hood changes which aren't visible in the game but very visible in project development. With previous approach I had to specify and manage almost every of drawable objects in the scene code. Term "scene" here means major game "screens", ugh, defining one word with another ambiguous one. Galaxy map is one "scene", zoomed in star system is another scene, space combat is third scene and so on. With new approach scenes only have to define what is there to display and let the engine sort out "how" and "when". Yes, they still have to cope with raw numbers like transformation matrices and vertex data values but they don't have to manage them all the time. The underlying engine tracks when low level buffers should be updated and in which order they should be drawn. It also tracks "physical" data for detecting which objects' region has been clicked/tapped by the user, greatly simplifies bookkeeping in galaxy scene. There I previously had a mess of multiple parallel lists (quad trees) for keeping track of fleet visual positions vs their real positions.

And lastly, a friend tested a game and ran into an issue. The issue appears with recent NVidia drivers and is a manifestation of an old OpenTK bug. The bug is fixed in new version but at the moment I can't use it because Stareater works with other component which depends on old OpenTK version. One option is to pray and wait for maintainers to update the component, which given their track record is not going to be soon. After some discussion with OpenTK maintainers I learned that I can make OpenGL in Stareater work without that extra component on top of OpenTK. To achieve that I'd have restructure user interface code but at the moment I'm not keen on large refactoring endeavors. If the component gets updated any time soon that would be great in short term solution. In the long term I will make GUI less and less dependent on it and ultimately get rid of it.

ponedjeljak, 16. siječnja 2017.

Preview release v0.5.3

So what's the fuss with space monsters recently? Click link below, unpack and find out :).

Download Stareater v0.5.3

 Aside from space monsters the graphics engine has been updated to newer OpenGL version and some bugs has been fixed (stability and saving/loading).

srijeda, 4. siječnja 2017.

Space butterfly

Stareater's native life forms are coming to ruin you day. Or whole year if turns represent years. Lovecraftian space butterfly may look harmless at first, it will ignore your glowing cities and curious star ships, it will go straight for the star in a middle of a system and put a curse on it. It will turn temperate solar weather into living hell with extreme radiation and flaming tongues of solar flares.

Catalyzers (those space butterflies described above) are very old life forms, dating lineage back to the first generations of stars. They were born on rogue planet, a gas giant without a star to orbit about. There the life evolved around utilizing liquid helium and planet's powerful magnetic field. Extremely low temperatures made one peculiar evolutionary advance possible, the fusion catalysis. A life form utilizing it would inhale hydrogen, preform cold fusion and have access to nearly inexhaustible source of energy. At least from human perspective that is. After millions of years, gigantic gas dwellers have had exhausted their hydrogen supplies. Because of it some resorted to preying on others and some to far more radical measures: interstellar travel. Another strange ability of liquid helium's superconductivity is twisting the space itself, allowing life forms to slingshot themselves toward new sources of hydrogen, the stars of their galaxy. Like moths flying into flame, many have died but some were lucky enough to stumble upon other gas giants and eventually evolve the ability to exploit stars. They would devour the galaxy if there wasn't another fantastic leap of evolution, moving through multiverse. Instead of traveling through normal space to another star they could reach much closer (in time, not necessarily distance or effort) another version of their main star, effectively exploiting it over and over. This eventually led to birth of a stareater, a seemingly single star swallowing entity which in fact is a byproduct of much smaller beings.

For now catalyzers are only native life form implemented but more are to come. As it was the case with previous features, my main goal was to work out the foundation and have at least one example of the feature in action. In this sense catalyzers are one example of special participants in the game who partly play as regular player and partly have special privileges. They can make order their fleet on galaxy map and in combat but can live without colonies, can see whole map and spawn "ships" out of thin air/vacuum. It was fair challenge but I now have a system which supports "fake" players without reinvention of the wheel. Theoretically I can add another fake player for parasitic life forms who pray on stareater's organism and have them fight each other. A theory which I intend to put in practice one day :).

Another big deal introduced with this feature is an ability to put persisting traits on stars during combat and they can have active component now. So far traits were passive, a celestial body would either have it turn 1 or not have it ever. Now for example stars with "catalized" trait can actively inflict increased radiation to orbiting planets and ceasing to do so after a few turns.

There are few bug left to iron out, mostly when saving and loading. When I fix them I'll make a new build available for download.

utorak, 6. prosinca 2016.

OpenGL 3.2 migration

It was a fight but finally it's over, I've converted game's graphics engine to OpenGL 3.2 (or at least removed functionality which was deprecated by that version). It was a fight because it took a lot more pieces in the right place to draw anything at all but it was a fight worth fighting. Now I have power of shaders at my disposal and I intend to use it.

Back in a day when I've started working with OpenGL, NeHe tutorials were the main learning material. They made stuff look simple and following them was fairly quick way to get results. For a good part that was due to simplicity of OpenGL's immediate mode and fixed pipeline. There was minimal setup code and very direct approach to specify what to draw. The setup consisted of tying OpenGL context with a window (or whatever OS of choice uses for displaying graphics, later covered by myriad of 3rd party libraries), turning desired options on and setting projection matrix (kind of like camera, defines which part of game world is visible and how is distance perceived). When it came to drawing stuff you'd simply specify which kind of polygons are you going to draw and then feed GPU with polygon vertex positions. Optionally you'd specify which texture to use (or no texture) and which color to apply.

That's all good when you are dealing with simple scenes and don't need that much performance. Feeding vertex data every frame (immediate mode) is inefficient because GPU can't do much but wait for CPU to communicate all the data. Alternative approach is retained mode where list of vertex data, much like texture image, is uploaded once and later just referred to. In this mode draw calls boil down just telling GPU which vertex list ID to crunch and GPU can get to work immediately. Additionally retained mode goes hand in hand with shaders which are an opposite of the fixed pipeline. Problem with fixed pipeline is it's "one size fits all" kind of solution where unneeded features can be disabled. Shaders on the other hand can be tailored much closer to application's needs and can provide features beyond those supported by fixed pipeline. For those and probably other valid reasons immediate mode and fixed pipeline were declared deprecated in OpenGL 3 and later.

But in order to get any graphical result from shaders and retained mode there is a lot of stuff to setup:
  • Load shader source code and compile it. One would think OpenGL doesn't deal with raw source code but that's the main way to get a shader on GPU. Of course shader source may not be valid and compilation can fail so the application has to check if this step was successful.
  • Attach and link shaders into a single program. In previous steps you just loaded various shader types (geometry, vertex, fragment) but to make them useful you have to tie them in a single unit called simply a "program". This can fail too (for example if output of one phase doesn't match with an input of the next) so application has to check this too.
  • Collect location IDs of shader attributes and uniform variables.
  • Make vertex data buffers.
  • Make "array objects". They hold information about how to feed vertex buffers to shaders, which bytes go to which attribute. This step won't fail but provides a lot of room for error.
  • Turn on options like in fixed pipeline (like depth test, alpha blending and face culling)
  • There is projection matrix calculation step too, like in fixed pipeline API but matrix management is very different. You can't use OpenGL's functions for building and switching matrices, you have to do it on your own (or use 3rd party library).

As I said, a lot more steps on top of the previous ones. If any of them fails or gets misconfigured, there will be no picture. It took me good part of the week to get it working in Stareater but when it started drawing it was like Christmas. Pieces stared falling in place one by one and I was able to experiment with some wilder ideas like drawing straight lines with circle arcs without involving infinity. For now I have mostly converted existing graphics from old system to new. Exceptions are planet orbits in system view, now they are a few smartly shaded polygons instead of ton of small quadrangles pretending to be a piece of circle arc. On top of that I've left room for improvements like applying texture to planet orbits to get gradient effect and to do the same for hexagonal grid in space combat. Also I can save texture space with a shader which recognizes which parts of ship should be painted with player color from single "sprite" image instead of requiring additional "mask" image.

It's exciting and all that but before I bring all that goodies I'd take pause from engine making in order to do something cool in game making department. After that I'll pack a release and then refactor graphical engine a bit to make scene building easier. And then the visible improvements will ensue.

petak, 11. studenoga 2016.

Preview release v0.5.2

It's almost as if I have a monthly schedule, new preview release is available for download. Semi-exclusive research is a new feature and there have been a number of improvements and bug fixes.

Download Stareater v0.5.2

Semi-exclusive research had it's own post so I'd focus on under the hood improvements. I won't bore you with coding details this time, let's just say that the game is back to 1000 FPS. As usual whenever the game starts lagging it's my fault, I either forgot to remove debug info collection or performed steps in wrong order. This time it was order of the steps, text rendering was initialized during the scene rendering instead of before it, making invalid OpenGL calls. Unfortunately it didn't crash the program nor bugged out graphics (which it should), driver made an effort to control the damage so I didn't notice the issue right away. After playing a bit with GLIntercept, an OpenGL debugging tool, I've found the culprit and was relieved that the cause was my sloppiness instead of something in programming language + OpenGL + driver combination.

I've also made a bit of code clean up and some refactoring. I've decided to drop T4 text template technology because editor support is not on the level I'd like and it cumbersome to work with it. Once you make it work, it works but when you have to make a change it ends up taking whole week. So far I've reworked two "classes" of T4 dependent code but the final and the most complicated class still remains. I have a prototype of an alternative approach in making but it will take me some time to incorporate it. I'm most probably postpone it and focus on something else.

So in a mean time enjoy the preview and feel free to give feedback!

srijeda, 9. studenoga 2016.

Semi-exclusive research

A hybrid between Master of Orion II exclusive research system and Space Empires V incremental system is done. When research breakthrough happens a player unlocks new topics and chooses their priorities. Higher priority items have lower development cost making lower priority items harder to acquire but not impossible.

In Master of Orion II research works by accumulating research points until breakthrough happens in a selected field. Each field level unlocks between one and three applications (building, ship component or passive bonus) and normally player can pick only one. Other applications can be acquired from other players through trade or espionage if they happen to research them or by having a creative race trait which gives all applications on breakthrough. Some players hate this exclusivity because if you don't play creative race you will miss out some very useful technologies and creative trait is quite expensive which limits amount of traits you can pick with it. Other players love the system because it gives the reason to use diplomacy and can make the game play a bit differently every time. Anecdotally my best MoO II experiences were when there was an uncreative race in the game. Uncreative trait gives random application (no choice) on breakthrough which makes otherwise predictable AI take interesting paths which in turn may make them actually stronger. It can make AI design better ships by preventing them from getting technologies for making their usual jack of all trades (but master of none).

How to make AI is currently hot topic in 4X community, I should address it at some point too but the topic of this post is research system. I wanted to make a system where player can have a cake and eat it. A system with good parts of exclusive mechanics and ability to eventually go back to missed out choices. One idea was to make some way of reresearching missed out application but that would either make research rewards random or would make reward list increasingly longer. The idea I settled on was to have research give all rewards every time and move the problem to development, where long list of possibilities and varying investment costs would be normal. How exactly would development cost vary with priority is still open question which I intend to iron out when I add more technologies. Speaking of which I have made a spreadsheet with tech "tree" and added to the game small part of if it. I'll add more as game mechanics get implemented and I fill more blanks in the spreadsheet.





And finally, this is how breakthrough screen looks like in game. On the left is the info about research field where breakthrough happened, name, level, description and in the middle are unlocked development topics. At the top is a list of topics which can be rearranged with buttons next to it. Order of topics determines their priority, higher on the list, lower the cost. Below it is currently mouse over or selected development topic description and accept button which finalized priority selection. I'll make new build soon so stay tuned.

subota, 15. listopada 2016.

Preview release v0.5.1

A new preview release is ready! Ship upgrading and refitting is the main news but there were a number of changes and improvements under the hood.

Download Stareater v0.5.1

Refitting and upgrading ships was explained in previous post and stayed pretty much the same but the game loop was reworked again. Last implementation caused weird performance issues, whenever regular Windows GUI should pop up over OpenGL area there would be a noticeable delay before a window started appearing and it would be appearing piece by piece. The delay and the time needed for a window to get full drawn was not proportional to the complexity of OpenGL scene but oddly by the number of components (buttons, labels, check boxes, ...) on the window. It looks like as if something in Windows is synchronizing main and background thread for each window component. For that reason I've moved OpenGL logic back to the main thread and used background thread loop for sending events when to redraw the scene. So VSync, framerate limiting, power hungry and power conservative frame timing methods are still available.

There was also general graphics performance improvement for non-animated objects. Previous method worked sort of like asking OpenGL to perform A+B and new method works like asking it to perform A and then perform B separately. For some reason former method is slow and I've observed double the framerate with latter method. There is more room for improvement since drawing stars takes 30 - 40 ms (~30 FPS) but only sometimes and the scene is simple enough to be drawn close to 1000 FPS. As I was writing this post I looked again at the issues to confirm the numbers and accidentally found a few bugs including one that caused slowdown. Stuff likes happens that way, there is a problem, you try to pin it down without success, you go to explain to someone what is bothering you and in the process get both correct diagnose and solution without other person ever saying a word :). In any case fixes to those bugs will be temporary band aids until I rework graphics engine to OpenGL 3.x compatible functions.

And there has been some code maintenance changes. Data loading logic was among the first things laid down in the last rewrite and it had some presumptions about future code which are not valid any more. One such thing was progress reporting about "how many percents was loaded" but that information was not used anywhere and implementation cluttered the code needlessly. If the need arises, I'll make cleaner solution. There was also unresolved issue of loading localization data. Previously it was done when settings data was requested for the first time which is not the most reliable approach and there was no good way to add error handling to it. Now the languages and other localization stuff are loaded in controlled manner like all other game assets (technologies, ship equipment, AI modules, map generators). Whole asset loading has been improved too so GUI has more freedom for choosing when to start it and receive notification when certain parts or all assets are ready. There has been a change about how loading logic finds it's data and that is an area which can be improved more. Responsibility for managing files has been moved from core to view so on one hand it would be easier to replace WinForms view with Unity3D but on the other hand view has to know too much about internal working for the core.

There is a lot of work left to do but feel free to try latest build and leave a comment!