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!

srijeda, 5. listopada 2016.

Refitting ships

First v0.6 feature is done, ships can now be upgraded or outright repurposed. It also includes automatically designing upgrades when new technologies are developed, as it was before rewrite.

The idea is that colonies passively produce certain amount of repair points which are first applied to repairing ships and then to upgrading/retrofitting. That much have been told in previous post. Currently ship repair is not yet implemented since no ship damage is carried over after a battle so all repair points go straight to retrofitting. Refit prices are currently simply full ship construction cost and repair points are generated at a rate of 1/5 per employed population (colonist with a workplace) making it 25 times slower then production of a new ship. I intend to revisit the numbers at a later date and make more nuanced cost calculation which takes into account equipment difference so upgrading will be cheaper then scraping and rebuilding ships.

So how does it look like? On design list screen each design has red "x" button (which I should change to something more descriptive) which opens "Refit to" dialog where player can choose to remove design, refit to other design or keep the design (cancel removing or refitting).

As with other things in the Stareater, nothing permanent (except exceptions) happens before ending a turn. Marked designs are removed at the beginning of a next turn if there are no ships of that design. If there were technological advancements which unlocked higher level of ship components then upgraded designs will automatically be added and older designs will be marked obsolete and set to refit to new design. That automatic upgrade order can be changed by player but only by selecting non-obsolete design to refit to. Building queues also get changed in the process, swapping obsolete designs ship orders with their upgrades.

I think that's enough for new preview build.

utorak, 13. rujna 2016.

New game loop

I had fun time learn how operating systems do (and don't) handle timing, what's guarantied, what's not and how and how achieve results by messing whole OS. On the one hand I'm disappointed there is no guarantee for having timing resolution below 64 Hz (ticks per second) and that there is no cross platform way of getting the resolution. But on the other hand I've observed 1000 Hz resolution on all machines I have access to.

Let's back off a little bit. Game loop is part of game logic which juggles when input events (mouse, keyboard, ...) are collected and processed and when a image frames are drawn. Typically it repeats following steps: check stop condition, process input, update game state, draw frame, sleep until next frame is needed. In previous Stareater version there was no explicit game loop, it was part of WinForm's internal "message pump" which in turn is too an endless loop that waits for a message, delegates it to an appropriate handler and checks if it got "quit" message. For signaling when to draw a next frame there was a timer component which was periodically sending "timer tick" messages. It was serviceable but not a "proper" solution. Timer's timing and my implementation of it's handler were sort of a "do it when you can".

When I started adding more game loop features, namely adjustable FPS limit, a mode without FPS limit and "battery mode" where game loop is bit more mindful about power consumption, it turned out I have to do a bit of research and rework the stuff. When it comes to timing precision there are two options, busy spin (a loop which repeatedly checks the clock) and thread sleep which is more concerned with letting other threads breath then timing. Timer is basically same qualitatively as thread sleep with a difference in how a thread is notified to wake up. So it's not surprising that most game engines, including the one supplied with OpenTK (graphics library used in the project), use busy spin approach. Busy spin is good when you have a lot of animations and movement in general but one has to keep in mind that such method uses all available CPU time which drains more power, heats CPU and makes cooler fans spin while not doing constructive work during the wait period. Since Stareater may or may not have a lot of animation, I made support for use both timing methods.

There was even bigger change to game loop, it was moved to a separate thread. I looked around the internet what is the best way to implement the game loop and there was no clear best practice. One approach (repeated from basic game dev tutorials) was to have ordinary loop which has extra step in cycle to let message pump process accumulated events. Another approach was vague reference to rendering in background thread. I've decided to marry those two concepts and suffer the consequences. The biggest reason I did that is to separate WinForms stuff from OpenGL stuff. This way window can handle it self at it's own pace and frames can be rendered in parallel. No need to send redraw request through who knows how many layers of bureaucracy. Many programmers fear the multithreading but it turned out to not be that bad. Sure I had my share of deadlocks (threads blocking each other) and race conditions (parallel tasks messing with eachothers data) and had to learn some new stuff but it was worth it. I finally had a chance to use thread join operation and discovered wonders of atomic operations and it didn't take long to fix bugs. In fact I'd like to share a few stories:

  • First one was an experiment. In theory when a process quits all of it's threads are killed so I tried to make game loop without explicit end condition. It turned out that exiting an application GUI left background thread working alone. Maybe it was the case when running from Visual Studio or Sharpdevelop, I didn't investigate further because I needed stop condition anyway. Game loop had to have some cleanup logic and it has to stop before GUI components get cleaned up.
  • What happens when GUI and main thread hosting it quit before game loop thread? Errors and exceptions because OpenGL is being used after the application had it deinitialized (disposed the context). Cure for that bug was use thread join so that main thread waits for background thread to finish.
  • More code you have guarded by synchronization mechanisms means deadlocks are more likely. When a combat happens, main thread informs game loop to switch to space battle "scene". Game loop switches scenes and calls scene initialization inside a guarded block and battle scene initialization "invokes" a piece of code on main thread. This code hides drop-down menus which triggers resize of draw area. Main thread tries to inform game loop of resize event but has to wait because loop is in guarded section so no thread can advance. Fix for this one was to make lighter signalization mechanism. Instead of guarding whole blocks of code I've reduced guards to only cover receiving signals (not handling) and simplified signals themselves (used atomic test and set instead of "monitor"). In retrospect asynchronous invocation would fix an issue too but simplifying code has further reaching benefits.

Enough with technical stuff, here is how settings menu looks like now. You can select or enter frame rate frequency limit or choose unlimited mode which will draw frames as fast as possible. Options below regulate whether to use precise but power consuming timing method or potentially imprecise but much less wasteful method. A little technical detail, power mode detection (whether a computer runs on battery or is plugged in) doesn't work in Mono so Linux and Mac won't have a benefit of game automatically switching modes. Players on those platforms will have to use "always" and "never" options which force the usage a particular method.

This is just a first phase of reworking graphics engine. It went better then expected. I know I'm repeating for the hundredth time but multithreading issues are nasty beast and I'm glad there wasn't so many of them. Next phase is moving to newer OpenGL API and improving performance. I've run profiler and noticed there are very bad performance issues. There is a lot of work left to be done.

subota, 3. rujna 2016.

Plan for 0.6 features

Loads of tech, that's the plan! And some space monsters.

It's been only a month and I already feel like v0.5 rewrite was done over a year ago. Strictly speaking software is never finished but I drew the line back then. Big rewrite was over and there were no glaring bugs. There was some functionality like ship design upgrade and colony/star list which didn't make through migration but they are either moved to future plan or moved back to drawing board.

This version will be about improving the "engine" and adding more gameplay, both featruewise and contentwise. There will be again moderately big code refactoring but I hope nowhere near as much as in previous version. In any case it should be possible to break it down to smaller (doable within a month) chunks. Code improvements made in v0.5 rewrite made that possible. Without further ado here are features planned for version 0.6:
  • Diplomacy with some basic capabilities like "declare war" and "cease fire". Will see for more complex interactions but for now I'd focus on laying foundation, figuring out where to put negotiation logic and how to handle it on user interface.
  • Hot seat multiplayer. Multiplayer as a whole is not in short term plan but I made a statement some time ago about how certain change brought the hot seat implementation closer to reality. It's time to test the theory.
  • Semi-exclusive research like research system in Master of Orion II where you can get only one item per technology field level. Stareater won't be so harsh, you will be able to get all items but you'll have to spend extra development effort. Idea is to instead of picking only one item you'd make your first, second and third choice. First choice item will be the cheapest to prototype, second choice will be expensive and the third will be even more expensive. On top of reworking research system I plan to start adding actual technologies to the game. I've made an draft document with about 120 candidates and more are to be added.
  • Ship repair and upgrade will be reintroduced. Ship damage will persist after battle and colonies will passively produce repair points. Once all ships at a star are repaired, surplus repair points will be used for upgrading or retrofitting ships.
  • Missiles in combat. First ambition level is to have "instant hit" missiles which will function similar to beam attacks but with slightly different chance to hit and limited ammunition. Next ambition level are torpedoes, missile which move across the map like space ships, can be destroyed and do area damage.
  • Space monsters are going to remind you that you are inside of a living organism. Most of them won't attack you directly but will interfere with growing your empire. On the development side their purpose is to give you something to fight before meeting other players or during the peace time and to provide some lore about the Stareater universe.
  • New rendering engine is already in development. Previous engine was using old OpenGL API, rendering loop was not very controllable when it came to timing and I'd like to make it easier to link visible objects with user interaction. Part of it is already done by now since messing with OpenGL and multithreading was more interesting to me then writing a post so that's why there is a delay :).
  • OpenGL based GUI is something I was looking forward to for a long time. WinForms are so restrictive, even for making ugly but servicable UI. The game uses a lot of lists, each displaying items differently and WinForms have two kind of GUI controls for lists: a simple ListBox where each item is just text and ListView which is basically carbon copy of file list in Windows Explorer. Both are inadequate for my needs so I've been faking lists with other components and the process is so prone to errors and full of workarounds. On top of that there is no way to easily change the look of controls so if I'm going to basically rewrite their drawing logic I might as well do it in OpenGL and solve other problems.
  • Refactoring state data is something I've been constantly doing in the last version. State data are stored in data types which beyond just holding the data don't have any more functionality of their own. The problem is there are a lot of such data types and each needs copying, saving and loading logic so there is a lot of repetitious code which looks like it can be generalized except no programming language feature can do that. Efficiently at least. In the last version I've tried C# text templates which are pieces of code for generating code (or any other kind of text file). They work but are hard to debug and update. I've been prototyping another approach, looks promising so I'll try it out.

utorak, 16. kolovoza 2016.

Library and ship building from galaxy view

As I mentioned last time two new features got in previous release build, library and star system management from galaxy map.

Library is a place where player can see information about all researchable technologies and equipment in the game. Much like civilopedia in Civilization series where player can look up all sorts of information in game instead of resorting to manual or game wiki. At the top left are categories, below it are topics in a category and the rest is information about the topic. There also an input for item level so player can see how technology benefits or ship equipment attributes are progressing. It's not the prettiest user interface but I'm not inclined to improve it at this point. In version 0.6 I'm planning to switch to OpenGL based GUI framework where I'll have much better control over how interface items look like and behave. When I get the framework working I'll gradually convert old Windows Forms interface to new one and library will be revisited eventually. In the mean time I have to rework how text is fetched from data files. Currently each item has a separate reference code for name and description text and with library there is a need for a third one, long description. So instead of actually adding third reference code on each item in game's core, I'm going to remove one and use it differently depending on context. For instance laser cannon will have only "LASER_CANNON" as text entry code and user interface will look under "LASER_CANNON_NAME" for weapon name, "LASER_CANNON_DESC" for short tooltip description and "LASER_CANNON_PAGE" for library text. It will be smart enough to append appropriate prefix on it's own.

Managing star system (the system as a whole, not individual planets) from galaxy is a small feature which greatly improves quality of life. When testing a game I usually need to build a few ships of certain kind and conclude the game in very few turns. This feature greatly accelerates the process and I hope it's usefulness goes beyond being development tool. Once I sort out new GUI framework I might extend the feature to show more star system information on map before it's selected. Much like cities in Civilization series where you can see what is being built, how long it would take and how well developed are the cities by just looking at the map, without needing to zooming in to particular city. And I'll keep adding quality of life features as I notice the opportunity.

Next in pipeline: version 0.6 plans and new rendering loop.

subota, 23. srpnja 2016.

Release v0.5

Big rewrite has finally come to conclusion. I stared it three, almost four years ago. It was supposed to be a moderately big refactor, not outright rewrite but in the end I think it was worth it. More about it in previous post about Stareater iterations.

Download Stareater v0.5.0

Since last release Wikipedialike library has been implemented, ship construction can be managed from galaxy map and there has been a number of bug fixes and unstubs. More about it in eventual next post. Feel free to try the game and report any bug you come across!

ponedjeljak, 20. lipnja 2016.

Preview release v0.4.5

Now that the biggest features for version v0.5 are implemented it's time to apply much needed polish. A lot of incomplete stuff is finished and stubbed stuff unstubbed, see below for more info. There is one new feature: game over screen.

Download Stareater v0.4.5

So far the game had no ending condition, one could destroy all colonies of other players and game would happily go on. Now at least there is a game over screen. Currently there is only one victory condition but I plan to add more down the road as well as some sort of game retrospective and more compelling victory screen.

As I mentioned in the last post there is new star image. Graphical work was and still is a low priority but this one was in the work for a long time and even low priority tasks get done eventually. I also changed starlane visual a tiny bit and plan on adding back old planet images. They are not meant for large surfaces but still better then current placeholder.

More colony related mechanics got implemented. Space construction penalty is back, it reduces industry points for ship construction and other objects outside of the planet. It incentivizes space projects on low gravity colonies and asteroids and allows improving space industry with space lifting technologies without penalizing colony development. Planet traits are implemented. Instead of having fixed set of attributes like atmosphere density rating and mineral abundance rating in previous version planets now have list of traits which detonate high or low rating of certain attribute or presence of special resource. For now there is only one test trait which increases farming efficiency but other traits can be easily modded in without touching the code.

Construction logic has been revisited and stockpile mechanic has been redone. Now construction projects have stockpile groups instead of each one having their own. When building an item which takes multiple turns to complete industry points are accumulating on the stockpile until there is enough to cover the item cost instead of being immediately spent. If you switch to another project within the same stockpile group then accumulated points would count toward that project and be spent when that project is completed. There is no penalty for switching projects and unused stockpile stays there forever.

While working on stockpiles I've fixed construction time estimation. It's was a bit messy and stockpile data sometimes made faulty situations like second queued item taking stockpile points accumulated from the first one. Colonization logic is also fixed and finished, colonization projects go away when colony is established. Colony ship arrival is handled a bit differently, instead of gradually landing on a planet as they come now they hang around the star system until there is enough of them to establish the colony and land together. Reason for it was to remove hidden ship pile and help with colony ships without colonization mission in the future. Theoretically I can now make idle colony ships count towards new colonization project if their star system is selected as colonization source.

Ship designer got revisited too. I finally ironed out how ship variables are organized and how resulting numbers are plugged in to both attribute used in combat and values displayed in ship designer. Now all numbers affected by special equipment are visible on GUI. Equipment amount input is fixed, both slider and textual input field work for normal and special equipment. Design list now shows design info when moused over. Unfortunately other design list features like number of built ships and deleting design are still stub.

Finally applied first aid for an issue when multiple fleets occupy same or almost the same location on the map. Instead of being able to select only"topmost" fleet player can now choose which fleet to inspect before getting the list of ships in a fleet. This works even for opponent fleets. Better solution where multiple fleet marks don't occupy the same position is postponed for next version where I plan to reorganize how visible objects are tracked and displayed, something like scene graph from popular game engines.

Stealth and detection in combat got implemented. It took me some good thinking for how to calculate distances on hexagonal grid but this awesome post helped me about it. There is a simple nice trick to convert square grid coordinates to hexagonal, visually simply shift every other column (can work for rows too just switch roles) by half tile size and under the hood treat each row as having two neighboring tiles on each side. The problem with that trick is having to constantly check and adjusting if tile is in even or odd column when calculating neighboring tiles and checking parity of both tiles when calculating distance. Before I only had a function which tested if a tile is inside a "circular" hex grid of certain radius and used it for simple distance checks like testing if target is in weapon range. It turned out it didn't work correctly if "center" tile was in odd row and converting it to distance calculation turned out to be way more complicated then a method proposed in aforementioned post. I was reluctant to use that method because it required representing positions with three coordinates, one along normal up-down axis, and others along left-right tilted up and left-right tilted down axes. It turned out it's easy to calculate those coordinates from usual horizontal and vertical coordinates and final solution ended up being fairly brief and clear. I wholeheartedly recommend reading the article for everyone working with hexagonal grids.

And finally, I've improved error reporting GUI. It should now catch more (if not all) unhandled exceptions and display them in copy friendly manner. Happy testing and feel free to comment the game!

četvrtak, 19. svibnja 2016.

New star

It's a funny story how drawing a star has bothered me from the very start of Stareater project to the recent days. I'm not good at drawing stuff by hand so did next best thing, I made program do the drawing for me.

First one was simple, it generated a texture (image) with each pixel painted according to a certain formula and displayed it. Any change in star shape or color required changing the code and rerunning the program. Actually using the resulting image in game was a bit complicated. Back in a day I didn't know about PNG so I did screenshots of each star color variant, pasted it in MS Paint, saved as BMP, loaded in GIF editing program (which name escapes me and) and marked black as transparent. This is how it ended up looking:

Bottom row is how it looks in the game, mostly OK but could be better. Edge between star color and darkness of space is too prominent especially in the case of red.White center is invisible in yellow star and too prominent in blue. Top row demonstrates functional problem with the whole thing, since GIF has so called key based transparency (all pixels with "key" color are treated as transparent) there was no way to make some pixels semitransparent and if the star was on top of something then the fake space darkness would become visible.

At the time it served the purpose and after a while I decided to fix those shortcomings. I've made a more complex program which could save usable PNGs and could change parameters on the fly. It had a little framework for making procedural images generators and star image was just one implementation of the framework. Each image generator had it's own logic and set of parameters on GUI and the best thing was that one of the supported parameter types was symbolic function. You could type "4*x+0.5*y" if x and y were applicable variables and it would work.

Above are examples of some image generators and as I said, star image was just one of them. I also used the program for experimenting and fine tuning Stareater algorithms like starlane generator (middle image) and star positioning (right image). It was great tool for making quickly visualization.

On the other end I was exploring vector graphics for drawing starships. Inkscape was the best and de facto the only good tool for the job but it didn't click with me. It's great for hand drawing, so to speak, but lacking for technical drawing which happens to be my way of thinking when it comes to drawing something bigger then 20x20 pixel art. So I started making my own program for vector graphics, it was no good so I made another with different approach, it was better but not up to a task and repeated the process a few more times. The thing evolved from clicking points on canvas to typing them in table to writing a sort of programming language. Seriously:

On the right side is code, a sequence of points and shapes made with those points and on the left side is resulting image. It was not the most polished tool but it had potential. Unfortunately it took a lot of effort to keep improving it and code editor was devoid of usual IDE (code editor) luxuries like autocompletion and syntax highlighting. As I was developing programs in SharpDevelop, an opensource IDE, I was pondering an idea of using their code editor for my vector graphics language. And then I took the idea even further, to use C# itself for drawing. On the one end I'd to develop image generator as DLL (much like other Stareater plugins for AI and map shapes) and on the other end was program which continually monitored if DLL has changed, loaded new version of image generator and displayed a resulting image.

It's kind of return to the first program I had back in 2008 but with much faster code to image loop and so far it's serving me well. There is a bit of initial setup overhead for establishing OpenGL logic (making texture, setting perspective, setting rendering flags and drawing textured rectangles) but once set up it really easy to adjust and experiment about. Especially when secondary monitor is available, put C# editor on main screen, image preview on the other and watch the image change as you type.

And there is one more important bit of the story. While I was making all those programs I was collecting images of real stars in order to figure out what to actually draw with my programs. The challenge was to find an image were star was not a simple globe of light and not overly distorted by atmospheric noise and lens. When I finally made a satisfactory program and picked a good looking star the real fun has began, analyzing how colors change from black to blue to white and how to make similar looking stars of different colors. That part might be too geeky so I'll just leave a picture without too much explanation:

petak, 22. travnja 2016.

Preview release v0.4.4

This is getting embarrassing, last release had same issue as the one before it. Despite me having checked 10 times if the game works on other computers, applying a solution a solution that should have worked there was still an unaccounted catch. This time it has to work. Period. Good news: farming and mining are implemented and included in the release!

Download Stareater v0.4.4

Last time I tried solving DLL loading issue I went with a solution which involved applying certain application configuration. To be honest I don't really know how application configuration XML works and what it can do so the fact it didn't work might have been my incompetence. I suspect that configuration only applies to one assembly, not whole program. Since Stareater has some logic in EXE file and some in a so called "core" DLL, the configuration might not have been automatically transferred from one to another. Anyway I've found a new solution, instead of loading DLLs with LoadFrom function I could use UnsafeLoadFrom. As the name suggests and as documentation convinces me, it won't pester perform security check so I hope it won't be a case of "works on my machine but explodes on yours" any more. And I promise to take closer look at sandboxing plugins later.

About new old game features: farming and mining. Much like Master of Orion II, farming is there to keep workforce from doing useful work and make biology advances improve economy by decreasing the portion unavailable workforce. To keep mechanic relevant in middle and maybe late game I've split food production to two parts: farming and gardening (for the lack of better word). Farming produces a lot of food, especially on planets with good climate but there is limit on how many fields can be cultivated. Gardening on the other hand produces small amount of food but is unrestricted by planet's characteristics. So as technological advances enable more densely populated planets there will be an incentive to improve farming too.

It's a bit of deviation from CroVar iteration (last attempt at whole Stareater project). Back then there were only farmers but after certain point their efficiency gradually diminished according to certain nonlinear function. The problem is when calculating food production you don't really need to deal with a function of food per individual farmer but with an inverse of integral of that function. In other words, you want to calculate how many farmers do you need to produce certain amount of food. Integral will tell you how much food would certain number of farmers produce and inverse of integral will tell you how many farmers do you need to produce certain amount of food. In general integrals and inverses are more complex then original function and when you combine complexity of all three you don't get a simple formula. And that's the beauty of farmer-gardener approach, it's easy to explain, relatively easy for player to estimate the numbers, it's easy for me to fine tune and it achieves the desired effect.

Mining was and remained simple mechanic. Miners are extracting ore at certain rate and industry workers convert ore to an industry point in 1:1 fashion. In a sense it's like food production, another mechanic for wasting workforce and excuse for introducing more economy boosting technologies :). But unlike farming it rewards exploitation of minerally rich planets. In future I plan to introduce trade mechanic which will allow an empires to import minerals from rich to poor worlds, increasing the importance of rich planets to galactic level. More about it in next version.

petak, 15. travnja 2016.

Preview release v0.4.3

New release is ready! Space combat is the biggest new thing since the last release and of course there is a number of bug fixes, code cleanups and streamlining .

Download Stareater v0.4.3

Like last time, the package is a simple zip file so to run the game extract contents and start Stareater.exe. And again the game is .Net 4.0 application so it should work as is on Windows XP SP3 and newer and should work on Linux and Mac with Mono.

utorak, 12. travnja 2016.

Nukes and lasers

Shooting part of space combat is mostly done. Ships can cut each other with lasers and drop nuclear bombs on planets. Colonies can be wiped out too but I'm still testing and polishing that part. Functionally, cloaking and detection is missing and I have to decide how to make inaccurate weapons like bombs viable in ship to ship combat. The idea is to give small and maneuverable ships means of seriously hurting large ships.

Visually there is a lot of work left and I'm feeling like I am stretching Windows Forms (Windows default user interface solution) way past intended purpose. Customization options boil down to either a set of inflexible switches or overrides where I have to do whole component from scratch. There is no middle ground where I could override some parts of default look and functionality but reuse the rest. Yes, I could instead work on adding more visual feedback on hex grid like beam rays and causality numbers but GUI part is bugging me so much. I'm seriously thinking about adopting GWEN.Net (an OpenGL friendly user interface solution) and ditch WinForms as much as possible.

And I see another cloud creeping over. At some point I'll have to improve my rendering engine and basically reinvent part of Unity engine, which poses a question: should I have made the game in the Unity in the first place? I'll try to stick with no as long as I can. Rewriting would probably take way more time then it seams at first glance and I have some experience on implementing scene graphs so it might end up being faster solution. Also, doing it on my own gives me the opportunity to tailor it to my needs. There are some design decisions in Unity I don't agree with and I can work with assumptions that apply only to my project. I'm confident that my current code base is good enough to endure such changes.

It's eating me too but you'll have to suffer through ugly GUI until version 0.5 is finished. I'll put more effort in visuals in the next version.

srijeda, 24. veljače 2016.

Hex grid

At last something visible in space combat! Well, by the time I finish this post it might be complete :). Boring stuff first, some more ground work had to be done in order to trigger space battle for right player at the right time. The way how battle events are pushed to GUI had to be more strictly defined and there were some changes in AI handling. Then there was also a question of how to organize ongoing battle data. I started with what there was in CroVar version and after some experimentation I ended up with game within the game structure. Space combat is going to have similar model-view-controller pattern as the main "galaxy" game and will not be entirely stuck inside the main game. It would pop in to existence, run as separate entity and feed the results to the main game.

Now fun stuff, image above is how game looked on paper a year ago. I've been thinking about space combat for a long time, I've decided to abandon one dimensional simplification from CroVar and do proper 2D tactical TBS. And while I'm at it I could do it on hexagons. Math is slightly more complex then it is for square grid but only slightly and there are few tricks for representing hex grid in memory in a same way as square grid. Image below is how it looks like at the moment, a grid, a star, a defender near the star and an attacker's fleet on the edge (exact location deduced from the direction it came from).

More coming soon!

nedjelja, 31. siječnja 2016.

Preparing space combat

On a way to implement space combat I have implemented conflict detection logic and unstubbed some parts of the game. Conflict detection is a mechanism for finding where and when space battle happens. Under the hood a fleet can have multiple waypoints and with advanced enough interstellar drive it can pass through multiple star systems in a same turn. If one of them happens to have an enemy presence, space battle happens and the fleet ends it's turn there. When the conflict begins is also important, it influences a turn limitation. If at the end of player's turn a fleet was 1 light year away from destination, traveled at the speed of 2 ly/turn and battle happened there then it would have 50% of maximum combat turns to resolve the fight. In case the battle doesn't end by then I plan to make persistent battles which can span multiple galaxy turns. I also thought about making a mechanism where a quick enough fleet can fight in multiple systems. For instance if a fleet finishes one battle quickly and is fast enough to travel to next star system it would be able to fight a few more turns there too. The problem is int that case conflicts wouldn't be isolated and players wouldn't be able to play each conflict to the end before moving on to the next one. It might work by making players play all space battles simultaneously, one turn at the time but that doesn't sound like fun. So I'll go with one battle per fleet per turn limitation and keep the idea in the drawer :). There is also a question of what to do with colony ships that retreated from the battle, do they try to reach a marked planet or do they go home and do what exactly? I'll cross that bridge when I come to it.

Next step toward space battles was making AI build ships so a player can have somebody to attack. In order to implement that I had to change how the game rotates players during the turn. So far I had a "current player" number and only one player could interact with a "game core" at the time. On the other hand AI was supposed to do it's work in the background. Since both AI and human player used the same means of communicating with the game core AI could only manipulate the empire of current human player so for a brief moment there was an AI which filled my building queues with random stuff :). To make AI independent I tossed the concept of the current player out of the core so from the it's perspective everybody is playing simultaneously and it is up to a user interface to worry about who has the turn. Interesting consequence of it is that Stareater is now very close to having hot-seat multiplayer.

utorak, 19. siječnja 2016.

Works on my machine

Every time I make Stareater release I find a new program breaking bug. Not just game breaking like improper behaviour of the game but bug that completely crashes the game's executable. Previous release turned out to be no different despite my effort.

Truth to be told I don't have much in a way of release procedure, there are no automated tests, nor alpha, beta and release candidate testing periods. Heck, there is not much in a way of installation package either, just zipped folder. But I do try to check by hand if the zipped stuff works at all before uploading it. And guess what, it did work on my machine. It also worked on the other machine I sometimes use for developing the project. I asked a friend to test it on his computer but Christmas was near, I couldn't wait so I uploaded it anyway. Couple of weeks later I met with him brought the topic up and he gave it a try. Main window appeared over the whole screen but main menu was not there. Second or two later the program crashed with only the most basic and generic "Application crashed unexpectedly" error message.

That puzzled me because I specifically made a logic for trapping run-time errors and displaying the error details in a manner which reasonably competent user could report to developers (me). Since there was no such error message I had to reproduce the problem in the environment where I have some debugging tools. Guess what, I could reproduce it on my own computer on which it worked before upload. Trick was to download a zip file from the Internet, not use the one I uploaded. No, it was not the case of GitHub or SourceForge (for some reason GitHub hosts Stareater releases there despite SoruceForge's shady recent history) injecting something in my file but the case of Windows not trusting downloaded files and .Net security. Such circumstances made the Stareater to reject loading DLLs for AI logic and map generator. These DLLs can be replaced by mods so they are not exactly known to the Stareater's EXE in advance and not trusted because of it. To be honest I'm not the best informed about security surrounding untrusted code but I've been educating myself on one previous projects and it turned out Mono doesn't support it. If I remember correctly Mono simply ignores security related functions, doesn't explode with errors but as we wanted to sandbox 3rd party code we dropped the concept and moved to something else. In the future I could spend more time researching the topic and make some sort of DLL trust checking but for now I'll just allow all.

Sorry for inconvenience, next build will be available when some visible part of space combats is implemented. Or sooner if there is an interest.