ponedjeljak, 28. prosinca 2015.

Preview release v0.4.2

Finally the project has reached some presentable level. It's still rough around the edges, not too user friendly but if you want to see for yourself where Stareater stands, here is a downloadable package.

Download Stareater v0.4.2

Package is a simple zip file, extract it and start Stareater.exe. Since it's .Net application under the hood it should work on Windows out of the box. If you have really old windows machine then you might have to install .Net 4.0 framework. The game should also work on Linux and Mac with Mono. Please report any issue you encounter either in the comment section on this blog or at GitHub. Especially if you encounter graphical bug where objects seam to be drawn in wrong order like star names below wormholes.

Have fun!

srijeda, 16. prosinca 2015.


As you might have guessed from previous posts, colonization has been implemented. Like some other features it was not a direct translation from CroVar iteration. In CroVar version colonization followed traditional Master of Orion I steps: bring a colony ship to a star system and land it on an empty planet. Additionally you could bring multiple colony ships and choose how many will land on which planet. Multiple ships on the same planet would establish a bigger colony. This is how the GUI for it looked:

Planets in the system are on the left side, information about a selected planet and estimated productivity are on the right side and a number of ships to land is selected with a slider below it. At first I thought about doing the same in this iteration but certain discussion on Wargaming's Master of Orion forum nudged me to think about other possibilities. In Master of Orion II there was a way to arrange colonization from a planet list. There was a screen with a list of planets which could be filtered and sorted by quality and size. Once you've decided which planet was the best candidate you could select it and press a "colonize" button. If you had available colony ships the game would direct a nearest one to the planet's star system and following turns the ship would fly there and land. Now don't kill me for bringing Master of Orion III up, that game went one step further in not necessarily bad way. There you could zoom in to a star system, mark planets for colonization and your unquenchable AI viceroy would build needed colony ships and send them to the planets.

I've decided to do something similar in the Stareater. Marking an empty planet for colonization creates a colonization project and on colonization screen you can decide which star system will build colony ships for which planet. Once built, colony ships will fly toward to planet and wait until there is enough of them. When minimum population has been accumulated, a colony is established.

GUI could use more work but that would be a job for another time. I've been looking around and there is an interesting GUI library for OpenGL, it's not so well maintained but I'll keep it in mind for that sunny day when I'll be converting Windows forms GUI to OpenGL. Now next on the menu: space battles!

petak, 11. prosinca 2015.

Stareater iterations

Before I move to the next topic I'd like to make a little intermission. Stareater is long running project, it's about 7 years old and yeah, still not done. I admit I have taken on very ambitious goal back then but instead of giving up when things got over my head I have started over. If you have been following this blog you'd noticed just that, the current programming effort is a rewrite of the previous iteration. What might have been lost to time is the fact that there has been one before that. Below is a short description of each iteration and names I made up just now so I can refer to them in future posts: 
  • DIY or "do it yourself" was the very first incarnation of the Stareater where I have literately went by coding everything myself in C++. Only "others" work I took was OpenGL for graphics and GLUT for "windowing" (how application window is started and managed) and mouse and keyboard input. Unfortunately such ambition had to hit a brick wall somewhere and it was in GUI department. Making GUI engine from scratch is science for itself and I've spent more time on it then making an actual game. Since I didn't take robust enough approach it got really tiresome. DIY iteration ended with pretty beautiful galaxy map (stars only, no planets), map navigation and minimal GUI for starting the game.
  • CroVar or "Croatian variables" began as GUI mockup project for DIY iteration. It was C# Windows Forms project and at some point I realized I'd be happier to spend more time on game logic and keep GUI effort to a minimum. So I filled in mockups with a actual game logic from DIY and somewhere along the line I've decided to use Croatian words for class and variable names. That's why I'd call this version CroVar. This iteration got pretty far, stars, planets and colonies were fully functional, planets could be colonized, ships could be designed, built and moved, foundation for AI was laid down and even space battles worked!
  • WhyNot is the current iteration of the Stareater. At some point CroVar code got big enough mess to consider refactoring it. At first wanted only to make better separation of GUI logic and game logic but I figured I could fix many other wrong decisions made in CroVar. And it resulted in a total rewrite with good amount of why not this too additions? In all seriousness "why not" approach saved me a lot more trouble than it has brought me and it improved the quality of the code and final product. Mod files got more intuitive format, OpenGL graphics are back, it got easier to code new features and simplified changing and maintaining old features.

utorak, 24. studenoga 2015.

Fleet movement

Next feature on the completed list was fleet movement. Well sort of completed because it was refactored while doing colonization (more about it next time) and there is an open question of how to propagate information about multiple missions to GUI.

Let me start from the beginning, in the last iteration of the project I made two collections for fleets, one for stationary and the other for moving fleets. Reasons were difference in data structure, moving ones have current, start and destination positions while stationary only have current position; in visualization, stationary fleet marker should appear next to the star instead in the center of it; and in some internal logic. In the current iteration I wanted to unify those two collections for easier handling and I did it by introducing the concept of fleet missions. I started by giving stationary fleets a "stationary" mission and moving fleets a "move" missions and while most parts got simpler, some were not in the best shape. With only two things fleet could do there was no need for spending more time on the topic.

That changed when implementation of colonization started. At first I started by making separate collection for colony ships but then I've realized it won't make stuff simpler. It worked well for colonizing within a star system but when it came to moving ships to remote stars I had to either duplicate the code of normal fleet movement or unify colonizers with regular fleets. Guess which path did I choose, more complicated one with better scalability. And on top of that I've pulled out visitor pattern. It was like climbing uphill a bit be rewarded with relaxing bike ride downhill. I've changed fleet data from having a single mission to having a list of missions which combined with visitor pattern led to simpler code, believe it or not. Missions themselves were changed, descriptor for "stationary" mission was removed, now fleets with empty mission list are considered stationary, "move" missions have reference to star lane they are using instead of starting star (which was used to deduce whether star lane was in use or not), "move" missions also have reference to only one destination instead of all waypoints (not yet implemented on GUI but planned for future) and "colonize" and "skip turn" missions were introduced. "Colonize" missions does what you'd expect, marks ships ready for landing and establishing a colony. "Skip turn" also does what the name says but the reason for introducing it was to prevent colony ships from having unfair advantage over normal ships by taking action on the same turn when they are built.

In the Stareater I aim for having strict rules about what happens when. Construction is an action that takes a whole turn so when a ship is built it should act as if it (or should I say "she", I find it weird to refer to ship as she, partly because it's inanimate genderless object and partly because in my first language and in German the ship is "he") has spent it's turn. Since colonies and stellarises (made up word for star system wide government) are processed before fleets and colony ships are built with non-empty list of missions, colony ship could colonize a planet within a system or move toward destination on the same turn it was built. Explicit "skip turn" mission was a way to prevent that.

Finishing fleet movement allowed for tackling more features. As you might have figured out colonization was next but it's worthy to mention that also brought me one step closer to implementing space combat. And I've decided to make it more interesting then it was in last iteration.

petak, 23. listopada 2015.

Turn reports

Oh boy a year passed already! I'm  alive, the project is alive and real life is real. There has been steady inflow of features in the Stareater despite steady inflow of real life distractions. Turn reports were first thing implemented after game loading. Oh boy, that was almost a year ago! Please feel free to contact me, comment below or in any other way ping me when I go silent for so long.

Anyway, I have finally found a proper solution for the under the hood details for report handling. Problem in the previous iteration of the Stareater was all kinds of reports (discovered technologies, buildings built, built ships) where contained in a single container and logic that handled openning a particular message had to perform, a not exactly object oriented, type checking. Technology related messages should open either research or development GUI, building completion message should open colony screen of the colony where the building has been built and so on. Back then I've included type information to the base class (those not versed in object oriented programming, base class is sort of common data and functionality for different data types that build upon particular base class) and "open message" logic simply asked a message are you type A, are you type B, ..., are you type Z. Action taken depended on which question was answered with yes. This was simple enough but there were few issues with that approach:
  1. Each data type already contains type information (programming language feature)
  2. Message "consumer" has to keep in mind which message types there are
  3. When new message type is added each message consumer has to be manually located and inspected for an update
Technically I could have used built in type information but back then I was quite stubborn with not using the black magic of code reflection and in the end it would not make much of a difference. True solution to the problem was so called double dispatch and the "visitor pattern". Double dispatch means action taken (function/method called) is deduced from two parameters, in the case of turn reports those would be message type and consumer type. Since C# doesn't have ready syntax for double dispatch, visitor patter is one way to emulate it. It's a design pattern which I've encountered while looking for parser generator for something in modding logic and at the time I didn't understand it because it requires a shift of perspective. Imagine a situation where Alice boards a train, normal sentence would be "Alice boarded a train" but in visitor pattern a sentence has to be paraphrased as "A train was boarded by Alice". Once I understood it, the pattern was perfect match for the problem. There was no need for explicit type checking and the pattern has nice feature of ensuring all consumer types know about and can process all message types. When adding a new message type, a single update to the base message class would cascade the update to all consumers.

All that said, user interface could use some more work and message filtering is not implemented. I'll make filtering later when I add more features and see what needs filtering. Polishing interface will also have to wait, I'm looking for alternative to Windows forms, preferably something with OpenGL rendering, so I can have more control over the look and feel but not to go all the way back to reinventing the wheel. GWEN.Net is in the consideration but I have to test it more and the whole thing is low priority for now.

Stay tuned for info about other features completed over the year!