petak, 27. prosinca 2013.

Stareater v0.4.1 downloadable

Current state of the project is available for download at


Compared to the last downloadable version there are no new features (in fact stuff are missing) but the game looks completely differently. Changes are not just cosmetic, under the hood stuff are radically different too and despite of loosing a year of progress project might be over sooner. Code maintainability is greatly improved and it's much easier to develop. To make it up I promise to make better space combat, a proper 2D mini game.

Future builds will be uploaded at some other service because Google is going to kill downloads section on their project hosting service. Allegedly the download section was abused for spreading malware. I disagree with their reasoning but I have no power to change their mind. It's not their only BS move, they killed "updates" section which showed recent changes on the project and they broke user experience on GMail web interface. Something wrong is happening with Google.

ponedjeljak, 2. prosinca 2013.

Silent fail and rage


I raged last Friday over a stupid designed choice Microsoft made for .Net framework. It all started with benign change, I changed folder where game settings were stored. When I tried to test the change the main window refused to close. I stabbed red "close window" button a couple more times but to no avail. It seamed as absurd as not being able to start a car because a house few street away has new door. So I paused the program through debugger and it turned out that "close window" event was being aborted for some reason. For those unfamiliar with MS Windows Forms, program can subscribe to "somebody requested to close the window" event. On such event the program is notified and can act upon it and even prevent closing. Stareater GUI code is subscribed to such event and naturally I checked it out:


A single line that saves settings. There is no code that cancels closing. With debugger tools I followed internals of SettingsWinforms.Get.Save() and it's execution wasn't as I expected. It was cut in a middle of execution. I spent some time trying why and it turned out there was an exception being thrown (sort of runtime error) inside Save. When a program doesn't handle an exception it usually crushes but proper programming tool catches it and presents plenty of information that helps programmer to fix it. Take a look at Visual Studio 2010:


It clearly says where the code broke and why. Other C# IDEs (programs for programming) also offer such good debugging tools so it's kind of expected that every exception will show on programmers radar. But no, Microsoft decided that in certain conditions window must not crush. If exception occurs in such situations, framework will catch it and "handle" it by not doing anything. That's called silent failure. This is how it looks like when it happens within "window is about to close" event:


Do you see it? I made similar divide by zero error like on previous image. Take some time. It's hidden in the last line in the "Output" window at the bottom. On top of that full message doesn't fit the window. Now I hope You can understand, dear reader, why I was furious.

Reasoning behind silent failure is usually that end user is see less crushes. In my opinion it's just giving the sense of false security for end user and as demonstrated makes job unnecessarily more difficult for programmer. There is absolutely no benefit from it in "debug mode".

And in the end, how did saving settings prevented window from closing? Destination folder didn't exist. Normally when non-existent file is open for writing it is automatically created. Apparently creating missing folders is completely different beast but it's OK as long as I get informed when my presumption turns to be wrong.

četvrtak, 24. listopada 2013.

Building queue


I manged to implement building queue for colonies before real life caught up. GUI is not final, monitor I was working on was bad at displaying colors (light gray, such as window background, looks white) so I wasn't sure what the window looks like before I got a chance to work on another computer. "Under the hood" part is basically ready for accepting star system building queue.


This is how system view looks like now. Not much different from before but under the hood it's not a place holder any more. "Construction site name" panel is aware of selected body. So far this awareness is manifested only as an icon of first building in the queue. I have some ideas of what to display in place of "Construction site name" label but I'm still working out technical details. Idea is to have different name format for different types of bodies. Rock planets would be the usual star name + roman numeral such as Alpha Centaury IV for 4th planet around Alpha Centaury. For asteroids it would be something like "Asteroid belt at Alpha Centaury III" and for gas giants "Moons of Alpha Centaury VI". In both cases I'll have to support a way of injecting a text (such as a star name) in the middle of localized text entry.

Next update will come later than usual. As I said, real life got me busy so during the month I did next to nothing for the project and I got little tired from the last month. Not in a way where I lacked sleep but in a way where I've started to add stuff without the proper planning. I don't know how to describe but that makes me feel tired, as if mentally exhausted.


On the bright side, I finally managed to learn how to draw simple stuff in Inkscape. Alhough it's not on the same level as Paint.NET, it's good enough for my needs and better then any vector graphics tool I'll ever make. I've already converted a few old ship images from raster (PNG) to vector (SVG) format.

četvrtak, 19. rujna 2013.

Orbital habitation

Back in version 0.3 I've been thinking about adding orbital habitation feature that would allow players to populate moons and even planetary orbits. For the rest of the post I'll refer to moons and orbit as just orbit. I ditched the idea because I couldn't come to terms how farming and mining should cooperate with the feature. Should there be a limit how many miners can exploit the planet, should there be penalties for transporting goods from surface to orbit (because there is such penalty when building ships). Splitting colony to two, one for each "plane", would help organize the matter but brings another question. Since surface and orbit would be very different in productivity and construction costs,  should there be different building queues for each "plane"?

Recently I thought about bringing orbit back. Thing is, I wanted to make gas giants feel different from normal "rock" planets. Orbital habitation seamed as the nice tool to achieve that, normal planets would have a small orbital area compared to a surface while gas giants would have it other way around. Logic was that gas giant "surface" would be actually surface of it's moons and a "orbit" would be the gas giant itself. But same questions from 2 years ago made me to ditch the feature again. Instead I'll bring gas giant moons directly into play.

Firstly I'd like to add special traits to all planet types. Traits would be mainly negative stuff like acidic atmosphere (increased environment hostility), active vulcanos, large mountains (less inhabitable space). Occasional there would be positive effects such as active core (less radiation) or fertile soil.

Than I'd add moons in place of gas giants. Each gas giant would be represented with cumulative surface of it's moons and traits that partially affect colony, simulating diversity of moons. For instance Jupiter has 4 moons "worth of notice" so it would be represented with 75 size points (75% of earth sized body) with vulcanic (Io) trait that affects 1/4 of colony, water world (Europa) trait that too covers 1/4 of colony and some gas giant specific trait like cheap fuel (faster ship resupply). What partial trait coverage means is not decided yet. In the simplest case it would be simply reduced normal trait. In a more complex case it would kick in when colony starts to utilize that part of moon system. For instance Io's vulcanic trait would start affecting the colony once it's population grows beyond 75% of maximum with increasing strength as population reaches 100%. I'll decide it when I start implementing planet traits.

ponedjeljak, 16. rujna 2013.

Development topics

According to Ohloh there has been a lot of activity on the project lately. Most of it went to implementing techologies.

On GUI side there are only development topics but that was enough to drive that many activity. First there was mockup and stub form. Then custom control for items in topic list had to be created. It required view related data (image, topic name and level, development cost) which in turn required controller class which in the end required model data. Model data consists of three parts:
  • Static data: technology name, description, image, cost per level and prerequisite technologies
  • Game state data: researched level, invested points and priority
  • State change data: new priority
Static data and change data are new "flavors" of data and both required different treatment than game state data and tinkering how to implement. Speaking if radically new stuff in the code, there is an image cache feature on GUI side. Game model (core) is only concerned with image path and it's up to view to load it and store it. Image cache is, as you might have guessed, an associative table that translates paths to images by either loading them from disk or by returning already loaded ones.

That's all cool but what is new for player. Well, you can look at pretty pictures and rearrange them :). Being able to invest points requires three big things: colonies, system governments and turn processing. I think I'll tackle colonies next.

Also there was some polishing. System view can be panned left and right, texture atlas bug fix and new feature and textured wormholes!

četvrtak, 1. kolovoza 2013.

Progress report July 2013





As usual there was a lot of under the hood work and some visible changes last three months. As you can see on image above galaxy map looks like something: textured stars, wormholes, star names, selection indicator.
Some new functionality is there too, double clicking the star opens the star system. View is still stub though. A lot of stuff is stub right now but as I'm running out of stuff that can be stubbed real implementation is under way. I'm experimenting with my tool for procedural image generation in order to make better star images (different for explored and unexplored) and to make fair map. Currently I'm tackling the fair distribution of vacant star positions. It may sound weird to use image generation tool for prototyping galaxy generation algorithm but I must say is good visualization tool.
This is how the tool looks like. Parameters on the right and generated image on the left. When I have to change the algorithm, I have to go back to source code yes but when I want to try out the algorithm with various parameter values I can do that on tool's GUI. Images above visualize output of star positioning algorithm. Left image is star map with hidden vacant positions while on the left those are shown as dark grey. Light gray/yellow dots are positions for players' homeworlds.
Also finally, I've found a comfortable way for keeping "to do" notes. With graphs! GraphViz is amazing tool, if only there was good GUI for it. Maybe I'll make one in the future. To do graph is simple, everything starts from special "Features to do" node and branches out from it. In order to complete the game I have to implement this, this and that feature, OK, but feature "Fleets" is too vague and considers a lot of tasks so I'll split it to this, this and that subfeature and so on. Leaves (nodes without following nodes or "children") are either tasks that I can immediately start and finish within few hours or concepts that have to be more elaborated and split into smaller tasks.
I've tried something similar before, called it "Spec tree" but it didn't feel fluid. I almost started in-depth analysis of why but I'll just say that standard Windows tree view feels cluncky (even with drag and drop) and looks noisy. On the other hand editing textual file in Notepad++, running a command in Command Prompt and seeing a result in Photo Viewer on the other screen is somehow easier and more satisfying.

četvrtak, 9. svibnja 2013.

Progress report April 2013

 

Introduction


There was a lot of changes under the hood and even a few visible ones during the past month:
  • Meditation on game data model
  • Programs for creating images
  • Organized external dependencies
  • OpenGL graphics

OpenGL graphics


This is last thing I've implemented last month but it is the root of most work. Also it is only visible progress so I'll explain it first. Last autumn was making a program (called it Grid Pixel Canvas) for creating vector graphics images. It didn't go far because I haven't elaborated how should tools (for drawing dots, lines, curves, polygons) be used but it was a great exercise in learning OpenTK. OpenTK (open toolkit library) is a library for .Net that among the other things wraps OpenGL. Other wrapper libraries mainly translate C functions and constants 1:1 to C# but this one it makes it feel C#-ish. Constants are translated to enums, matrices are proper C# objects instead of plain two-dimensional arrays and so on.

Galaxy map in the Stareater is now rendered with OpenGL provided by OpenTK. So far the rendering only draws red squares in place of stars but it's a foundation I can build upon. Rendering loop is implemented in such way to minimize unnecessary updates on one side and to allow smooth animations on the other. All game engines I've previously tried, including the one shipped with OpenTK, simply redraw a scene as often as possible. Upside of that approach is maximal possible frame count per second but the down side are constant CPU usage and consequently bigger energy usage. Energy usage can be an issue on laptops because an application with 100% CPU usage can drain the battery in less than an hour, maybe even less then half an hour. Stareater is not going to be graphics intensive game or generally constantly computationally demanding so it will not be designed in a way that clogs CPU. Way it done now is with a timer that triggers refresh roughly every 10 ms.

Along with rendering I've implemented map panning and zooming. When zooming, the point under the mouse is fixed. I'm pointing that out because I had to do some matrix calculus on paper for that and I was proud when it worked :). Anyway no more jumbo picture box with scrollbars and glitchy panning.

Old data model


In order to draw something on the map, star locations have to be stored somewhere. Data model used before remake (prior the version 0.5) was clunky. It was classic object composition and it turned out that I needed something that looks like relational database. To explain this, the situation was along this lines:
  • Game object contains collection of stars and collection of players
  • Player object contains collection of fleets and collection technologies
Sometimes the game needs collection of fleets of a certain player and sometimes collection of fleets at certain location. Old data model made one query straightforward and the other complex. Getting players fleet would look like game.players[playerNumber].fleets. Getting fleets at certain star would require looping through all fleets of all players and check if location matches star's location:

Collection fleetsAtStar = new Collection();
foreach(Player player in game.players)
    foreach(Fleet fleet in player.fleets)
        if (fleet.location == star.location)
            fleetsAtStar.Add(fleet);

As you can see, the code is visually complex. Performance is suboptimal but not a big issue. Why I'm complaining about visual part, because the code that is easier to read is easier to fix and build upon. Another big issue with object composition is that temporary data (such as player's total research points) also has to live within objects. Well, it doesn't necessarily have to but it's hard to move it somewhere else.  In properly designed relational database data organization is radically different. There are no nested objects and certain mechanism, called indexing, allows skipping the majority of uninteresting data when searching for objects that satisfy certain condition. Example from above would look like this in a database:
  • Collection of stars
  • Collection of players
  • Collection of fleets with reference to owner (player) and location (star)
  • Collection of technologies with reference to owner (player)
Getting data from database is this simple:

Collection fleetsAtStar = db.Fleets.Where(
    fleet => fleet.location == star.location
);

Code for getting fleets of certain player would look the same but with different "where clause". Easy, isn't it? For those unfamiliar with the syntax of lambda functions, the parameter of where method is a function that takes a fleet object and decides if it satisfies condition (returns bool). Performance-wise this code is by default equal to nested loop from object composition example but as I said, database "tables" (collections of data of certain type) can be indexed.
Simply put index is kind of parallel collection that groups references to objects in primary collection by certain property. If the database query (such as Where method in the code example above) involves property that has been indexed than an the query would be reduced to finding appropriate groups and loop only through elements in those groups. And just to be sure, finding a group is faster (O(log(n))) then checking all groups but that's enough details in this digression.

Custom collections


I was really tempted to use a database to store runtime data. With SQLite and an adapter library the size of game would increase by 3 MB. That may not seam as a problem in post the ADSL era but upload speed at my location is horrible, space on Google Code hosting is limited, code repository get clunkier and it simply can be done with less megabytes. In fact I've found solution that is as big as few C# classes. When translated to machine code it's merely a kB or two. The solution is custom collection implementation for each "database table" that groups elements on their own and exposes those groups. Now the kicker is that I'm using T4 to generate code for those classes. Instead of copy-pasting and modifying same but slightly different code I can write no more then a dozen lines in a text template file and the C# class is generated for me.

T4 is a markup language much like ASP (or PHP and JSP) that allows mixing of content and generation logic. In this case the content is C# code. Generation logic is either VB or C# code that direct the flow of content generation. Sound like inception, using C# to generate C# code :). Another feature I'm using or even exploiting is including one text template file to another. One text template is a base, a set of helper methods and variables and class generator with placeholders. Other templates fill those placeholders and use base template to generate desired code. And they are quite short:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ include file="$(ProjectDir)/Utils/Collections/IndexedCollectionBase.tt" #><#
  
  namespaceName = "Stareater";
  usings.Add("Stareater.Utils.Collections");
  usings.Add("Stareater.Maps");
  usings.Add("Stareater.Players");
  
  Generate("VisitedStarsCollection", "VisitedStars",
   new GroupInfo("Stars","StarData","Star",ViewType.Collection),
   new GroupInfo("Players","Player","Player",ViewType.Collection)
  );
#>

First two lines are overhead, what langauge is used in template code and what extension to append to generated file. Third line includes the base template file. Next four lines fill certain optional parameters in base template and finally, call to Generate method fills placeholders and does all the heavy lifting. Parameters of that method are collection attributes (class name, type of elements) and group descriptors


New data model


After I got a way of storing data it was the time to see what data does the game needs and how exactly to organize it. To do that I went through all classes that contained some kind of dynamic data and plotted it on a graph. A tool specialized for creating class diagrams would be more appropriate but I wanted to learn and test the limits of GraphViz.

Analysis showed that the game operates with four kinds of data:
  • Static (doesn't change over the game, for example technology "tree" or types of ship equipment)
  • State descriptors (describes current turn, for example colony population or ship position)
  • Change descriptors (players' decisions such as spending ratios or fleet orders)
  • Temporary data (temporary values used when calculating the state of the next turn)
This figure show new data organization model where blue nodes are classes and gray nodes their properties. Static data is boring so I skipped it in the deeper analysis. Boring in a sense that they don't interact with or depend on other data, they are for all intents and purposes constants. Among dynamic data, state descriptors are the biggest. What surprised is that change data is small. Don't be fooled by the number of gray nodes in temporary data, effects are very big structures.


This is the graph of old data model. Rectangles are classes a ellipses are their properties. Property colors depict their placement in new model (green = state, orange = change, pink = temporary). Blue properties will be used as grouping keys and red will be either changed, moved to controller (layer between game logic and user interface) or removed entirely. Some nodes have multiple colors which means they multiple roles in new model. Names are copied from source file (plus prefix to make nodes unique since by that time I didn't know how to use a certain feature in GraphViz) so if you don't understand Croatian you may have a hard time to read the graph. That is one issues I'm correcting in current code rewrite, all code is being written in "common trade language" (English).

Separation of state, change and temporary data is perhaps the change with the biggest impact to the code rewrite. Partly because I didn't expected it when planning the rewrite, partly because it allows better separation of concerns and it improves readability.

External dependencies


I touched the subject of external dependencies earlier. Two new external dependencies were introduced to Stareater last month: NGenerics and OpenTK. OpenTK, as mentioned, interface to OpenGL (pretty graphics on user interface). It also provides OpenAL (open audio library) that may come handy in the future. NGenerics provides additional data structures that are needed in the code, namely priority queue, 2D vectors and graph vertices and edges. Those classes are relatively simple to write but I weighted that cost of the existing library is lower then reinventing the wheel. Size of the DLL is acceptable, about 160 kB. In my humble opinion it would be better if they have had split the library to a few smaller because serious stuff is mixed with educational (like gnome sort) and algorithms and data structures can be separated.

To manage external dependencies I learned and started to use NuGet. It's the tool for managing dependencies that integrates well with Visual Studio C# projects. For professional and higher editions of VS there is the NuGet extension. For others there is a command line tool which is fairly simple to use. The benefits of the tool are simplified installation of dependencies, easy updating and separation of library repository and code repository. Separation is neat thing because the versioning system doesn't have to track DLL file which can be quite large compared to the rest of the files.

Conclusion

Last month I learned a lot of new stuff in order to make a progress in the Stareater. I learned how to use GraphViz, NuGet and T4,  i4o and C# Expression Evaluator. Last two weren't used in the project but they were a learning material.

As usual, majority of progress isn't visible but will add it's value along the line. Now on the menu are the cool things: playing with OpenGL, exploitation of the gained knowledge, experimentation with starlane generation algorithms and experimentation with procedural image generation. Oh, now I see I haven't touched the subject of my programs for creating graphics. The post is too lengthy as is. I'll write about it some other time.

In retrospective, for me the blog turned out to be horrible medium for reporting progress. At first there is nothing to write about and then there are either many small subjects or a few hard ones. For instance, this post took me more than a week to write it. It was still April when I started. I could have used that time do work on the game. That's why I've decided to either blog even less often or write simpler posts and use Twitter in the mean time. Hash tag is #stareater4x.

ponedjeljak, 25. ožujka 2013.

New game finished

 
"New game" GUI is almost finished, actually it's in that state for few weeks. Part that currently stands between almost finished and finished is map preview. There are few things under the hood that have to be implemented beforehand so by the time the "New game" GUI is finished, the main game GUI will already be in the development. So I'll take this opportunity to write about new stuff in new "New game" GUI.

Obviously the current design differs from original concept (compare the image above with the image in the post from November). First of all the "New game" is not a single window in the process. Main window provides overview of selected settings and opens other windows for specific settings. I figured it would be cleaner to separate and have larger GUI form each group of settings than cram everything on a one big window.

Quantity and quality (color, organization, human or AI) of players is defined in "Player setup window". Once I get some spare time I'll add default "confirm" button to make it consistent with other windows and when I get sensible drawing tool (or skills) I'll add visual description for a player type in the list of players. Imagine it as human or computer icon inside color rectangle. What is not seen on the image above is support for multiple AI implementations. AI logic is contained in plug-ins, in DLL files that have one or more classes with certain interface. That way it's easy to add and change AI implementations and no implementation receives special treatment including my own.

Starting conditions setup window is for setting up initial population, infrastructure and number of colonies. I was thinking about having options for adding starting fleet and technologies but that is for future work when I'll have too much spare time :) (and when technologies and ship designs are reimplemented). Oh and one sexy thing that is already implemented are magnitude prefixes. Instead of writing 1500000000 simply write 1.5 G. Valid prefixes are k, M, G, T, P, E, Z, Y (as in kilo, mega, giga, tera, peta, exa, zetta, yota).

And finally the map setup window. Parameter assortment depends on map generators which are, like AI implementation, defined in plug-ins. Map are generated in three steps: positioning, connecting and populating stars. Positioning step determines number and positions of the stars. Second step connects stars with wormholes. In the final step star types are decided and populated with planets. Each of these steps is implemented in separate plug-in so it's possible to mod only part of map generation process while reusing other parts. In case there are more then one implementation for a certain step, GUI will show a dropdown menu for choosing one. Big black area is currently a place holder and will be used as map preview once I implement map generation steps (for now there are only interfaces and empty implementations) and draw new images for stars and wormholes.

As you can see there is a good deal of moddable parts. And there is more. As you may have seen on my main blog I've been trying out parser generators. One of result of such work is a parser that could crunch normal infix expressions. In previous versions of Stareater numbers in data files (such as food per farmer) were either constants or expressions in prefix or postfix notation (Polish or reverse Polish notation). Why were they in a text file instead in code in the first place? To make balancing easier (modding support is just a bonus). It's easier to tell a friend which number to change in text file than how to navigate and recompile the source code. And because I felt they are kind of configuration data and should be outside the source code. Now it's even simpler, with infix notation. I admit I overdid some things but I believe it will pay out. Just for the record writing a syntax for infix parser with proper operator precedence and associativity is less than 2 hour job but attributing that grammar (writing C# code for actions when certain terminals or non-terminals are matched) took me almost 20 hours.

Next thing on the list is to complete the map generator and have galaxy map rendered as soon as possible. I'll probably make simple map generator without resource balancing and making sure home systems are "fair" than implement map rendering and do the rest of the map generator afterward.

subota, 19. siječnja 2013.

Map generation pipeline

New game form is almost complete, all that is left is map setup GUI. That would be trivial if it was simple "select size" drop down menu but I want to expand it a little, I want to add more options. By default map is square shaped and I want to add means for defining different shapes such round or spiral. Instead of hardcoding few shapes, I opted for plugin based system where each shape generator is a DLL file containing a class with certain interface. Actually a single DLL file can contain multiple map shapes but that's technical detail point is, map shapes are .Net code that is outside the main executable. That was the idea before I've started implementing new game GUI. Thing I realized yesterday is that code for positioning stars is short compared to the rest of the map generation code (assigning star types, populating stars with planets, ensuring balanced distribution of "good" and "bad" planets) and that I or modder would want to reuse that over multiple map shapes. That made think a little bit more, define the map generation pipeline and decide what would be moddable and how.


Looks simple and trivial and that is the power of documentation (that I can't stress more). In star positions phase, as mentioned positions for the stars are calculated but stars are not yet generated. In the next phase
star types and sizes are decided. There potentially could be more attributes such as space monster lairs or alien relics but at the moment they are not defined. In parallel to that phase can go the phase where "starlanes" (or wormholes) are distributed. Planet distribution phase and planet attributes phase may actually be single phase. Anyway those two phases fill star systems with planets and calculate attributes such as planet size or environmental conditions.

Potentially each phase on the flow chart can be made moddable but at the moment I don't see the need for that extreme. For now I'd group those five phases to two groups: star graph and planet generation.


Odd choice is putting star attribution to planet generation. The original idea was that star type directly influences distribution of planets (both positionwise and typewise) in the star system. Putting star positions and starlanes in the same bucket may reduce the code reuse a bit but it simplifies interfaces for plugin code. I don't know, may I could split them somehow without "void *" arguments and with the fewest presumptions.