Pages

Wednesday, July 21, 2021

Beta test

Or should I say a month of playtesting. A good number of bugs are identified and fixed and publishing a pipeline (to beta test at least) is established. Also, the game UI finally looks like a game UI.

At least that was the state of the game in May. This is going to be a long post, game development is going faster than blogging. So let's begin. Here is the trailer! And information about how to join beta:

It took me a number of attempts to make this video and it shows. I have decent experience in chopping and compressing a video but this was my time composing one out of multiple pieces. The audio was the easiest part, I wrote the text, tried a few recording programs, a few microphones, and read the text the best combination. In principle that is. I had run through multiple drafts of the text because the speech is not a blog post. You have to use simpler sentence structure, watch your breath and rephrase hard to pronounce words. But at least it was quick and easy to iterate. I settled on recording one paragraph (2-3 sentences) multiple times at the time and stitching the best takes in one audio file afterward. Getting video footage was a mess. The game is not integrated with Google Play Games so I couldn't use their screen recording feature, which is otherwise very ergonomic and makes good quality footage. So I had to look for other programs and make do with a barely passable one. Composing a video out of multiple ones was an even bigger mess. I was unable to find a good no-fuss program for it so I had to stretch the capabilities of a tool I worked with before. It again took multiple tries to get desired clips out of recordings because the tool doesn't like making cuts at arbitrary frames and appending multiple such hack job video files often resulted in the glitchy final video. It was the FLV encoder that saved me from non-keyframe cuts hell. And now, now the game is changed so much that I should make another trailer... I dread about it but I'm prepared with better software now and all I really need, besided courage, is to find the time to make the footage.

Ok, so the trailer got uploaded, the link posted here and people came, and then what happened? I'll get to that, after elaborating one little detail. Getting a beta test invite link requires basically having an app published, which means, filling in more forms, figuring out app signing, getting comfortable with the release treadmill, and then wait for a few days to get the app reviewed. The upside of the process is that Google will do some basic app tests for you and the results could be useful for improving the app. Automated tests do have trouble with navigating game map because they don't do touch gestures but they will do everything possible on regular UI widgets and report all sorts of accessibility issues. Also, Google will try running your app on older devices if you declared it should be compatible with them. This test has found (crashed) a few places where the game was using functions unavailable in the old versions of Android.

Ok, so people came, and what happened? When you present a program to the general public, keep in mind that most feedback will not be aligned with your plans for the project and that requests for additions of a similar kind will not be uncommon. Don't get overwhelmed by it, keep calm and try to compromise.

I've limited promoting the game so I got about 10 beta testers. Most of the requests were for more role-playing features. Ones that come to mind are flag emblems, named fleets, and AI personalities. But the most requested change was to make a black background. Since the game kind of already had that in the form of the night mode theme, I made the night mode the default.

At least that was the first step. The second step was to make properly set up application's theme, for both night and day mode and both portrait and landscape orientation. This took the most of the May, mostly for learning which leavers to pull to get the desired effect. But there were also trials and errors in making and setting button and panel background images. Android, especially older OS versions, has very limited support for stretchable images, both in terms of capabilities and documentation. I managed to get things working under imposed constraints but it's not foolproof there are still some quirks remaining I cannot find a solution for.

Other smaller improvements done during the month:

  • Fleets can be redirected in flight. Immediate destination (first waypoint) still can't be changed, the rest of the path can be. The idea is that once you send a fleet it is committed to that destination but everything beyond the first destination is a future order and therefore prone to change. 
  • Star type and star trait are listed in the star/colony info panel.
  • Speed boost technological is effective only between own colonies. The idea is to help speed up ship deployment but to still have an advance warning when being attacked.
  • The game now tracks how many qubits you got from each source instead of one total number. This makes it possible to change rank-based rewards in the future and consolidates data for rewards like beating previous survival record.
  • Players are first ranked by whether they survived until the end of the game or not and then by score (within alive and eliminated groups). I entertained the idea of having it possible for an eliminated high scoring player to rank above an alive but low scoring one but this would defeat the point of making a big alliance to take out dominating player and just make alive players postpone concluding a finished game until they outscore eliminated players.
  • Computer players now gather at least 3 combat ships before attacking. It's a quick and dirty patch for preventing bots from sending ships one at a time in the early game and just losing them without incurring any damage to an enemy with slightly higher defense tech.
  • Research points each player gains is not affected by combat outcomes (such as losing a colony). The amount shown in the research screen is guaranteed and technology advancement happens after combat.
  • Survival threat ships spawn at random locations outside the map. Quick and dirty partial unstub of this part of the game until I come around implementing it properly.
  • Save file can be exported so if the game is crashing in certain situations, you can help by sending me your save.
  • Infrastructure for upgrading save files when the game updates, since now there are players other than me.
  • Optional ads at the end of the normal game to increased qubit reward.
Bug fixes:
  • Fleet orders are properly saved.
  • Computer player logic starts properly in survival mode.
  • Computer player war declaration trigger properly calculates ally strengths so it doesn't change its mind about relation with the strongest player every turn.
  • Computer player doesn't crash when sending troop ships.
  • Colonization news when the whole map is colonized happens only once per game (was repeating itself every turn).
  • Attempting colonization on the already colonized world doesn't prematurely end turn processing anymore.
  • Selecting an object on the map doesn't change orders given to a previously selected one. Before, selecting an uncolonized star you don't want to colonize would remove colonization order from a previously selected star, and the same happened for stimulation and factory prioritization on own colonized stars.
  • Star name uniqueness is guaranteed.
  • Technologies can advance by multiple levels if there are enough research points.
June
 
Most of June was spent improving rendering performance. Yup, even a game as simple as this can have FPS issues. Occasionally at least. Just drawing the map was pretty fast but any map transformation (panning and zooming) would create a lot of short-lived objects, resulting in a performance drop on older phones. Improving the performance was tricky. An initial approach was supposed to be simple, just delegate translation (result of panning) and scale (zoom factor) numbers to the drawing API. But this also scales things you don't want it to: line thickness and text size. For such cases, I still had to make "manual" transformations but I've tried to minimize the work that happens there.
 

Another big thing, simply due to the amount of ground to cover, this month was more info in the game. You can long tap on almost any UI element in the game and get clarification on it. This is akin to right-click in Master of Orion 2 and Master of Magic.

Other smaller improvements done during the month:

  • Limited player length to 2 to 100. 
  • Changed starting conditions, each player starts with a fully developed colony and one cruiser to start scouting with.
  • Perform negotiations with other players by long taping their names on galaxy map info sheets.
  • Increased research benefits to x1.2 per level and changed research cost. The first few levels have handpicked costs and later levels grow by factor x1.5.

Bug fixes:

  • Diplomatic contacts are checked when the game is created.
  • Prevented homeworld placement overlap that was causing players staring eliminated on a crowded map.

July

As of yet, July doesn't come with big works like the previous two months so I seized the opportunity to tie up some loose ends and add improve gameplay. One thing I wanted to do for a long time was to add cheats to speed up testing new features. Like being able to see the whole map when working on graphics or jumping straight to survival mode when working on it. Until now I was modifying code to achieve that but that was always running the risk of inadvertently slipping into an official build. And if nothing else, remembering the place I need to hack to get a certain cheat got old pretty fast. Formalizing cheats into app feature neatly solves those problems and it's easy to limit it only to development builds.

Cheats for ending the normal game greatly helped to test the survival mode, which I wanted to align with the design document. Now the replicators don't send their probes before turn 100, if you manage to end the normal mode before it, and their escalation progression counts from that moment rather than from whenever the survival mode was started. This is mostly to prevent players from building up the economy before entering survival mode but also to not overwhelm players who start the mode early. Another major survival mode change is how replicators move, now their fleets attack a colony that is nearest to their spawn location and then moves toward the center of the map, taking time destroying colonies along the way. Once they reach the center, they stay there, I'll have to come up with something more interesting. Also, replicators now have more varied ship types in the fleet and their tech progression is slower.

Survival mode UI was also improved. Contact list now sorts players by population since the score makes no sense in this mode. Population count is also a good indicator of how long a player can withstand a replicator threat. A moment when a player is eliminated is tracked by the game and game over screen for the survival mode ranks the player in order the managed to stay alive.

Other smaller improvements done during the month:

  • Ground defense troop growth speed is tied to the number of factories. Previous constant growth was too fast and messed with bombardment a lot.
  • Rebalanced bombardment by increasing base bombardment damage and having chemistry reduce received bombard damage. This way early game when you have a few ships, the bombardment is strong enough but doesn't become overpowered later on. 
  • The star with ancient megastructure is guarded by high-tech hostile ships. My favorite strategy for getting an advantage over computer players was to colonize central star early. Admittedly that was super unfair and needed to be nerfed.
  • Info sheet raised/lowers state is preserved when ending a turn or rotating a phone. It was annoying to me to have the colony info sheet disappear when ending a turn, every turn. Now I only need to figure out how to keep a fleet selected over turns.

Bug fixes:

  • The game ends when a human player is eliminated. It would be an interesting feature to see the computer playing against itself, may I'll implement it in the future. Until it's formally coded, there is no point game going on without a human, both normal mode and survival mode.
  • Survival can't be started if a human is eliminated.
  • Fixed crash when 5 player game ends. An interestingly specific corner case :).
  • Fixed normal game always giving a maximum reward. For some reason, the reward was determined at the start of the game and updated only when loading a game (when a particular object was recreated).

Friday, April 30, 2021

Month of polish

How would have thought that polishing UI would take so much time? Or conversely that there are so many UI components to pass through in such a simple game.


But don't expect fancy graphics and sci-fi fonts just yet. By polish, I meant raising UI from "just enough so it works" to "not an eyesore anymore". This still required checking placing and spacing of elements, adjusting their size, making the stuff that can grow large is scrollable, and repeat all of that for the landscape mode. Yup, you can play the game like a game now! Though I find portrait mode more practical for mobile apps, especially when not seated, stuff just looks nicer in the landscape mode when an app supports it adequately. I'll add some fancy sci-fi look and feel down the road but I have to first decide on a general theme of it.

Along the way, the contacts screen got renamed to diplomacy and made into the list of the known status of all players. It shows your relations with them (peace with uncontacted ones) and a score of all players, including yours. The screen sort of doubles as a leaderboard now.

Qubit spending screen got a little bit of functionality change too. You can't reallocate bonus levels arbitrarily anymore, you can only refund the levels you bought in the current turn.

Global news screen got a bit of controversial update, it shows a banner ad below news text. I'm not a fan of advertisements either but I'm not making this game entirely for free. There will be some monetization in it but I promise there will be no evil schemes. The banner will show only on the news screen, the galaxy map screen will be free of ads forever, and the news screen will not show for minor news if a certain number of turns did not pass since the last news item. Why did I decide to put an ad banner there instead of a more prominent place then? Well in most games a news screen (like GNN in Master of Orion games) is made to look like a funny version of real TV news: anchorman, news text and image in the primary screen area, and some white noise running at the bottom, usually a scrolling text with some jokes. In a way, I've placed an actual advertisement as a joke. Hopefully, you won't find the fact offensive.

There were some minor gameplay changes implemented this month. Restrictions on what you can see on the map are now enforced properly:

  • A star needs to be scouted in order to learn its planet size
  • A star needs to at least be inside your vision range to know if somebody else has a colony there
  • You need to have a fleet at the star to see other's colony population and factory count
  • You can only see the immediate next destination of other's fleets, not all waypoints
  • As before, other's fleet has to be in vision range to know about it at all

And there were some bug fixes too:

  • The colonization checkbox won't flip its state when clicking around the map anymore
  • Another case of a computer player hanging in an infinite loop fixed
  • Research progress not working properly after loading game fixed

The problem with the colonization checkbox was basically that the Android UI framework, like many other frameworks, doesn't make a distinction between user clicking/taping a checkbox and code setting/clearing check mark. So when selecting one uncolonized star after another, without deselecting or selecting some other type of object in between¸ the UI update logic would inadvertently set the colonization checkbox of a previous star to the state of the next one.

The research progress bug was an interesting one, after loading a game it was possible that multiple research fields (across multiple players!) would get research points simultaneously at the end of a turn. After loading, multiple research fields would share the same research progress describing object so investing points in one of them would advance all with the same object. It was hard to pinpoint down the exact moment when that object would get shared because save file data would look normal (no object sharing) and for no visible reason research loading code would make some objects shared and some distinct. And it was a single line of code on my side manipulating a data structure from a standard library, so a debugger could not step inside and let me see what is going on. After reading the documentation on that data structure (HashMap) very carefully, I've learned it doesn't behave as it does in other programming languages. Java Maps and their subclasses override default equality functions so two maps will show up being the same if their key-values are the same. In C# and other languages, the usual practice for collection's default equality function is to just check if memory addresses (references) are the same and have a separate function for testing item equality. Fortunately, the fix was not that difficult, I only need to change how caching identifies which objects have been loaded and have cache users work with that identifier. Each saved object already had a textual name so I just used that instead of a reference to the object's save data.

Wednesday, March 31, 2021

Phase two progress

The game development is progressing, a bit slower than the previous year but it is progressing.

I should really make some more descriptive names for the development stages. Phase one, two, three are not descriptive at all, and alpha, beta stages are not applicable. By those labels, the project is still in pre-alpha and will be for some time. Let's call phase one stubbing phase because in that phase all features are technically implemented but with stubbed details. Things that are left out are mostly content, say for "the colony builds ships" feature, the code for building queue and general construction item is written but there is only one ship type to build, just enough to test the feature. Parts of logic that are left out or stubbed are mostly ones that give a game feel but don't affect the structure much. For instance, for the map generation, it's enough for the first phase to have it place player homeworlds at the first few stars in the internal star list and have the proper placement be implemented in the second phase. Consequently, let's call phase two the unstubbing phase, where loose ends from previous phases are addressed and the actual content is added. This phase still has a lot of work to do so I'd add a third phase for fully finishing (polish, test, release) the game.

Stuff done since the last post:

  • Game creation settings - map size, player count, human player name, and color
  • Players can have one of 7 colors
  • Unstubbed map generation
  • Map zoom and pan limits
  • Different star types
  • Cyclic building queue
  • Factory count can be fractional, like population
  • 3 combat ship types
  • Constrained ship movement
  • Pathfinding
  • Unstubbed computer player logic
  • Player scoring
  • Players can have custom supplementary data
  • Qubit bonus cost increases with level
  • Graphics (serviceable, needs improvement) for all ship types, factories, and icons on a map screen
  • Improved ship movement visuals (not hidden below star when starting, the icon is facing movement direction)
  • Graphics for each star type and trait
  • Decimal number formatting
  • Automated tests for utility code, almost all colony features, space combat
  • Automated test integrated with repository host's CD/CI pipeline
  • Various bug fixes
  • Various code refactoring
  • Design document
  • App store listing and release draft

Looks like a lot but it has been 3 months, and real life situation that prevented me from posting updates here also prevented me to do more development. Even after accounting for repurposing blogging time to actual development and hours not reported to a time tracker (prototyping graphics, fill out app store information, writing design doc), time spent on the project has been about 1/3 less than in October and November last year. There was definitely some execution friction too. Having worked for years on the Stareater, I'm very comfortable with the stubbing phase and pure coding. The unstubbing phase feels very different, there are a lot of non-coding tasks and coding too is different. You have to make sure the game logic works for all inputs, not just ensure that code compiles and doesn't crash. This increasing the pressure to have good automated tests which in turn begs to have a thorough document describing which features the game has and how exactly do they work.

Computer player development was an interesting experience. Again, an area I only dipped my toes a little until now. I tried to make a simple implementation of every major area (scouting, colonization, ship movement) but almost all areas quickly grew in complexity. Then I decided to write in plain English words how a bot utilizing all game mechanics should behave and then turn those words into code. 90% of bot logic ended up being information analysis, 8% selecting the proper amount of assets, and 2% actually giving orders. I haven't fully play-tested it yet but it appears to be good at scouting and colonization. Diplomacy logic needs more work, at the moment it doesn't consider who is where on the map so it may declare wars that make sense from a relative strength perspective but not a map situation. Attack staging logic should be improved too because if war breaks out too early it will send ships one by one and just lose them without inflicting any damage.

Adding ship types, star types, and changing movement logic were more of standard coding tasks. New ship types have a rock-scissor-paper relationship when it comes to the space combat cost-effectiveness and they behave a bit differently outside of the combat:

  • Battleship - strong against cruisers, expensive, good at bombardment, no movement penalty in a nebula
  • Destroyer - strong against battleships
  • Cruiser - strong against destroyers, no movement penalty in an asteroid field

I'd like to add more galaxy speed to cruisers and something to destroyers but nothing natural to an anti-armor unit comes to mind at the moment. Star types for now only affect ship movement speed when leaving them but there too I'd like to add more later:

  • Normal star - no special effect
  • Dwarf star - double ship speed
  • Giant star - half ship speed, would like to make it have smaller colony size
  • Dense asteroids - all ships except cruisers have half speed, would like to add production bonus
  • Nebula - all ships except battleships have half speed, would like to add the ability to hide ships

Ship movement modifiers are just the tip of the iceberg of the new movement system. Now ships have a limit to how far they can move at a time but by doing multiple hops they are free to travel anywhere. The hop range is about 2 star distances. The idea is basically taken from tiled tactics games, enemies should not be able to just move through each other without triggering combat but otherwise, the space should be open to interstellar travel.

Introducing multiple ship types invalidated the idea that a warship is implicitly at the end of a building queue because there is now a question about which type of warship. That's why there is a cyclic queue feature, you have to enqueue warships types manually but they will rotate in the queue as they are built. So once you set up desired fleet composition the colony will continually produce it.

At this point, I've regretted not having automated tests. There were multiple combinations of repeating and non-repeating construction projects I had to manually test after every single change to the building queue code and each run would uncover a faulty scenario. Manual testing didn't take so much time, about an hour in total, but I feel like I've aged for a whole day in the process. Making an automated test for a game was a bit of unfamiliar territory for me but it turned out making a minimal game state for a test was an easy thing. In a Java/Kotlin project it is very clear what is a "normal" code and what is a test code so you can have tests reach into what would otherwise be internals of the module and not have the test and test supporting code included in the release build. In the process, I dipped my toes in the CD/CI + Docker fanfare and set up a pipeline on the code repository host that runs tests on every code change upload. Not super useful, especially due to the limited monthly time budget but I learned some cool tech and I can set up something similar locally to trigger on every upload attempt.

Admittedly, code coverage is not that great at the moment. I'd say slightly less than 10% and the thing that needs improving first is how to tell what needs covering. Test framework can calculate line coverage but that's a very flawed measure that at very best overestimates the coverage. Having a branch coverage figure would be much better but ideally, there should be a way to tell how many features are covered. I'm trying to think of something that would do like that but for the time being, I'll have to rely on fallible human brain to sync tests with the design document.

This is the first game, heck first program, I have made a complete design document. It took a few failed attempts on other projects and three on this one. Almost a year before I've started coding Ancient Star, I've drafted a high level design document. From it, I've removed a bunch of features to simplify the game and made another document. But both of them were not really useful so I've made a third one, with low level details, explaining every detail of the game rules. It is 10 pages long, plus table contents covering a whole page height. And this game is supposed to be simple!

Not being an artist I've managed to make some decent looking graphics past few months. Here are star types (the last one being a normal star with the "ancient star" trait):


I'm proud of the result but don't ask me how I made them. Hint: they are coded rather than drawn. Ship images are more of traditional drawing, made in Inkscape, measured, and rewritten to SVG instructions. They are so so, not very pleasant but at least they are distinct. I'll rework them at some point. Here you can see ship images along with other graphics (factory, research, diplomacy, supply icons):

And last non-coding task that is more or less done is apps store listing. All the necessary "paperwork" is done, data is entered and a test release draft (signed app package) is made. I'd still like to do another pass on the long description, make proper a feature image and add more screenshots before hitting a release button for real.

Thursday, December 17, 2020

Ancient Star - phase one complete

Diplomacy, vision range, and survival mode are implemented. This concludes phase one of the project where all major game features are implemented in at least rudimentary form. Two weeks ago I wasn't joking about the phase getting nearly over.

Once you get the other player (ship or colony) in your vision range the diplomatic contact is established. From that point, both parties can select the desired relation toward each other. Relations are war, peace, and alliance and the effective one is the worst one the involved parties have selected. If one side has selected peace and the other side wants alliance then the peace will be in effect. So war is the easiest to declare while the alliance requires the will of both sides to ally.

By default, players are at peace and it takes a declaration of war to be able to do any combat action. For now, alliances don't force any relations and military action to third parties. They are purely a peaceful way to end the game. Once every player is in an alliance with each other, the game ends. It sounds cheap but remember, there is a ranking system involved and not everyone will want to end the game while they can still improve their standing.

Once the game ends the player is rewarded with qubits and has an option to start survival mode. Yup, there is a premium currency in the game, and I promise to play nice with it. In the survival mode players fight increasingly stronger waves of enemies coming outside of the map and the goal is to stay alive as long as possible. Also, in this mode qubits can be spent on additional bonuses. For now, the bonuses are bigger industry, ship attack, and ship defense multipliers per technology level.

The next step is phase two, of course :). In the second phase, I'll work on improving the quality of the game, do the preparation work for publication on Google's Play Store, and at the end of the phase have the game available for beta testing.

Friday, December 4, 2020

Ancient Star - basic AI and news screen

With AI infrastructure and news screen, phase one (basic feature implementation) of the project is getting very close to being completed.

Having calculations run in the background and affect UI at the end turned out to be very simple. So now there is AI that controls "bot" players and plays them all in parallel in the background. It has very basic logic for now: build scouts, visit unscouted stars, build colony ships, and colonize everything available. In the future, the logic will be more elaborate and goal oriented.

This required some changes to the code structure. Controller classes players use to read and manipulate the game state have been moved from UI to game core subproject (where game data and game logic is) so in theory, AI can be coded without being a part of an Android application. And the other change was to how a turn is ended. So far the human player had absolute control over the matter but now each player marks their turn as ended. The next turn is processed when all players have ended the turn.

When a certain portion of the map is colonized news screen triggers, informing all players about the event.
 

Again, a simple-looking feature that had more going on under the hood. Now there is a proper concept of player events, uniting tech advances and news items. On a new turn, UI runs through the list of new events, switches to relevant screens, and moves to the galaxy map once all events are cleared.

Monday, November 30, 2020

Ancient Star - autosaving, money, Orion?

The feature "to do" list is getting smaller and smaller. This week three features got implemented: a special star, monetary colony stimulation, and autosaving and continuing a game.

The reason why the game is named the Ancient Star is that there is a special star on a map (for now in the center) which holds remnants of an ancient civilization. Colonizing that star will grant a considerable research bonus to the owner and will be the center of a conflict after the end of a normal game. There is more foundation for future work there, all stars can have a trait and "ancient" is only one of them. In the future there will be more traits, affecting ship movement and colony productivity. I'll come back to this after I implements movement range limits.

Next feature this week: money. Money is gained passively from the population working in factories and can be spent on multiplying colony productivity (both industry and research). For now, numbers are 0.2 credits income per manned factory, and spending 1 credit yields the same amount of industry and research as 1 unit of the population would produce. Money doesn't improve ancient ruins bonus and research during construction. Initially, money can only double colony output but each point of sociology tech improves that multiplier by 10%, exponentially. So later on stimulation can seriously jump-start fledgling colonies. Also stimulating multiple colonies without big enough cash reserve will spend whatever cash there is (tax income + cash reserve) equally over all stimulus receiving colonies. So if you stimulate all of your colonies you'd get a 20% boost.

And finally, I've recovered from serialization burn out and integrated the thing with the rest of the game. Now the game will autosave when you navigate away from the galaxy screen or the game app as a whole. When the autosave file is there, the game can be continued later on.


Friday, November 20, 2020

Ancient Star - game over

Now that there are means to end the game (bombardment and ground combat) it is a good time to make the ending itself.

Many 4X games are about the journey then the destination and some of them tend to have no fanfare at the end because of it. This bugs me more than it should, I like to finish all my games and the lack of acknowledgment at the end feels unsatisfying. That's why I've made it this "early" in my project. It also makes me think more about the overarching question in game design: what is the goal? Usually, 4X games have victory conditions where there can be only one winner, and that in my opinion creates a lot of game design problems. Mainly, if you win by eliminating everyone then the end game is one interesting conflict followed by a long and repetitive mop-up phase. If there are multiple victory conditions then you are likely to get a situation where everyone is playing almost a different game that abruptly ends when someone else reaches their goal.

In the image above you can see players ranked by some score (1, a mock value). Meaning I'm experimenting with something different, instead of trying to be the only winner, players are trying to be ranked as high as possible. I'm also pondering the idea of having a score that doesn't feed directly into military power to have some opportunity cost of being higher ranked. I made a similar system in the Stareater where you directly "sacrifice" your colonies for the score but since the game is not finished yet I still don't know the real downsides to it and I want something less extreme in this game. At first, I thought of using the population as a score but when someone gets eliminated, their population will be zero or, depending on when elimination counts, some low circumstantial value. Also, the population is a direct indicator of economic strength and to an extent military potential. So I thought why not research points? They are the closest to representing the art and culture of a civilization, they are accumulating value so they can't be taken away, and counter-intuitively, having a lot of research doesn't directly indicate a strong military or economy. Heavy research is an investment that trades "now" for "later" and makes you vulnerable in the meantime. 

Anyway, nothing is set in stone yet and a mock score of 1 will stay for a while :).

Thursday, November 19, 2020

Ancient Star - ground combat

I'm back to adding features to the Ancient Star, and ground combat is done. Including bombardment and invasion controls UI.

It was a simple feature and I was saving it up when I get burned up with the serialization business. Numbers, for now, are straightforward, each troopship carries one ground combat unit, colony defenders grow by one unit every turn, up to population limit. Combat itself is similar to space combat but with troop attack and defense values being the same.

Saturday, November 14, 2020

Ancient Star - serialization

The nice convention about mobile applications is that you can turn them "off" at any moment and continue where you've left off later. Yeah, some apps don't work that way but developers are generally encouraged to make apps tolerant to being paused and resumed at any moment. In order to pull this off in the Ancient Star I need a solid system for saving and loading game data.

There are other things to do to make an app lifecycle aware (handle pausing, stopping, and resuming) but Android SDK does a very good job of covering the usual parts. Built-in UI components take care of themselves, custom components (like one where galaxy map is drawn) are fairly easy to make persistent and it's easy to move data around in a lifecycle aware manner. But in comparison getting game data into a format that can be written to a file and back is significantly more work. You might be fooled by built-in JSON converter and open source solutions that this is an already solved problem but I haven't found a solution with both low maintenance overhead and the ability to cope with complex data structures.

When serializing data there are two parts of the process, picking up data from objects and converting data. Think of it as answering "what" and "how" questions. Serializers like built-in Android one expect from app developer to answer "what" question so the code ends up handling the same piece of an object in three different places: declaration, serialization, and deserialization. This incurs considerable code maintenance overhead. Whenever you add a new data member to an object, you have to remember to include it in serialization and deserialization functions. Forgetting to do so is still legal code, the compiler will not complain about it and the app might run for a good while until the issue becomes apparent. And even then it's not trivial to figure out which member did have you forgotten to serialize or deserialize. Better libraries ask you only to put a special annotation next to member declaration so it is very easy to keep serialization coverage in sync with the actual object structure.

As long the structure is simple (tree). Such serializers work by dereferencing each reference and embedding values behind it inside the object that held the reference. So if there is an object referenced by multiple objects its data will get serialized multiple times, producing unnecessary data duplication in a save file, and what is worse, deserialization would not be able to deduplicate it, potentially producing a faulty game state. Cyclical references are even worse, they'll make a serializer run in an infinite loop. And it's easy to have data with such structures. For instance, in the Ancient Star, each Star object can have a reference to a Colony object, Colony has a reference to a Player who owns it and the Player has a list of scouted Stars. That's an example of both a cycle and multiple references to the same Player object since each colony references its owner. It is possible to swap direct references with indirect ones and make data simpler in the eyes of a serializer but it comes with the price of more complicated code. And besides, in the Stareater I did develop a serializer that both utilizes annotations and can work with complex reference networks.

The first "trick" I used there is to have the serializer make indirect references out of real ones. It generates a unique "name" for each object and references are substituted with those names. The second "trick" was to gradually build a reference network while deserializing, similar to how in the normal course of the game the complexity of data gradually increases. For instance, initially, stars don't have colonies, are not scouted, and during the game each player scouts and colonize more and more stars. Similarly, the deserializer can first create objects with only bare necessary data (primitives and references required by a constructor) and fill them with remaining data in the second pass. So how long it took to port the code from the Stareater? 30% of the total development time so far!

I expected it would take some time because I wanted to learn and use Java's annotation processor stack for code generation but I expected it to take half as much. Stareater is written in C# and runs on .Net (CRL actually) while Ancient Star runs in Java Virtual Machine (or something close to it). Certain metadata (generic parameters) which is available in CRL is not available in JVM and Stareater code depends on it. I didn't know that until I ported most of the code and give it a spin. I had to scrap and rebuild the serialization code two more times until I arrived at a workable solution. It was a frustrating road but I'm glad I have done it. It will pay off in the future.

Monday, November 9, 2020

Ancient Star - introduction


Wouldn't it be awesome to have a 4X game on a phone? Now that I mention it, yes? Then I recommend Uciana, it's worth the price. It's so easy to turn on while on break, play a turn or ten, turn it off, and continue later. Do you need more such games? Well, Ancient Star is going to be one.

The ambition level for the Ancient Star project is to make a simple game, akin to Master of Orion 1, but unlike Stareater, to have a complete product. Published by the end of the year, with working AI and multiplayer. That's right, completed, and published in two months. Or at least have a beta version by then. I've been developing it for two months already and about 75% of core game logic is finished. When the app as a whole is considered (UI polish, graphics, writing, AI, multiplayer, tests, publishing), the completion level is about 45%. Here is how looks at the moment:

Galaxy map functions similar to Google Maps map, pan by dragging with one finger, zoom by pinching with two fingers, tap to get information about an object in the panel at the bottom. Colony management is a simple focus setting and a building queue. Features implemented so far:

  • Colony development
  • Ship construction
  • Fleet movement
  • Colonization
  • Space combat
  • Bombardment
  • Turn reports

For now, graphics are minimal, either stock Android SDK images or basic shapes, UI is not styled, and so on. The idea is to get core game features in and then work on polish and visuals. Hopefully, that second phase will come soon, at the end of this month. Stay tuned for more development news about Ancient Star on this blog.

Friday, December 9, 2016

Master of Orion II: Gnolams

See Master of Orion II: every race for introduction and links to games with other stock races.


Gnolams are another race which where introduced in Master of Orion II. Their stereotype is money making and their trait list reflects that quite strongly: +1 BC, expert traders, lucky, low G and dictatorship government.

BC (also shown as tax +1) bonus is quite powerful (cost 7 points) because it's multiplicative with other sources of income such as government, morale and buildings. It's as if each population unit counts as two for the purpose of taxation. Fantastic traders (in some places referred as expert traders, yeah, game can't make up it's mind) have all sorts of situational bonuses: +25% BC from trade treaties, double income from surplus food and double profit from building trade goods. Trade treaty bonus looks decent but absolute numbers are not to so big and normal taxation bonus will always overshadow it. Extra cash from surplus food is also symbolic bonus because early on you want to have as smallest surplus as possible and later on you won't be producing so much food to see comparable difference to regular taxation. More cash from trade goods on the other hand can have big impact because a good planet can dish out a lot of industry points. The perk costs 4 points but in the eyes of many players it's not worth half the cost unless one is about exploiting credit cheat. Lucky is another ineffective trait, for 3 points only good events can happen to the player and Antarans rarely attack his colonies. Well, events happen every 50 turns to a random player so in four player on average this perk does nothing for 200 turns. Or on the positive side it does one thing during the whole game. Not being pestered by Antarans early on is helpful but they too appear very infrequently. Low G is negative trait, it costs -5 points and the race suffers -25% penalty to farming, industry and research on normal G planet and -10 in ground combat. There is no economy penalty on low G planets and the homeworld has low gravity. Dictatorship is default government type, see Alkari playthrough for more details.

Since last few games on normal turned out to be quite easy, this time I've started a game on hard. My starting position was decent, large desert and small ultra rich barren. Not spectacular, weak early game potential but quite good for the long run. While homeworld was providing food, large desert became research center and small ultra rich an emergency shipyard and main housing (extra population growth) center. Neighboring stars were so so, couple of irradiated average planets and a medium tundra in Weg system. I've landed my initial colony ship on tundra and immediately (turn 7) got in contact with Sakkra. At first I thought it's going to be an opportunity to use my trade bonus but it turned out Sakkrans were repulsive. If that didn't spell early war clearly enough, positions of their colonies did. In four player maps homeworlds are usually near corners but their was in a middle of the map. Cephee, their first expansion was in my direction and it was quite logical they will use it as staging point for attacking Weg. I've scouted remaining stars I had in range, encountered space crystal at Mensa system which guarded large ultra rich gaia with natives and parked other scout at neutral Yen system. That proved to be a good decision because on turn 22 I've spotted Sakkra troop transporter going to Cephee and it gave me time to prepare defense at Weg. My defenses were humble, two frigates, former scouts refitted with two unrefined nuclear missiles each. On turn 30 Sakkra moved to Weg but didn't attack. They blockaded the system for a few turns, until I've built 3rd frigate.


The war was dragging out, I've kept building missile frigates and eventually had enough to blockade Cephee and keep Weg safe from invasion. I've also invested in espionage and managed to steal deuterium fuel cell and biosphere technology, to sabotage a few buildings in Sakkra main system and most importantly the star base in Cephee system. After some time I even attempted to conquer a colony at Cephee but my ground combat score was too low, partly due to my -10 from low G and partly to Sakkran +10 while defending. On turn 110 I've researched planetary supercomputers and established contact with Meklars. While Sakkra and I played tug of war with two systems each, they expanded to four systems. I've tried my diplomatic skills on them but they kept refusing to sign any treaty so I tried something silly, trade supercomputers for heavy armor. It improved my standing a bit but still it took a lot of perseverance to get trade treaty. At least one solid step toward non-aggression pact. War with Sakkra went well, I've advanced chemistry by researching tritanium and started replace frigates with destroyers. On turn 151 as I was getting ready to send colonization fleet to Yen system, hyperspace flux happened preventing all interstellar travel. By the time the flux lifted Sakkra built a colonization fleet too and occupied Yen before I could. While I finally got safety by signing non-aggression pact with Meklar, on turn 188 Antarans decided to raid Yen system. Sakkra was unable to defend so I got the second chance and took the system before anybody got the same idea.

Settling Yen got me in range with Silicoids, another repulsive race. At first I didn't know how powerful they were so I've left Sakkra alone (they where down to their home system) and hoped they will be a distraction while I build up my army. I managed to steal positronic computer from Sakkras and advance physics on my own so I started to refit missile ships with lasers, a lot of lasers. Plus usual special equipment for beam ships, battle scanner and battle pods. Thing is everybody had class I shields which are not strong enough to make lasers ineffective and miniaturized armor piercing lasers are very strong weapon. While I was arming up Tanus, a colony leader, offered me his services and when I hired him I got pleasantly surprised by getting imperium, an advanced govnerment technology from him. My first field test of laser destroyers was against Sakkra who tried to invade me with quite sizable fleet (4 or so battleships with 3 more smaller ones). Lasers ripped their titanium hull to shreds. Then I figured I have enough military power to deal with space crystal and on turn 212 I colonized juicy large ultra rich gaia in Mensa system. I pumped all my money and excess population (mainly from small ultra rich in my home system) to that colony and turned it into a heavy duty shipyard. At this point I've filled command point capacity with destroyers and the time came for bigger ships so I started to build battleships. Where destroyers where packing 9 lasers, battleships could go up to 40. While I was preparing for eventual Silicoid invasion I've also backfilled systems around my homeworld and on turn 240 I was a candidate for galactic council. Silicoids were too numerous to be out voted by Meklars and me at that but that event gave me hope of eventually winning the game with diplomaticy rather then being forced to conflict.

Silicoids on the other hand had no other options then to expand through conquest. On turn 255 they defeated Sakkra and were at war with Meklars and few turns later they tried their luck on me. My laser destroyers and few battleships were strong enough to handle their titans but not powerful enough repel Antarans who decided to raid Yen (again but with me controlling it this time). Their fleet was quite big at this point, 3 frigates, 2 destroyers and a cruiser. I managed to destroy their frigates and retreat battleships on time, thanks to heavy armor but unfortunately the colony got bombarded to oblivion. On the flip side I had second colony in the system so I've managed to remain in control of the system and rebuild the lost colony. After Antaran incident I've proceeded to conquer Silicoids and grow my population to increase voting power. I would have won at turn 290 election if Meklars did vote for me. I traded few more technologies with them to improve standing, tried to make an alliance with them but as usual they were not keen on signing. 50 turns later I assimilated more of Silicoid empire, switched weaponry to phaser beams, defeated Orion guardian and got Meklars to vote for me.


It was a bit slow game if you go by technology progression rate but considering the cause of it was early and constant war, it was an interesting game. The fact that most of the fights were fought with imperfect technologies (plain, non-MIRV missiles), sort of subversion of expectation brought extra fun factor. So did Gnolam traits influence the game and my play style? Low G certainly did slow my economy down. Monetary bonuses didn't look very influential early on while I was playing but in retrospect I was buying a lot more buildings than I could with other races, I was even able to afford buying ships and I didn't have to wait long to afford most expensive leaders. Also there was no mid-game deficit period where building maintenance cost would grow over tax income and by time as I was half way through technology tree I had enough income to go substantially over command point capacity. Gnolams are deceptively strong. I doubt lucky trait probably saved from negative events because Silicoids got a lot of good events but it kept Antarans away from me for the most part.


One side note, see how top right part of galaxy map is uninhabited? It's not because nobody has bothered to send a colony ship there, it's because there was no habitable planets. There was 2 toxic ones in Python system and the rest where either empty systems or filled with gas giants.

Monday, March 21, 2016

Master of Orion II: Elerians

See Master of Orion II: every race for introduction and links to games with other stock races.

Elerians were introduced in the second installment of the Master of Orion and their archetype is..., um, I'll keep my opinion to myself :). From the other perspective they are space elves. For some reason telepathy and other mind powers are perfectly OK magic to use in science fiction setting and Elerian traits are mix of mind magic and warmongering: +20 ship attack, +25 ship defense, telepathic, omniscient and feudal.

Ship attack and defense bonuses are straightforward extra accuracy and evasion (see Alkari and Bulrathi articles for more info). Telepathic gives a few ordinary bonuses, +10 to espionage and +25% to diplomacy (whatever that means), but the best thing is the mind control ability. After a successful space battle cruisers and larger ships can mind control planets to side with the attacker. Such planets do not suffer from conquered penalty and don't revolt. There is a small space battle effect too, when telepathic race successfully captures a ship, they can use it during the same battle. All in all it's great trait for rushing because early conquest doesn't require building and deploying troop ships and conquered planets are developed sooner. Trait cost is quite high, 6 points. Omniscient on the other hand is cheaper mind magic, for 3 points it reveals the details of all star systems as if they have been scouted and reveals all opponent ships, no matter how well they are hidden. Great for planning your game from the start and it's kind of counter for stealthy ships. Feudalism is a government type and a negative one. It costs -4 points, lowers morale for -20% on colonies without barracks and has -50% penalty to research. There is slight bonus, starships cost 2/3 of normal cost. If you didn't get enough incentive to blitz your opponents with telepathy, feudalism would be screaming "rush or die" at you. Imperium, the advanced form of feudalism has lower research penalty (-25%) and ship cost reduced to 1/3 of the normal price which is awesome if one can live long enough to research it. On the surface Elerians look like disaster, overcommited to rushing from turn 1 when you don't really weapons for breaking early starbases but I'm looking forward to the challenge.


Before doing any move, I observed the map. Systems around me were mostly poor with minerals, while some of them are tundras and ocean I wouldn't gain much by expanding and would lose time. By exploiting wormhole placement and extended range on colony ship I could have reached Darloks very quickly. Either by colonizing Ras system without escort or by colonizing Rhilus system and making outpost at Ras. Both systems had a medium tundra planet but I thought about going with the safer option and use Rhilus later for launching attack on Trilarians. Next question was how to take down star bases? Six command points is barely enough for big enough fleet of missile boats but a friend gave me a different suggestion: heavy lasers. Beam ships are not limited with ammo and heavy mount would provide the range for shooting while staying away from most of opponent's weaponry. Fleet composition was third question, there had to be one cruiser in order to use mind control on planets and the question was what to do with remaining three command points. After some time playing in the ship designer I've decided to simply go with 3 frigates, I could build them much faster (plus I could speed things up by refitting scouts) then a single cruiser or destroyer and frigate and they would be packing similar amount of firepower. I've never played with unminiaturized lasers before and my final ship designs where something unique: frigate design had only a single heavy mount laser (much like A-10 airplane, a cannon with wings and engines) and cruiser had one heavy laser and 20 PD (defensive) lasers. The idea was to have a cruiser provide anti-missile defense while frigates do the heavy lifting.

When I've finally pressed "end turn" button I saw Darloks sending colony ship to Ras. That was great for me because I could mind control it and get fuel range to Nazin instead of having to build and deploy an outpost ship. My colony ship was on the way to Rhilus and homeworld was refitting scouts with a heavy lasers and building the cruiser. On turn 22 the invasion fleet was complete and three turns later positioned at Rhilus system, ready for war. Instead of outright declaring the war on Darloks I've tried provoking it by demanding anti-missile rockets technology from them. In either case I would win something. They refused, got so angry they declared war on me and I had "justification" for moving through wormhole and taking Ras system next turn. On turn 28 Nazin fell and Darloks no longer owned anything. The battle at Nazin was straight forward, a starbase was launching missiles at the cruiser which was happy to shoot them all down. Occasionally a heavy laser would scratch the cruiser but not often enough to make significant damage. It took some time but starbase armor and structure was slowly worn down and I got to double my empire's population.

Next on my hit list were Trilarians. I've built an outpost ship and sent it to Praxis, hired commander Hawk and assigned him to the cruiser. His bonuses were not ground breaking, +5 to beam defense was not that impressive but navigation skill was actually good one. +1 to galaxy speed was nice (huge bonus considering the base value is 2) and secondary effect, no slowdown in nebula, was the best part. Both Trilar and Cryslon had a nebula in the way and being able to travel through with full speed was very useful. By the turn 39 I've established contact with Trilarians and had fleet ready in the Praxis system. I've tried again to provoke the war by demanding a technology but this time AI agreed. I got my self fusion beam but not the the war, now what? I've asked for research treaty and again they agreed. I sighed and decided to spare them for a while.

I thought about attacking Silicoids last but given the situation it was actually not bad idea to deal with them before they spread too much. I did a bit of research and development on my new colonies and then ordered a new outpost ship. Administrator Garron offered his service and I've hired him. All of his bonuses would be useful in some way, +10 diplomacy might give me some better deal with Trilarians, fame bonus would reduce the price of later leaders and megawealth (10 BC/turn) alone would justify hiring him. On turn 50 I've researched my first very own technology: research labs. The feudalism really makes researching early technologies feel like huge achievement. I've traded lab with Trilarians for hydroponic farms because they would help me a bit with food and Trilarians wouldn't live long enough to make good use of labs anyway. Few turns later Silicoids got lucky, they've uncovered a wreckage of an ancient ship and got a fusion beam technology. Then they've lended me a hand by colonizing Dendo system. Once I've made outpost in Honte system I was one system away from having a continious path to all Silicoid systems. Dendo fell on turn 63, but they were able to destroy two of my frigates so I took me some time until I attacked them again. My research was producing results and by turn 67 I had reinforced hull and automated factories and traded factories for space academy. I've built my second cruiser on turn 82, some time after researching fusion rifles so it had a bit more advanced weaponry, it sported AP NR (armor penetrating, no range dissipation) heavy laser. Too bad it was built one turn before I advanced physics field again. I've decided it was worthy to lose time refitting so I've sent it to meet with an old fleet at new outpost in Oba system. New physics technology was tachyon communications which gives an extra command point per starbase. I usually pick battle scanner for more beam accuracy but this time I figured I have good enough accuracy and bigger fleet was more important. And again I traded my new technology with Trilarians but this time for planetary missile base, an excellent planetary defense which can repel most early game fleets, including Antarans.

Fortunately Antarans were asleep whole game and by turn 92 I've mind controlled the last Silicoid colony. AP laser performed well, it was crippling starbase weaponry as it was destroying it, reducing the threat level considerably faster but it was not that great damage wise. The problem was I had mix of no-AP weapons which had to drill through armor so in the end it took almost the same amount of turns. Silicoids are awesome race for to have. They don't need food and they don't produce pollution which translates to almost quadruple industrial output. And on top of that they have higher population limit on hostile planets. Did I mention they don't eat food? Yeah they can spread like weed and bacteria combined. Once I've conquered them their former homeworld was capable of outproducing my whole empire. There should be no surprise if I tell you I made it my main shipyard.

As I was preparing for Trilarians I was concerned about missile bases. Would 20 PD lasers be enough? At the time I had enough command points for 3 cruiser so I've figured 3 times 20 should be enough. I was lazy to run the numbers but knowing how stuff works under the hood I estimated NR modifier would trick fraction rounding into effectively double PD damage, "autofire" modifier would increase actual number of shoots and "continuous" modifier would compensate for autofire accuracy penalty. While refitting the fleet my scientist have researched battle pods so I had even more firepower at my disposal and there was no worry about Trilarian defenses. Final cruiser design was 4 heavy and 9 PD lasers all with aforementioned modifiers. That's very powerful for turn 105 and there were few defensive improvements as well, tritanium armor and fusion drive I got from Trilarians while trying to provoke war. This time I just declared war after failed provocation, there was no more reason to let lone AI live. Trilar fell on turn 112 and missile base wasn't so hard, partially because the system was in nebula so their shields were not working and partially because their ships were busy bombarding my outpost at Praxis. The real battle with Trilarians happened at Kae system, they had a battleship with captain Mukirr, a destroyer with captain Altos, two frigates, a starbase, a missile base and defensive structures were shielded with class I shields. My cruisers were swift at destroying defensive structures, despite the shields, but their ships were good at evading my shots. Extra accuracy on PD lasers helped a lot, something I was scarcely aware it was there. While I was trying to land enough shoots on their titanium plates they managed to cripple and capture one of my ships. Few moments later there were fireworks, one of their ships exploded so hard that my captured cruiser got destroyed along with and Trilarian frigate. Last Trilarian system Yad was undefended and it fell one turn after Kae, concluding the game.


Well that was an interesting game. I've expected a disaster and got exhilarating roller coaster ride. I felt so powerful taking a whole race before turn 30 and defeating everybody else with lasers. Elerians are weird race to play with, as if they are playing a different game then everybody else. Rushing so early feels like cheating but that is the case in all games, not just Master of Orion. Limiting their research capabilities is actually nice touch since it balances out the fact that successful rush would double the empire and it really made me appreciate every single technology I got.