Prikazani su postovi s oznakom progress. Prikaži sve postove
Prikazani su postovi s oznakom progress. Prikaži sve postove
srijeda, 4. rujna 2019.
Nailing down a thing
Real life has been really busy past few months and I've been tackling very nasty issue in the Stareater so that's why there has been such long time from last update. The project is still going and version 0.8 will soon be published. The nastiness of rendering text is finished (for now) but the real life will remain busy so "soon" will be probably somewhere this month.
petak, 26. siječnja 2018.
Preview release v0.6.4
Now that holidays are over it's time to get back to work. And what a better way to kick off a new year by doing something crazy: own GUI engine.
Download Stareater v0.6.4-alpha
Making own mouse and keyboard event handling, element positioning, drawing variable length borders, state handling, positioning text and images inside elements and many more gotchas sound like a lot of complicated work. But when you look at the project code you'd see good deal of that already implemented. Turn number on galaxy map and bombardment buttons in postcombat bombardment are the most prominent examples, galaxy map scrolling and interaction is a subtle one which also uses most of aforementioned features. So it was mostly a matter of restructuring already existing code and thinking through some details. And think it through I did, after all, I've abandoned very first Stareater incarnation due to GUI logic getting too complicated. Since then I've seen a lot of GUI code, both in use and details under the hood. I saw a lot of interesting approaches and a lot of bad realizations.
I've looked for existing solution I could use but they were either one of bad realizations or couldn't smoothly integrate with C# and OpenTK. Still, I have to give credit for an effort to Gwen.Net, a port of C++ library to C# with OpenTK. It's easy to integrate and emulates WinForms quite well. And that's the problem, I want to get rid of WinForm's look and feel. Gwen's skinning support looked very convoluted, you had to look through code to figure out which pixels on texture did what and documentation is practically nonexistent. Also I'd like to work with more modern layout mechanisms, something where it's easy to say "put this button at the bottom right corner" and have a framework calculate exact (x, y) coordinates and update them when window resizes. Something like GUI framework in Unity Engine and Android framework. WinForms is very limited in that area and from what I managed to dig out from Gwen.Net the situation is not much better there either. So I rolled my own framework and replaced old end turn button. Visually it needs more time in the oven but that's a challenge for another time and it would be an issue with any GUI framework, all of them expect you to bring your own artwork.
Core game feature in this release is colony maintenance, bad planet traits increase maintenance cost per population and it's payed up by whole nation. If maintenance cost is greater then 50% of nation's productivity then colonies in the worst shape will suffer population loss. Reason for including this mechanic is to make bad planets less desirable since they are going to put a burden on all of your colonies, to make star "catalysis"(afflicted by stareater's native organisms) bigger problem for a player and to make terraforming and building up more desirable. This also gives me an opportunity to fill some gaps in tech tree :).
Finally, another tier of technologies has been worked over and again it took more time then expected. In fact it took more time then making new GUI framework. Reason this time around is that I decided to make few changes to the tech tree: to remove limited use technologies. In Master of Orion 2 when you research new type of armor all previous types become obsolete. New ships are automatically built with the best armor and there is no trade-off between lower and higher tier armor. In Master of Orion 1 there was some nominal trade-off, lower level tech costs less and takes less space but even then I rarely went more then one tier below highest available. Something similar was in old concept of Stareater tech tree plus the fact that techs in Stareater can be upgraded with more science investment. I don't think it would play well "dead end" techs. Why would you invest a lot in an item that would go obsolete. In case of armors I've removed all techs that unlock particular armor type and replaced them with two techs: one which unlocks new types of armor material as you level it up and other which improves armor quality (level within armor type). Ditto for reactor technologies, reactor type tech and reactor level tech instead of one tech for each type. For computers, sensors and interstellar drives I'd make a mix of cumulative upgrades and special abilities. Quantum computer would increase instead of replace electronic computer bonus, lidar would add up to radar bonus and provide "telescope" ability for increased detection strength in a narrow cone, inerstellar drives would have unique movement abilities, etc. Thrusters are still one foot in old concept and one foot in new one, there will be less thruster types and upgrading them will provide some economic bonuses like lower space lift penalty due to gravity and increased migration capacity.
This left a few holes in a tech tree and by moving few items around I might go back to originally planes 7 tiers per field. Physics is still cramped full for 8 tiers while biology and sociology are very sparse, sometimes having only one item in a tier. Work on tech tree is still in progress, I hope to fill the gaps with techs for missing features (trade treaties, espionage, fuel range) and end up having 3 items in every tier in 7 tier model.
Download Stareater v0.6.4-alpha
Making own mouse and keyboard event handling, element positioning, drawing variable length borders, state handling, positioning text and images inside elements and many more gotchas sound like a lot of complicated work. But when you look at the project code you'd see good deal of that already implemented. Turn number on galaxy map and bombardment buttons in postcombat bombardment are the most prominent examples, galaxy map scrolling and interaction is a subtle one which also uses most of aforementioned features. So it was mostly a matter of restructuring already existing code and thinking through some details. And think it through I did, after all, I've abandoned very first Stareater incarnation due to GUI logic getting too complicated. Since then I've seen a lot of GUI code, both in use and details under the hood. I saw a lot of interesting approaches and a lot of bad realizations.
I've looked for existing solution I could use but they were either one of bad realizations or couldn't smoothly integrate with C# and OpenTK. Still, I have to give credit for an effort to Gwen.Net, a port of C++ library to C# with OpenTK. It's easy to integrate and emulates WinForms quite well. And that's the problem, I want to get rid of WinForm's look and feel. Gwen's skinning support looked very convoluted, you had to look through code to figure out which pixels on texture did what and documentation is practically nonexistent. Also I'd like to work with more modern layout mechanisms, something where it's easy to say "put this button at the bottom right corner" and have a framework calculate exact (x, y) coordinates and update them when window resizes. Something like GUI framework in Unity Engine and Android framework. WinForms is very limited in that area and from what I managed to dig out from Gwen.Net the situation is not much better there either. So I rolled my own framework and replaced old end turn button. Visually it needs more time in the oven but that's a challenge for another time and it would be an issue with any GUI framework, all of them expect you to bring your own artwork.
Core game feature in this release is colony maintenance, bad planet traits increase maintenance cost per population and it's payed up by whole nation. If maintenance cost is greater then 50% of nation's productivity then colonies in the worst shape will suffer population loss. Reason for including this mechanic is to make bad planets less desirable since they are going to put a burden on all of your colonies, to make star "catalysis"(afflicted by stareater's native organisms) bigger problem for a player and to make terraforming and building up more desirable. This also gives me an opportunity to fill some gaps in tech tree :).
Finally, another tier of technologies has been worked over and again it took more time then expected. In fact it took more time then making new GUI framework. Reason this time around is that I decided to make few changes to the tech tree: to remove limited use technologies. In Master of Orion 2 when you research new type of armor all previous types become obsolete. New ships are automatically built with the best armor and there is no trade-off between lower and higher tier armor. In Master of Orion 1 there was some nominal trade-off, lower level tech costs less and takes less space but even then I rarely went more then one tier below highest available. Something similar was in old concept of Stareater tech tree plus the fact that techs in Stareater can be upgraded with more science investment. I don't think it would play well "dead end" techs. Why would you invest a lot in an item that would go obsolete. In case of armors I've removed all techs that unlock particular armor type and replaced them with two techs: one which unlocks new types of armor material as you level it up and other which improves armor quality (level within armor type). Ditto for reactor technologies, reactor type tech and reactor level tech instead of one tech for each type. For computers, sensors and interstellar drives I'd make a mix of cumulative upgrades and special abilities. Quantum computer would increase instead of replace electronic computer bonus, lidar would add up to radar bonus and provide "telescope" ability for increased detection strength in a narrow cone, inerstellar drives would have unique movement abilities, etc. Thrusters are still one foot in old concept and one foot in new one, there will be less thruster types and upgrading them will provide some economic bonuses like lower space lift penalty due to gravity and increased migration capacity.
This left a few holes in a tech tree and by moving few items around I might go back to originally planes 7 tiers per field. Physics is still cramped full for 8 tiers while biology and sociology are very sparse, sometimes having only one item in a tier. Work on tech tree is still in progress, I hope to fill the gaps with techs for missing features (trade treaties, espionage, fuel range) and end up having 3 items in every tier in 7 tier model.
ponedjeljak, 9. listopada 2017.
Preview release v0.6.2
You got a real treat, two releases in a month! In this one organizations finally have a purpose (they give you boost in a research field) and starting technologies have a description and an in-game effect.
Download Stareater v0.6.2-alpha
In Stareater story there are multiple alternate universes and in some of them humanity tries to send manned mission to Mars on spacecraft propelled by nuclear engine (think of project Orion). For certain reason the Stareater pulls them in his pocket universe and those lucky enough to end up near habitable planet form a colony. Some of those colonists were pulled from universe where NASA launched the ship and others were from other universes where some other organization was leading the space race for Mars.
When starting a game player picks which organization has sent the people he is going to lead. Each organization brings technologies from the first level of one of the research fields which means that player will not have to pay prototyping cost for those technologies and will advance faster through that field (research cost decreases with level). For now there are 7 organizations to pick from:
Download Stareater v0.6.2-alpha
In Stareater story there are multiple alternate universes and in some of them humanity tries to send manned mission to Mars on spacecraft propelled by nuclear engine (think of project Orion). For certain reason the Stareater pulls them in his pocket universe and those lucky enough to end up near habitable planet form a colony. Some of those colonists were pulled from universe where NASA launched the ship and others were from other universes where some other organization was leading the space race for Mars.
When starting a game player picks which organization has sent the people he is going to lead. Each organization brings technologies from the first level of one of the research fields which means that player will not have to pay prototyping cost for those technologies and will advance faster through that field (research cost decreases with level). For now there are 7 organizations to pick from:
- NASA - North American Space Agency. Specializes in sociology which will allow them to grow their colonies faster and get more out of them.
- ESA - European Space Agency. Specializes in physics which translates to more advanced weapons and impact blocking shields.
- JAXA - Japan Aerospace Exploration Agency. Masters of mechanics, have higher industry output and more special equipment for starships.
- CNSA - China National Space Administration. Specializes in chemistry, meaning better mining efficiency, more advanced armor types and longer ship range.
- SSSR - Soviet space program. Specializes in energetics which brings more advanced reactor types and impact absorbing shields.
- ISRO - Indian Space Research Organisation. Masters of mathematics who sport more advanced interstellar drives and stealth technologies.
- UKSA - UK Space Agency. Masters of biology who can get more out of their planets and improve their habitability faster.
It's still work in progress, mind you but that's how I hope the game will play out. I could write in similar length about starting technologies but I'll save that material for later. Writing blog posts ends up taking up a lot of time. On this one I've been working for almost full week and the topic is an event from two weeks ago. And the project is about to hit a pretty talk-worthy milestone, a 1000th code commit so yeah I better start in advance :).
utorak, 22. kolovoza 2017.
New state engine progress
Last major release went well, all in all. The game attracted a few curious persons and one was very generous with feedback. Some of the easier suggestions (turn count in the corner, special equipment limit in ship designer) are already implemented and other are added on to do list.
What is going to be done for next major release? This will be reviled in next post, I'm still working on the feature list and I've already started working on something. I'm weighing how much refactoring should I do because I really want to clean up some things but the downside of refactoring is that features doesn't get made during that time. So I've started new milestone to by refactoring the biggest thorn in the side. Now is the best time while there is no psychological pressure to work on polish, feels like I have all the time in the world and it's better to do breaking changes early with plenty of time to test them thoroughly. In last version I've been working on removing text template code generators but I had to keep state handling ones due to complexity and their time has come to an end.
In Stareater code game data is split in following categories:
What is going to be done for next major release? This will be reviled in next post, I'm still working on the feature list and I've already started working on something. I'm weighing how much refactoring should I do because I really want to clean up some things but the downside of refactoring is that features doesn't get made during that time. So I've started new milestone to by refactoring the biggest thorn in the side. Now is the best time while there is no psychological pressure to work on polish, feels like I have all the time in the world and it's better to do breaking changes early with plenty of time to test them thoroughly. In last version I've been working on removing text template code generators but I had to keep state handling ones due to complexity and their time has come to an end.
In Stareater code game data is split in following categories:
- States - facts of the game world such as star positions, which planets are colonized and by whom, which technologies players have researched and so on.
- Orders - how players want to change the state. This includes building queues, technology development order, audience request and so on.
- Derivates - implications of states and orders. Population growth for example is calculated from colony's current population, population limit and "housing" building which converts industrial production to population.
- Statics - assortment of stuff in the game. Which technologies there are, kinds of ship equipment, kinds of buildings and so on.
When it comes to juggling data statics are simple, they are loaded once and that's it, derivates are recalculated when needed so they don't require much management either but states and orders have to be copied, saved to a file and loaded back. Ordinary mortal programmer would simply write functions for each operation in each data type. Maybe I would too if it's was a smaller project but in this one there are currently 20 state and order data types with total of 82 attributes (members/properties/fields). That's a lot of stuff keep in mind and remember to update when adding new features. So like every engineer I've decided to let computer do the bookkeeping for me and that's where T4 text template came to play. I'd simply list which attributes a type has and for each attribute it would generate logic for initialization, copying, saving and loading. It sound awesome in theory but T4 is hard to debug (at least was at the time) and there were always some edge cases which were hard to solve with general approach.
Developing and updating T4 based solution took me at least two months, in total making it almost 10% of effort since v0.5 rewrite. New system already took a month to develop but I'm confident it won't take much time to maintain. Firstly, it already works, secondly it's easier to work with since it's pure C# code. I also simplified data a bit in order to make it work, some relations were really complicated and required a certain unintuitive order of operations to get stuff done.
How does this new "state engine" works and why didn't I implement it first time around? In C# there is something called reflection and I tend to call it "dark magic". It allows you to get information about data types while the program is running, information such as which attributes a type has, how they are called in source code, which types does the type inherit, reading and writing values where you normally can't and many more. All of this comes at the price of quite slow performance. Also there is another form of "magic", so called expressions trees which basically let's you create more program logic while the program is running. At first I was concerned whether it's a good idea (how fast is compilation, would antivirus freak out) but I've found out that Microsoft's own database access functions use so it's not something foreign to the world. The price is only a slowdown on first use (compilation actually), further uses work almost as fast as native code. New state engine uses both schools of magic, reflection for gathering data and build up engine and compiled expression trees to do the actual operations but I tried to keep them to a minimum since they don't make very readable code. It's much more readable then T4 templates, true, but still not self-explanatory on a first glance as normal C# code.
This engine didn't come out of a blue either, I've been experimenting with technology a year ago and developed a small prototype project to test out those "magics". Now that a new engine is made, there is some minor code cleanup is left to do, full removal of remaining T4 templates and verification if all state and order data types save and load properly. God, I need to automate this somehow but only thing that comes to mind is to make a test suite which would take another month of making features. Back to compiling feature list for the milestone, one thing is certain, organizations are going to have a tangible effect.
Developing and updating T4 based solution took me at least two months, in total making it almost 10% of effort since v0.5 rewrite. New system already took a month to develop but I'm confident it won't take much time to maintain. Firstly, it already works, secondly it's easier to work with since it's pure C# code. I also simplified data a bit in order to make it work, some relations were really complicated and required a certain unintuitive order of operations to get stuff done.
How does this new "state engine" works and why didn't I implement it first time around? In C# there is something called reflection and I tend to call it "dark magic". It allows you to get information about data types while the program is running, information such as which attributes a type has, how they are called in source code, which types does the type inherit, reading and writing values where you normally can't and many more. All of this comes at the price of quite slow performance. Also there is another form of "magic", so called expressions trees which basically let's you create more program logic while the program is running. At first I was concerned whether it's a good idea (how fast is compilation, would antivirus freak out) but I've found out that Microsoft's own database access functions use so it's not something foreign to the world. The price is only a slowdown on first use (compilation actually), further uses work almost as fast as native code. New state engine uses both schools of magic, reflection for gathering data and build up engine and compiled expression trees to do the actual operations but I tried to keep them to a minimum since they don't make very readable code. It's much more readable then T4 templates, true, but still not self-explanatory on a first glance as normal C# code.
This engine didn't come out of a blue either, I've been experimenting with technology a year ago and developed a small prototype project to test out those "magics". Now that a new engine is made, there is some minor code cleanup is left to do, full removal of remaining T4 templates and verification if all state and order data types save and load properly. God, I need to automate this somehow but only thing that comes to mind is to make a test suite which would take another month of making features. Back to compiling feature list for the milestone, one thing is certain, organizations are going to have a tangible effect.
subota, 24. lipnja 2017.
Bombardment Mk II
Real life got me busy again, it has been a while since last update but the last feature for v0.6 is done. Bombardment can be performed after victorious space battle.
New bombardment kicks in when attacker is at undefended colonies. Be it after defeating defender's fleet in space battle or by simply there being no space defenses at all. Rules for in battle and out of battle bombardment are virtually the same: damage calculation, ammunition limits and turn limit are the same. This also means that ammunition and turns spent in space combat are not available in bombardment phase. In essence bombardment acts like simplified space combat without unit movement, any colony can be bombarded instantly with all ordinance without spending turns on travel.
On top of this feature I've improved starlane generator so the map looks more organic and less like a crystal lattice. It was in rather a simple change, I've increased minimum angle between incident (coming out of a same star) lanes and decreased the number of extra lanes beyond the minimum required to connect all stars. It turned out that those extra lanes were major contributor for turning organic look to crystalline. Now, if 0% means minimum number of lanes to connect all stars and 100% means maximum lanes possible then new starlane density settings are as follows:
New bombardment kicks in when attacker is at undefended colonies. Be it after defeating defender's fleet in space battle or by simply there being no space defenses at all. Rules for in battle and out of battle bombardment are virtually the same: damage calculation, ammunition limits and turn limit are the same. This also means that ammunition and turns spent in space combat are not available in bombardment phase. In essence bombardment acts like simplified space combat without unit movement, any colony can be bombarded instantly with all ordinance without spending turns on travel.
On top of this feature I've improved starlane generator so the map looks more organic and less like a crystal lattice. It was in rather a simple change, I've increased minimum angle between incident (coming out of a same star) lanes and decreased the number of extra lanes beyond the minimum required to connect all stars. It turned out that those extra lanes were major contributor for turning organic look to crystalline. Now, if 0% means minimum number of lanes to connect all stars and 100% means maximum lanes possible then new starlane density settings are as follows:
- Few - 20% (was 33%)
- Decent - 33% (was 50%)
- Many - 65% (was 100%)
- Maximal - 100%
Why stop on simple things when I can do complicated stuff too? Occasionally in maximum lanes setting there would be a few extra long lanes at the edge of the map, practically running along the whole edge. I've made an algorithm to remove them. It's something along the lines if a long lane was not there, find out if previously connected stars can still be reached via other lanes which are individually shorter and form a path which is not much longer then removed lane. Sounds simple but is a bit of a calculation intensive.
And now the plan is to fix a major bugs, polish a few things and finally release v0.6.
utorak, 18. travnja 2017.
Peace by deafult
Peace is now a default state, meaning diplomacy has been implemented. In other games in the genre, even if it is called peace, by default you are neither at peace nor at war with your neighbors. In Master of Orion for instance parties have to form a non-aggression pact in order to stop each other from engaging in combat. Without it you are free too attack each other and still enjoy trade treaties if neither side explicitly declares a war. Sure, an AI will automatically declare war every single time you attack it's ships (even if you let them retreat without casualties) but when AI attacks you it's "only" a friendly rub and you end up being rude for feeling offended.
Peace in the Stareater on the other hand assumes non-aggression pact. Picking on targets of opportunity (weak fleets, unprotected colonies) is strictly forbidden before formally declaring a war. Natives on the other hand don't respect human customs so they are always treated as enemies.
What is implemented at the moment is public relations screen where you can see your contacts with other players and see which treaties you have with them. From there you can call for an audience which will be held after hitting next turn. During the audience you can declare war or offer peace. For now this is it and AI will go along with whatever you ask of it. It will take some fleshing out but the idea for the future is to have "public opinion" feature where each civilization population holds an opinion about other civilizations. If opinion is too low then war can be declared and trade treaties will be harder to form. If opinion is very high then cease fire must be declared and war between those civilizations can't be declared again.
It was a bit boring to implement this feature, mostly due to sizable amount of GUI involved. It doesn't look much but there is quite a number of things inside the things. At the end it became interesting and I even did an extra mile to finish an old task of including undefended colonies to space combat check. There are not many tasks left in the backlog for v0.6, this milestone is going to conclude faster then I've anticipated.
Peace in the Stareater on the other hand assumes non-aggression pact. Picking on targets of opportunity (weak fleets, unprotected colonies) is strictly forbidden before formally declaring a war. Natives on the other hand don't respect human customs so they are always treated as enemies.
What is implemented at the moment is public relations screen where you can see your contacts with other players and see which treaties you have with them. From there you can call for an audience which will be held after hitting next turn. During the audience you can declare war or offer peace. For now this is it and AI will go along with whatever you ask of it. It will take some fleshing out but the idea for the future is to have "public opinion" feature where each civilization population holds an opinion about other civilizations. If opinion is too low then war can be declared and trade treaties will be harder to form. If opinion is very high then cease fire must be declared and war between those civilizations can't be declared again.
It was a bit boring to implement this feature, mostly due to sizable amount of GUI involved. It doesn't look much but there is quite a number of things inside the things. At the end it became interesting and I even did an extra mile to finish an old task of including undefended colonies to space combat check. There are not many tasks left in the backlog for v0.6, this milestone is going to conclude faster then I've anticipated.
subota, 11. ožujka 2017.
Map generator 2/3: starlanes
It's been cooking for some time and it's finally out, starlane distribution algorithm in map generator has got some actual implementation instead of stub. The algorithm could use some tweaking but it already produces good results.
The algorithm has three subalgorithms: maximum connectivity graph, minimum connectivity graph and interpolation between minimum and maximum. Don't get discouraged by the word graph, I won't dive too deep in graph theory mathematics, I'll just as a convenient word for "a way how points are connected with lines".
The general idea is to start with maximum connectivity and remove connections until desired starlane density is reached. Maximum connectivity algorithm has been the hardest part to nail down. I've tried and scrapped about a dozen methods. First couple of ideas looked promising until I've run into edge cases which were impossible to handle without introducing some undesired properties like bias toward topmost or leftmost star positions. Then I've tried to get so called Delunay triangulation working. Failing to find easy to copy-paste code and after contemplating whether it's worthy or not to spend time integrating nontrivial code I have found, a simple solution dawned on my mind. I figured my ideal solution would always contain shortest possible connection and from there I assumed the ideal would favor short connections over long ones. I expanded it to an algorithm which checks potential connections one by one, from shortest to longest, and adds a connection to a solution if it doesn't cross over previously added connections. Prototype was promising, there was only an issue where some points had a lot of lines coming out in a narrow cone. After adding a condition where a connections has to have certain minimal angle between them I solved that issue and got satisfactory results.
Minimum connectivity algorithm starts from maximum connectivity solution and finds the smallest set of connections necessary to connect all points. First it picks a point closest to the center and adds connections which form a shortest path from player homeworlds to that point. That central point is momentary substitution for what will later be a stareater's "brain" system so this steps ensure that players will have access to it and to eachother (and shortest path ensures there will be no cycles meaning no superfluous connections). Then the rest of points unconnected by those paths are added to solution by taking the shortest connection which would connect a new point with the set.
Finally, depending on chosen starlane desnity some extra connections are added to minimal graph. Again, the shortest candidate connections are added but this time the ones linking points with least connection endpoints have a priority.
All this was accompanied with some general map generator code refactoring. Parameters (map size, position randomness, starlane density) are handled in a much nicer way and last map settings are finally getting remembered. Now that I think about it last number of players is still not remembered, oh well. Anyway, the map still has to be filled with stars and planets in some meaningful way, I have some ideas and I'm look forward for a day when third piece of the puzzle will fall in place.
The algorithm has three subalgorithms: maximum connectivity graph, minimum connectivity graph and interpolation between minimum and maximum. Don't get discouraged by the word graph, I won't dive too deep in graph theory mathematics, I'll just as a convenient word for "a way how points are connected with lines".
The general idea is to start with maximum connectivity and remove connections until desired starlane density is reached. Maximum connectivity algorithm has been the hardest part to nail down. I've tried and scrapped about a dozen methods. First couple of ideas looked promising until I've run into edge cases which were impossible to handle without introducing some undesired properties like bias toward topmost or leftmost star positions. Then I've tried to get so called Delunay triangulation working. Failing to find easy to copy-paste code and after contemplating whether it's worthy or not to spend time integrating nontrivial code I have found, a simple solution dawned on my mind. I figured my ideal solution would always contain shortest possible connection and from there I assumed the ideal would favor short connections over long ones. I expanded it to an algorithm which checks potential connections one by one, from shortest to longest, and adds a connection to a solution if it doesn't cross over previously added connections. Prototype was promising, there was only an issue where some points had a lot of lines coming out in a narrow cone. After adding a condition where a connections has to have certain minimal angle between them I solved that issue and got satisfactory results.
Minimum connectivity algorithm starts from maximum connectivity solution and finds the smallest set of connections necessary to connect all points. First it picks a point closest to the center and adds connections which form a shortest path from player homeworlds to that point. That central point is momentary substitution for what will later be a stareater's "brain" system so this steps ensure that players will have access to it and to eachother (and shortest path ensures there will be no cycles meaning no superfluous connections). Then the rest of points unconnected by those paths are added to solution by taking the shortest connection which would connect a new point with the set.
Finally, depending on chosen starlane desnity some extra connections are added to minimal graph. Again, the shortest candidate connections are added but this time the ones linking points with least connection endpoints have a priority.
All this was accompanied with some general map generator code refactoring. Parameters (map size, position randomness, starlane density) are handled in a much nicer way and last map settings are finally getting remembered. Now that I think about it last number of players is still not remembered, oh well. Anyway, the map still has to be filled with stars and planets in some meaningful way, I have some ideas and I'm look forward for a day when third piece of the puzzle will fall in place.
ponedjeljak, 6. ožujka 2017.
Warning: Graphic content
Few post ago I've thought about making planet orbits and combat grid textured, consider it done now. I've repurposed the shader to apply texture instead of flat color and instead of regular rectangular texturing it bends rectangular image to fit on curved surface. So orbits in system view are no more jagged and combat grid looks a bit nicer too.
Which drove me insane at one point. Adding texture to old polygons produced black spots around line intersections because they were overlapping and had same depth level, making depth test sometimes passed through a darker color. On top of that each hexagon produced all of it's boarder lines so lines between two hexagons were drawn twice. At first I've tried utilizing that by making each hexagon draw only it's half (half width, from border middle to line edge closest to the center of a hexagon). It worked well for all but for outermost lines which ended missing outer half. I've tried hundred ideas to get them finished properly but there was always some edge case which required twice as much code to handle as regular case. In the end I flipped the table, stopped thinking in hexagons, started thinking in lines and devised a two phase process. First phase was repurposed old code for processing grid per hexagon basis but this time it only made a list of where each border line starts and ends. Second phase inspects each line from the list, checks with which lines it is connected and generates draw polygons in a way that each line covers it's part of intersection. If you know me then it wouldn't surprise you that first phase is quadtree territory (for removing duplicate lines and points, plus cardinal sin of using non-integer numbers as a table key) and second phase is linear algebra town. Now I won't make any promises but I was pondering different shape for combat grid, something that still plays like current hex grid but looks more spacey :).
Shaders are not the limit of my limited artistic prowess. Oh, no I can make distinct low resolution images too. I've reworked two more smallest ship images and made up four new images for second ship size. Some long time ago I've came up with five distinct spacecraft shapes, some inspired by SF shows, some by permutating underlying shape. For instance, one of the inspirations is "fighter1" which resembles colonal Viper from Battlestar Galactica and it's rough shape it upside down kite. Simple way to get another shape of a spacecraft would be upside up kite. Make a broad part broader and thin part thinner and you get "T" shaped "fighter2".
Make rough outline with darker color, fill it with brighter and move pixels around until it looks right. That is how I arrived at images of the smallest spacecrafts. Larger ones I've made by inflating small ones, following the initial shape but adding a little twist here and there and adding a bit of detail.
I also thought more about hull size assortment and decided for fewer sizes then in CroVar iteration. Instead of having 10 or so sizes which grow by factor of 2.5 I decided to have 5 sizes which grow by factor of 5. I think having fewer but better defined sizes would suite the game better then having a lot of small increments and it gave me easier time coming up their names. I don't want to default to usual military frigate-destroyer-cruiser route if I have other options. One reason is that in real world navy these words describe ship role, not necesserly it's size class and second reason is that I don't want to depict spacecrafts as exclusively military vessels. For instance it would be awkward to describe a colony ship as a battleship class. I also don't want to use vague size gradations like small-medium-large because what is large for early game is medium or small in the late game and I want names to have some absolute meaning like X is this big. For now names are meteor, shuttle, cruiser, liner and asteroid but they are not set in stone and I'm open to suggestions.
Which drove me insane at one point. Adding texture to old polygons produced black spots around line intersections because they were overlapping and had same depth level, making depth test sometimes passed through a darker color. On top of that each hexagon produced all of it's boarder lines so lines between two hexagons were drawn twice. At first I've tried utilizing that by making each hexagon draw only it's half (half width, from border middle to line edge closest to the center of a hexagon). It worked well for all but for outermost lines which ended missing outer half. I've tried hundred ideas to get them finished properly but there was always some edge case which required twice as much code to handle as regular case. In the end I flipped the table, stopped thinking in hexagons, started thinking in lines and devised a two phase process. First phase was repurposed old code for processing grid per hexagon basis but this time it only made a list of where each border line starts and ends. Second phase inspects each line from the list, checks with which lines it is connected and generates draw polygons in a way that each line covers it's part of intersection. If you know me then it wouldn't surprise you that first phase is quadtree territory (for removing duplicate lines and points, plus cardinal sin of using non-integer numbers as a table key) and second phase is linear algebra town. Now I won't make any promises but I was pondering different shape for combat grid, something that still plays like current hex grid but looks more spacey :).
Shaders are not the limit of my limited artistic prowess. Oh, no I can make distinct low resolution images too. I've reworked two more smallest ship images and made up four new images for second ship size. Some long time ago I've came up with five distinct spacecraft shapes, some inspired by SF shows, some by permutating underlying shape. For instance, one of the inspirations is "fighter1" which resembles colonal Viper from Battlestar Galactica and it's rough shape it upside down kite. Simple way to get another shape of a spacecraft would be upside up kite. Make a broad part broader and thin part thinner and you get "T" shaped "fighter2".
Make rough outline with darker color, fill it with brighter and move pixels around until it looks right. That is how I arrived at images of the smallest spacecrafts. Larger ones I've made by inflating small ones, following the initial shape but adding a little twist here and there and adding a bit of detail.
I also thought more about hull size assortment and decided for fewer sizes then in CroVar iteration. Instead of having 10 or so sizes which grow by factor of 2.5 I decided to have 5 sizes which grow by factor of 5. I think having fewer but better defined sizes would suite the game better then having a lot of small increments and it gave me easier time coming up their names. I don't want to default to usual military frigate-destroyer-cruiser route if I have other options. One reason is that in real world navy these words describe ship role, not necesserly it's size class and second reason is that I don't want to depict spacecrafts as exclusively military vessels. For instance it would be awkward to describe a colony ship as a battleship class. I also don't want to use vague size gradations like small-medium-large because what is large for early game is medium or small in the late game and I want names to have some absolute meaning like X is this big. For now names are meteor, shuttle, cruiser, liner and asteroid but they are not set in stone and I'm open to suggestions.
utorak, 14. veljače 2017.
Refit discount
Time to address some leftovers. Proper refit cost calculation got implemented and scene building code got simplified.
Previously, refit cost was equal to full construction cost. On one hand it was not a big issue since refit and construction points are generated in parallel so there was never a situation where rebuilding ships was more profitable then refitting. But the idea behind whole feature was to have small refit changes result in lower refit cost while major role changes require more investment. In order to achieve that ship designs are now decomposed and compared component by component with following rules in order that would minimize cost:
Scene building improvement is one of the under the hood changes which aren't visible in the game but very visible in project development. With previous approach I had to specify and manage almost every of drawable objects in the scene code. Term "scene" here means major game "screens", ugh, defining one word with another ambiguous one. Galaxy map is one "scene", zoomed in star system is another scene, space combat is third scene and so on. With new approach scenes only have to define what is there to display and let the engine sort out "how" and "when". Yes, they still have to cope with raw numbers like transformation matrices and vertex data values but they don't have to manage them all the time. The underlying engine tracks when low level buffers should be updated and in which order they should be drawn. It also tracks "physical" data for detecting which objects' region has been clicked/tapped by the user, greatly simplifies bookkeeping in galaxy scene. There I previously had a mess of multiple parallel lists (quad trees) for keeping track of fleet visual positions vs their real positions.
And lastly, a friend tested a game and ran into an issue. The issue appears with recent NVidia drivers and is a manifestation of an old OpenTK bug. The bug is fixed in new version but at the moment I can't use it because Stareater works with other component which depends on old OpenTK version. One option is to pray and wait for maintainers to update the component, which given their track record is not going to be soon. After some discussion with OpenTK maintainers I learned that I can make OpenGL in Stareater work without that extra component on top of OpenTK. To achieve that I'd have restructure user interface code but at the moment I'm not keen on large refactoring endeavors. If the component gets updated any time soon that would be great in short term solution. In the long term I will make GUI less and less dependent on it and ultimately get rid of it.
Previously, refit cost was equal to full construction cost. On one hand it was not a big issue since refit and construction points are generated in parallel so there was never a situation where rebuilding ships was more profitable then refitting. But the idea behind whole feature was to have small refit changes result in lower refit cost while major role changes require more investment. In order to achieve that ship designs are now decomposed and compared component by component with following rules in order that would minimize cost:
- Refitting to same equipment type and level is free.
- Refitting to same equipment type but higher level has discount on full new item cost. Discount is 80% for 1 level difference and falls exponentially.
- Refitting to 5 levels higher item of same type or to entirely different type receives no discount.
Scene building improvement is one of the under the hood changes which aren't visible in the game but very visible in project development. With previous approach I had to specify and manage almost every of drawable objects in the scene code. Term "scene" here means major game "screens", ugh, defining one word with another ambiguous one. Galaxy map is one "scene", zoomed in star system is another scene, space combat is third scene and so on. With new approach scenes only have to define what is there to display and let the engine sort out "how" and "when". Yes, they still have to cope with raw numbers like transformation matrices and vertex data values but they don't have to manage them all the time. The underlying engine tracks when low level buffers should be updated and in which order they should be drawn. It also tracks "physical" data for detecting which objects' region has been clicked/tapped by the user, greatly simplifies bookkeeping in galaxy scene. There I previously had a mess of multiple parallel lists (quad trees) for keeping track of fleet visual positions vs their real positions.
And lastly, a friend tested a game and ran into an issue. The issue appears with recent NVidia drivers and is a manifestation of an old OpenTK bug. The bug is fixed in new version but at the moment I can't use it because Stareater works with other component which depends on old OpenTK version. One option is to pray and wait for maintainers to update the component, which given their track record is not going to be soon. After some discussion with OpenTK maintainers I learned that I can make OpenGL in Stareater work without that extra component on top of OpenTK. To achieve that I'd have restructure user interface code but at the moment I'm not keen on large refactoring endeavors. If the component gets updated any time soon that would be great in short term solution. In the long term I will make GUI less and less dependent on it and ultimately get rid of it.
srijeda, 4. siječnja 2017.
Space butterfly
Stareater's native life forms are coming to ruin you day. Or whole year if turns represent years. Lovecraftian space butterfly may look harmless at first, it will ignore your glowing cities and curious star ships, it will go straight for the star in a middle of a system and put a curse on it. It will turn temperate solar weather into living hell with extreme radiation and flaming tongues of solar flares.
Catalyzers (those space butterflies described above) are very old life forms, dating lineage back to the first generations of stars. They were born on rogue planet, a gas giant without a star to orbit about. There the life evolved around utilizing liquid helium and planet's powerful magnetic field. Extremely low temperatures made one peculiar evolutionary advance possible, the fusion catalysis. A life form utilizing it would inhale hydrogen, preform cold fusion and have access to nearly inexhaustible source of energy. At least from human perspective that is. After millions of years, gigantic gas dwellers have had exhausted their hydrogen supplies. Because of it some resorted to preying on others and some to far more radical measures: interstellar travel. Another strange ability of liquid helium's superconductivity is twisting the space itself, allowing life forms to slingshot themselves toward new sources of hydrogen, the stars of their galaxy. Like moths flying into flame, many have died but some were lucky enough to stumble upon other gas giants and eventually evolve the ability to exploit stars. They would devour the galaxy if there wasn't another fantastic leap of evolution, moving through multiverse. Instead of traveling through normal space to another star they could reach much closer (in time, not necessarily distance or effort) another version of their main star, effectively exploiting it over and over. This eventually led to birth of a stareater, a seemingly single star swallowing entity which in fact is a byproduct of much smaller beings.
For now catalyzers are only native life form implemented but more are to come. As it was the case with previous features, my main goal was to work out the foundation and have at least one example of the feature in action. In this sense catalyzers are one example of special participants in the game who partly play as regular player and partly have special privileges. They can make order their fleet on galaxy map and in combat but can live without colonies, can see whole map and spawn "ships" out of thin air/vacuum. It was fair challenge but I now have a system which supports "fake" players without reinvention of the wheel. Theoretically I can add another fake player for parasitic life forms who pray on stareater's organism and have them fight each other. A theory which I intend to put in practice one day :).
Another big deal introduced with this feature is an ability to put persisting traits on stars during combat and they can have active component now. So far traits were passive, a celestial body would either have it turn 1 or not have it ever. Now for example stars with "catalized" trait can actively inflict increased radiation to orbiting planets and ceasing to do so after a few turns.
There are few bug left to iron out, mostly when saving and loading. When I fix them I'll make a new build available for download.
Catalyzers (those space butterflies described above) are very old life forms, dating lineage back to the first generations of stars. They were born on rogue planet, a gas giant without a star to orbit about. There the life evolved around utilizing liquid helium and planet's powerful magnetic field. Extremely low temperatures made one peculiar evolutionary advance possible, the fusion catalysis. A life form utilizing it would inhale hydrogen, preform cold fusion and have access to nearly inexhaustible source of energy. At least from human perspective that is. After millions of years, gigantic gas dwellers have had exhausted their hydrogen supplies. Because of it some resorted to preying on others and some to far more radical measures: interstellar travel. Another strange ability of liquid helium's superconductivity is twisting the space itself, allowing life forms to slingshot themselves toward new sources of hydrogen, the stars of their galaxy. Like moths flying into flame, many have died but some were lucky enough to stumble upon other gas giants and eventually evolve the ability to exploit stars. They would devour the galaxy if there wasn't another fantastic leap of evolution, moving through multiverse. Instead of traveling through normal space to another star they could reach much closer (in time, not necessarily distance or effort) another version of their main star, effectively exploiting it over and over. This eventually led to birth of a stareater, a seemingly single star swallowing entity which in fact is a byproduct of much smaller beings.
For now catalyzers are only native life form implemented but more are to come. As it was the case with previous features, my main goal was to work out the foundation and have at least one example of the feature in action. In this sense catalyzers are one example of special participants in the game who partly play as regular player and partly have special privileges. They can make order their fleet on galaxy map and in combat but can live without colonies, can see whole map and spawn "ships" out of thin air/vacuum. It was fair challenge but I now have a system which supports "fake" players without reinvention of the wheel. Theoretically I can add another fake player for parasitic life forms who pray on stareater's organism and have them fight each other. A theory which I intend to put in practice one day :).
Another big deal introduced with this feature is an ability to put persisting traits on stars during combat and they can have active component now. So far traits were passive, a celestial body would either have it turn 1 or not have it ever. Now for example stars with "catalized" trait can actively inflict increased radiation to orbiting planets and ceasing to do so after a few turns.
There are few bug left to iron out, mostly when saving and loading. When I fix them I'll make a new build available for download.
utorak, 6. prosinca 2016.
OpenGL 3.2 migration
It was a fight but finally it's over, I've converted game's graphics engine to OpenGL 3.2 (or at least removed functionality which was deprecated by that version). It was a fight because it took a lot more pieces in the right place to draw anything at all but it was a fight worth fighting. Now I have power of shaders at my disposal and I intend to use it.
Back in a day when I've started working with OpenGL, NeHe tutorials were the main learning material. They made stuff look simple and following them was fairly quick way to get results. For a good part that was due to simplicity of OpenGL's immediate mode and fixed pipeline. There was minimal setup code and very direct approach to specify what to draw. The setup consisted of tying OpenGL context with a window (or whatever OS of choice uses for displaying graphics, later covered by myriad of 3rd party libraries), turning desired options on and setting projection matrix (kind of like camera, defines which part of game world is visible and how is distance perceived). When it came to drawing stuff you'd simply specify which kind of polygons are you going to draw and then feed GPU with polygon vertex positions. Optionally you'd specify which texture to use (or no texture) and which color to apply.
That's all good when you are dealing with simple scenes and don't need that much performance. Feeding vertex data every frame (immediate mode) is inefficient because GPU can't do much but wait for CPU to communicate all the data. Alternative approach is retained mode where list of vertex data, much like texture image, is uploaded once and later just referred to. In this mode draw calls boil down just telling GPU which vertex list ID to crunch and GPU can get to work immediately. Additionally retained mode goes hand in hand with shaders which are an opposite of the fixed pipeline. Problem with fixed pipeline is it's "one size fits all" kind of solution where unneeded features can be disabled. Shaders on the other hand can be tailored much closer to application's needs and can provide features beyond those supported by fixed pipeline. For those and probably other valid reasons immediate mode and fixed pipeline were declared deprecated in OpenGL 3 and later.
But in order to get any graphical result from shaders and retained mode there is a lot of stuff to setup:
As I said, a lot more steps on top of the previous ones. If any of them fails or gets misconfigured, there will be no picture. It took me good part of the week to get it working in Stareater but when it started drawing it was like Christmas. Pieces stared falling in place one by one and I was able to experiment with some wilder ideas like drawing straight lines with circle arcs without involving infinity. For now I have mostly converted existing graphics from old system to new. Exceptions are planet orbits in system view, now they are a few smartly shaded polygons instead of ton of small quadrangles pretending to be a piece of circle arc. On top of that I've left room for improvements like applying texture to planet orbits to get gradient effect and to do the same for hexagonal grid in space combat. Also I can save texture space with a shader which recognizes which parts of ship should be painted with player color from single "sprite" image instead of requiring additional "mask" image.
Back in a day when I've started working with OpenGL, NeHe tutorials were the main learning material. They made stuff look simple and following them was fairly quick way to get results. For a good part that was due to simplicity of OpenGL's immediate mode and fixed pipeline. There was minimal setup code and very direct approach to specify what to draw. The setup consisted of tying OpenGL context with a window (or whatever OS of choice uses for displaying graphics, later covered by myriad of 3rd party libraries), turning desired options on and setting projection matrix (kind of like camera, defines which part of game world is visible and how is distance perceived). When it came to drawing stuff you'd simply specify which kind of polygons are you going to draw and then feed GPU with polygon vertex positions. Optionally you'd specify which texture to use (or no texture) and which color to apply.
That's all good when you are dealing with simple scenes and don't need that much performance. Feeding vertex data every frame (immediate mode) is inefficient because GPU can't do much but wait for CPU to communicate all the data. Alternative approach is retained mode where list of vertex data, much like texture image, is uploaded once and later just referred to. In this mode draw calls boil down just telling GPU which vertex list ID to crunch and GPU can get to work immediately. Additionally retained mode goes hand in hand with shaders which are an opposite of the fixed pipeline. Problem with fixed pipeline is it's "one size fits all" kind of solution where unneeded features can be disabled. Shaders on the other hand can be tailored much closer to application's needs and can provide features beyond those supported by fixed pipeline. For those and probably other valid reasons immediate mode and fixed pipeline were declared deprecated in OpenGL 3 and later.
But in order to get any graphical result from shaders and retained mode there is a lot of stuff to setup:
- Load shader source code and compile it. One would think OpenGL doesn't deal with raw source code but that's the main way to get a shader on GPU. Of course shader source may not be valid and compilation can fail so the application has to check if this step was successful.
- Attach and link shaders into a single program. In previous steps you just loaded various shader types (geometry, vertex, fragment) but to make them useful you have to tie them in a single unit called simply a "program". This can fail too (for example if output of one phase doesn't match with an input of the next) so application has to check this too.
- Collect location IDs of shader attributes and uniform variables.
- Make vertex data buffers.
- Make "array objects". They hold information about how to feed vertex buffers to shaders, which bytes go to which attribute. This step won't fail but provides a lot of room for error.
- Turn on options like in fixed pipeline (like depth test, alpha blending and face culling)
- There is projection matrix calculation step too, like in fixed pipeline API but matrix management is very different. You can't use OpenGL's functions for building and switching matrices, you have to do it on your own (or use 3rd party library).
It's exciting and all that but before I bring all that goodies I'd take pause from engine making in order to do something cool in game making department. After that I'll pack a release and then refactor graphical engine a bit to make scene building easier. And then the visible improvements will ensue.
srijeda, 9. studenoga 2016.
Semi-exclusive research
A hybrid between Master of Orion II exclusive research system and Space Empires V incremental system is done. When research breakthrough happens a player unlocks new topics and chooses their priorities. Higher priority items have lower development cost making lower priority items harder to acquire but not impossible.
In Master of Orion II research works by accumulating research points until breakthrough happens in a selected field. Each field level unlocks between one and three applications (building, ship component or passive bonus) and normally player can pick only one. Other applications can be acquired from other players through trade or espionage if they happen to research them or by having a creative race trait which gives all applications on breakthrough. Some players hate this exclusivity because if you don't play creative race you will miss out some very useful technologies and creative trait is quite expensive which limits amount of traits you can pick with it. Other players love the system because it gives the reason to use diplomacy and can make the game play a bit differently every time. Anecdotally my best MoO II experiences were when there was an uncreative race in the game. Uncreative trait gives random application (no choice) on breakthrough which makes otherwise predictable AI take interesting paths which in turn may make them actually stronger. It can make AI design better ships by preventing them from getting technologies for making their usual jack of all trades (but master of none).
How to make AI is currently hot topic in 4X community, I should address it at some point too but the topic of this post is research system. I wanted to make a system where player can have a cake and eat it. A system with good parts of exclusive mechanics and ability to eventually go back to missed out choices. One idea was to make some way of reresearching missed out application but that would either make research rewards random or would make reward list increasingly longer. The idea I settled on was to have research give all rewards every time and move the problem to development, where long list of possibilities and varying investment costs would be normal. How exactly would development cost vary with priority is still open question which I intend to iron out when I add more technologies. Speaking of which I have made a spreadsheet with tech "tree" and added to the game small part of if it. I'll add more as game mechanics get implemented and I fill more blanks in the spreadsheet.
And finally, this is how breakthrough screen looks like in game. On the left is the info about research field where breakthrough happened, name, level, description and in the middle are unlocked development topics. At the top is a list of topics which can be rearranged with buttons next to it. Order of topics determines their priority, higher on the list, lower the cost. Below it is currently mouse over or selected development topic description and accept button which finalized priority selection. I'll make new build soon so stay tuned.
In Master of Orion II research works by accumulating research points until breakthrough happens in a selected field. Each field level unlocks between one and three applications (building, ship component or passive bonus) and normally player can pick only one. Other applications can be acquired from other players through trade or espionage if they happen to research them or by having a creative race trait which gives all applications on breakthrough. Some players hate this exclusivity because if you don't play creative race you will miss out some very useful technologies and creative trait is quite expensive which limits amount of traits you can pick with it. Other players love the system because it gives the reason to use diplomacy and can make the game play a bit differently every time. Anecdotally my best MoO II experiences were when there was an uncreative race in the game. Uncreative trait gives random application (no choice) on breakthrough which makes otherwise predictable AI take interesting paths which in turn may make them actually stronger. It can make AI design better ships by preventing them from getting technologies for making their usual jack of all trades (but master of none).
How to make AI is currently hot topic in 4X community, I should address it at some point too but the topic of this post is research system. I wanted to make a system where player can have a cake and eat it. A system with good parts of exclusive mechanics and ability to eventually go back to missed out choices. One idea was to make some way of reresearching missed out application but that would either make research rewards random or would make reward list increasingly longer. The idea I settled on was to have research give all rewards every time and move the problem to development, where long list of possibilities and varying investment costs would be normal. How exactly would development cost vary with priority is still open question which I intend to iron out when I add more technologies. Speaking of which I have made a spreadsheet with tech "tree" and added to the game small part of if it. I'll add more as game mechanics get implemented and I fill more blanks in the spreadsheet.
And finally, this is how breakthrough screen looks like in game. On the left is the info about research field where breakthrough happened, name, level, description and in the middle are unlocked development topics. At the top is a list of topics which can be rearranged with buttons next to it. Order of topics determines their priority, higher on the list, lower the cost. Below it is currently mouse over or selected development topic description and accept button which finalized priority selection. I'll make new build soon so stay tuned.
srijeda, 5. listopada 2016.
Refitting ships
First v0.6 feature is done, ships can now be upgraded or outright repurposed. It also includes automatically designing upgrades when new technologies are developed, as it was before rewrite.
The idea is that colonies passively produce certain amount of repair points which are first applied to repairing ships and then to upgrading/retrofitting. That much have been told in previous post. Currently ship repair is not yet implemented since no ship damage is carried over after a battle so all repair points go straight to retrofitting. Refit prices are currently simply full ship construction cost and repair points are generated at a rate of 1/5 per employed population (colonist with a workplace) making it 25 times slower then production of a new ship. I intend to revisit the numbers at a later date and make more nuanced cost calculation which takes into account equipment difference so upgrading will be cheaper then scraping and rebuilding ships.
I think that's enough for new preview build.
The idea is that colonies passively produce certain amount of repair points which are first applied to repairing ships and then to upgrading/retrofitting. That much have been told in previous post. Currently ship repair is not yet implemented since no ship damage is carried over after a battle so all repair points go straight to retrofitting. Refit prices are currently simply full ship construction cost and repair points are generated at a rate of 1/5 per employed population (colonist with a workplace) making it 25 times slower then production of a new ship. I intend to revisit the numbers at a later date and make more nuanced cost calculation which takes into account equipment difference so upgrading will be cheaper then scraping and rebuilding ships.
So how does it look like? On design list screen each design has red "x" button (which I should change to something more descriptive) which opens "Refit to" dialog where player can choose to remove design, refit to other design or keep the design (cancel removing or refitting).
As with other things in the Stareater, nothing permanent (except exceptions) happens before ending a turn. Marked designs are removed at the beginning of a next turn if there are no ships of that design. If there were technological advancements which unlocked higher level of ship components then upgraded designs will automatically be added and older designs will be marked obsolete and set to refit to new design. That automatic upgrade order can be changed by player but only by selecting non-obsolete design to refit to. Building queues also get changed in the process, swapping obsolete designs ship orders with their upgrades.
I think that's enough for new preview build.
utorak, 13. rujna 2016.
New game loop
I had fun time learn how operating systems do (and don't) handle timing, what's guarantied, what's not and how and how achieve results by messing whole OS. On the one hand I'm disappointed there is no guarantee for having timing resolution below 64 Hz (ticks per second) and that there is no cross platform way of getting the resolution. But on the other hand I've observed 1000 Hz resolution on all machines I have access to.
Let's back off a little bit. Game loop is part of game logic which juggles when input events (mouse, keyboard, ...) are collected and processed and when a image frames are drawn. Typically it repeats following steps: check stop condition, process input, update game state, draw frame, sleep until next frame is needed. In previous Stareater version there was no explicit game loop, it was part of WinForm's internal "message pump" which in turn is too an endless loop that waits for a message, delegates it to an appropriate handler and checks if it got "quit" message. For signaling when to draw a next frame there was a timer component which was periodically sending "timer tick" messages. It was serviceable but not a "proper" solution. Timer's timing and my implementation of it's handler were sort of a "do it when you can".
When I started adding more game loop features, namely adjustable FPS limit, a mode without FPS limit and "battery mode" where game loop is bit more mindful about power consumption, it turned out I have to do a bit of research and rework the stuff. When it comes to timing precision there are two options, busy spin (a loop which repeatedly checks the clock) and thread sleep which is more concerned with letting other threads breath then timing. Timer is basically same qualitatively as thread sleep with a difference in how a thread is notified to wake up. So it's not surprising that most game engines, including the one supplied with OpenTK (graphics library used in the project), use busy spin approach. Busy spin is good when you have a lot of animations and movement in general but one has to keep in mind that such method uses all available CPU time which drains more power, heats CPU and makes cooler fans spin while not doing constructive work during the wait period. Since Stareater may or may not have a lot of animation, I made support for use both timing methods.
There was even bigger change to game loop, it was moved to a separate thread. I looked around the internet what is the best way to implement the game loop and there was no clear best practice. One approach (repeated from basic game dev tutorials) was to have ordinary loop which has extra step in cycle to let message pump process accumulated events. Another approach was vague reference to rendering in background thread. I've decided to marry those two concepts and suffer the consequences. The biggest reason I did that is to separate WinForms stuff from OpenGL stuff. This way window can handle it self at it's own pace and frames can be rendered in parallel. No need to send redraw request through who knows how many layers of bureaucracy. Many programmers fear the multithreading but it turned out to not be that bad. Sure I had my share of deadlocks (threads blocking each other) and race conditions (parallel tasks messing with eachothers data) and had to learn some new stuff but it was worth it. I finally had a chance to use thread join operation and discovered wonders of atomic operations and it didn't take long to fix bugs. In fact I'd like to share a few stories:
Enough with technical stuff, here is how settings menu looks like now. You can select or enter frame rate frequency limit or choose unlimited mode which will draw frames as fast as possible. Options below regulate whether to use precise but power consuming timing method or potentially imprecise but much less wasteful method. A little technical detail, power mode detection (whether a computer runs on battery or is plugged in) doesn't work in Mono so Linux and Mac won't have a benefit of game automatically switching modes. Players on those platforms will have to use "always" and "never" options which force the usage a particular method.
This is just a first phase of reworking graphics engine. It went better then expected. I know I'm repeating for the hundredth time but multithreading issues are nasty beast and I'm glad there wasn't so many of them. Next phase is moving to newer OpenGL API and improving performance. I've run profiler and noticed there are very bad performance issues. There is a lot of work left to be done.
Let's back off a little bit. Game loop is part of game logic which juggles when input events (mouse, keyboard, ...) are collected and processed and when a image frames are drawn. Typically it repeats following steps: check stop condition, process input, update game state, draw frame, sleep until next frame is needed. In previous Stareater version there was no explicit game loop, it was part of WinForm's internal "message pump" which in turn is too an endless loop that waits for a message, delegates it to an appropriate handler and checks if it got "quit" message. For signaling when to draw a next frame there was a timer component which was periodically sending "timer tick" messages. It was serviceable but not a "proper" solution. Timer's timing and my implementation of it's handler were sort of a "do it when you can".
When I started adding more game loop features, namely adjustable FPS limit, a mode without FPS limit and "battery mode" where game loop is bit more mindful about power consumption, it turned out I have to do a bit of research and rework the stuff. When it comes to timing precision there are two options, busy spin (a loop which repeatedly checks the clock) and thread sleep which is more concerned with letting other threads breath then timing. Timer is basically same qualitatively as thread sleep with a difference in how a thread is notified to wake up. So it's not surprising that most game engines, including the one supplied with OpenTK (graphics library used in the project), use busy spin approach. Busy spin is good when you have a lot of animations and movement in general but one has to keep in mind that such method uses all available CPU time which drains more power, heats CPU and makes cooler fans spin while not doing constructive work during the wait period. Since Stareater may or may not have a lot of animation, I made support for use both timing methods.
There was even bigger change to game loop, it was moved to a separate thread. I looked around the internet what is the best way to implement the game loop and there was no clear best practice. One approach (repeated from basic game dev tutorials) was to have ordinary loop which has extra step in cycle to let message pump process accumulated events. Another approach was vague reference to rendering in background thread. I've decided to marry those two concepts and suffer the consequences. The biggest reason I did that is to separate WinForms stuff from OpenGL stuff. This way window can handle it self at it's own pace and frames can be rendered in parallel. No need to send redraw request through who knows how many layers of bureaucracy. Many programmers fear the multithreading but it turned out to not be that bad. Sure I had my share of deadlocks (threads blocking each other) and race conditions (parallel tasks messing with eachothers data) and had to learn some new stuff but it was worth it. I finally had a chance to use thread join operation and discovered wonders of atomic operations and it didn't take long to fix bugs. In fact I'd like to share a few stories:
- First one was an experiment. In theory when a process quits all of it's threads are killed so I tried to make game loop without explicit end condition. It turned out that exiting an application GUI left background thread working alone. Maybe it was the case when running from Visual Studio or Sharpdevelop, I didn't investigate further because I needed stop condition anyway. Game loop had to have some cleanup logic and it has to stop before GUI components get cleaned up.
- What happens when GUI and main thread hosting it quit before game loop thread? Errors and exceptions because OpenGL is being used after the application had it deinitialized (disposed the context). Cure for that bug was use thread join so that main thread waits for background thread to finish.
- More code you have guarded by synchronization mechanisms means deadlocks are more likely. When a combat happens, main thread informs game loop to switch to space battle "scene". Game loop switches scenes and calls scene initialization inside a guarded block and battle scene initialization "invokes" a piece of code on main thread. This code hides drop-down menus which triggers resize of draw area. Main thread tries to inform game loop of resize event but has to wait because loop is in guarded section so no thread can advance. Fix for this one was to make lighter signalization mechanism. Instead of guarding whole blocks of code I've reduced guards to only cover receiving signals (not handling) and simplified signals themselves (used atomic test and set instead of "monitor"). In retrospect asynchronous invocation would fix an issue too but simplifying code has further reaching benefits.
Enough with technical stuff, here is how settings menu looks like now. You can select or enter frame rate frequency limit or choose unlimited mode which will draw frames as fast as possible. Options below regulate whether to use precise but power consuming timing method or potentially imprecise but much less wasteful method. A little technical detail, power mode detection (whether a computer runs on battery or is plugged in) doesn't work in Mono so Linux and Mac won't have a benefit of game automatically switching modes. Players on those platforms will have to use "always" and "never" options which force the usage a particular method.
This is just a first phase of reworking graphics engine. It went better then expected. I know I'm repeating for the hundredth time but multithreading issues are nasty beast and I'm glad there wasn't so many of them. Next phase is moving to newer OpenGL API and improving performance. I've run profiler and noticed there are very bad performance issues. There is a lot of work left to be done.
utorak, 16. kolovoza 2016.
Library and ship building from galaxy view
As I mentioned last time two new features got in previous release build, library and star system management from galaxy map.
Library is a place where player can see information about all researchable technologies and equipment in the game. Much like civilopedia in Civilization series where player can look up all sorts of information in game instead of resorting to manual or game wiki. At the top left are categories, below it are topics in a category and the rest is information about the topic. There also an input for item level so player can see how technology benefits or ship equipment attributes are progressing. It's not the prettiest user interface but I'm not inclined to improve it at this point. In version 0.6 I'm planning to switch to OpenGL based GUI framework where I'll have much better control over how interface items look like and behave. When I get the framework working I'll gradually convert old Windows Forms interface to new one and library will be revisited eventually. In the mean time I have to rework how text is fetched from data files. Currently each item has a separate reference code for name and description text and with library there is a need for a third one, long description. So instead of actually adding third reference code on each item in game's core, I'm going to remove one and use it differently depending on context. For instance laser cannon will have only "LASER_CANNON" as text entry code and user interface will look under "LASER_CANNON_NAME" for weapon name, "LASER_CANNON_DESC" for short tooltip description and "LASER_CANNON_PAGE" for library text. It will be smart enough to append appropriate prefix on it's own.
Managing star system (the system as a whole, not individual planets) from galaxy is a small feature which greatly improves quality of life. When testing a game I usually need to build a few ships of certain kind and conclude the game in very few turns. This feature greatly accelerates the process and I hope it's usefulness goes beyond being development tool. Once I sort out new GUI framework I might extend the feature to show more star system information on map before it's selected. Much like cities in Civilization series where you can see what is being built, how long it would take and how well developed are the cities by just looking at the map, without needing to zooming in to particular city. And I'll keep adding quality of life features as I notice the opportunity.
Next in pipeline: version 0.6 plans and new rendering loop.
Library is a place where player can see information about all researchable technologies and equipment in the game. Much like civilopedia in Civilization series where player can look up all sorts of information in game instead of resorting to manual or game wiki. At the top left are categories, below it are topics in a category and the rest is information about the topic. There also an input for item level so player can see how technology benefits or ship equipment attributes are progressing. It's not the prettiest user interface but I'm not inclined to improve it at this point. In version 0.6 I'm planning to switch to OpenGL based GUI framework where I'll have much better control over how interface items look like and behave. When I get the framework working I'll gradually convert old Windows Forms interface to new one and library will be revisited eventually. In the mean time I have to rework how text is fetched from data files. Currently each item has a separate reference code for name and description text and with library there is a need for a third one, long description. So instead of actually adding third reference code on each item in game's core, I'm going to remove one and use it differently depending on context. For instance laser cannon will have only "LASER_CANNON" as text entry code and user interface will look under "LASER_CANNON_NAME" for weapon name, "LASER_CANNON_DESC" for short tooltip description and "LASER_CANNON_PAGE" for library text. It will be smart enough to append appropriate prefix on it's own.
Managing star system (the system as a whole, not individual planets) from galaxy is a small feature which greatly improves quality of life. When testing a game I usually need to build a few ships of certain kind and conclude the game in very few turns. This feature greatly accelerates the process and I hope it's usefulness goes beyond being development tool. Once I sort out new GUI framework I might extend the feature to show more star system information on map before it's selected. Much like cities in Civilization series where you can see what is being built, how long it would take and how well developed are the cities by just looking at the map, without needing to zooming in to particular city. And I'll keep adding quality of life features as I notice the opportunity.
Next in pipeline: version 0.6 plans and new rendering loop.
četvrtak, 19. svibnja 2016.
New star
It's a funny story how drawing a star has bothered me from the very start of Stareater project to the recent days. I'm not good at drawing stuff by hand so did next best thing, I made program do the drawing for me.
First one was simple, it generated a texture (image) with each pixel painted according to a certain formula and displayed it. Any change in star shape or color required changing the code and rerunning the program. Actually using the resulting image in game was a bit complicated. Back in a day I didn't know about PNG so I did screenshots of each star color variant, pasted it in MS Paint, saved as BMP, loaded in GIF editing program (which name escapes me and) and marked black as transparent. This is how it ended up looking:
Bottom row is how it looks in the game, mostly OK but could be better. Edge between star color and darkness of space is too prominent especially in the case of red.White center is invisible in yellow star and too prominent in blue. Top row demonstrates functional problem with the whole thing, since GIF has so called key based transparency (all pixels with "key" color are treated as transparent) there was no way to make some pixels semitransparent and if the star was on top of something then the fake space darkness would become visible.
At the time it served the purpose and after a while I decided to fix those shortcomings. I've made a more complex program which could save usable PNGs and could change parameters on the fly. It had a little framework for making procedural images generators and star image was just one implementation of the framework. Each image generator had it's own logic and set of parameters on GUI and the best thing was that one of the supported parameter types was symbolic function. You could type "4*x+0.5*y" if x and y were applicable variables and it would work.
Above are examples of some image generators and as I said, star image was just one of them. I also used the program for experimenting and fine tuning Stareater algorithms like starlane generator (middle image) and star positioning (right image). It was great tool for making quickly visualization.
On the other end I was exploring vector graphics for drawing starships. Inkscape was the best and de facto the only good tool for the job but it didn't click with me. It's great for hand drawing, so to speak, but lacking for technical drawing which happens to be my way of thinking when it comes to drawing something bigger then 20x20 pixel art. So I started making my own program for vector graphics, it was no good so I made another with different approach, it was better but not up to a task and repeated the process a few more times. The thing evolved from clicking points on canvas to typing them in table to writing a sort of programming language. Seriously:
On the right side is code, a sequence of points and shapes made with those points and on the left side is resulting image. It was not the most polished tool but it had potential. Unfortunately it took a lot of effort to keep improving it and code editor was devoid of usual IDE (code editor) luxuries like autocompletion and syntax highlighting. As I was developing programs in SharpDevelop, an opensource IDE, I was pondering an idea of using their code editor for my vector graphics language. And then I took the idea even further, to use C# itself for drawing. On the one end I'd to develop image generator as DLL (much like other Stareater plugins for AI and map shapes) and on the other end was program which continually monitored if DLL has changed, loaded new version of image generator and displayed a resulting image.
It's kind of return to the first program I had back in 2008 but with much faster code to image loop and so far it's serving me well. There is a bit of initial setup overhead for establishing OpenGL logic (making texture, setting perspective, setting rendering flags and drawing textured rectangles) but once set up it really easy to adjust and experiment about. Especially when secondary monitor is available, put C# editor on main screen, image preview on the other and watch the image change as you type.
And there is one more important bit of the story. While I was making all those programs I was collecting images of real stars in order to figure out what to actually draw with my programs. The challenge was to find an image were star was not a simple globe of light and not overly distorted by atmospheric noise and lens. When I finally made a satisfactory program and picked a good looking star the real fun has began, analyzing how colors change from black to blue to white and how to make similar looking stars of different colors. That part might be too geeky so I'll just leave a picture without too much explanation:
First one was simple, it generated a texture (image) with each pixel painted according to a certain formula and displayed it. Any change in star shape or color required changing the code and rerunning the program. Actually using the resulting image in game was a bit complicated. Back in a day I didn't know about PNG so I did screenshots of each star color variant, pasted it in MS Paint, saved as BMP, loaded in GIF editing program (which name escapes me and) and marked black as transparent. This is how it ended up looking:
Bottom row is how it looks in the game, mostly OK but could be better. Edge between star color and darkness of space is too prominent especially in the case of red.White center is invisible in yellow star and too prominent in blue. Top row demonstrates functional problem with the whole thing, since GIF has so called key based transparency (all pixels with "key" color are treated as transparent) there was no way to make some pixels semitransparent and if the star was on top of something then the fake space darkness would become visible.
At the time it served the purpose and after a while I decided to fix those shortcomings. I've made a more complex program which could save usable PNGs and could change parameters on the fly. It had a little framework for making procedural images generators and star image was just one implementation of the framework. Each image generator had it's own logic and set of parameters on GUI and the best thing was that one of the supported parameter types was symbolic function. You could type "4*x+0.5*y" if x and y were applicable variables and it would work.
Above are examples of some image generators and as I said, star image was just one of them. I also used the program for experimenting and fine tuning Stareater algorithms like starlane generator (middle image) and star positioning (right image). It was great tool for making quickly visualization.
On the other end I was exploring vector graphics for drawing starships. Inkscape was the best and de facto the only good tool for the job but it didn't click with me. It's great for hand drawing, so to speak, but lacking for technical drawing which happens to be my way of thinking when it comes to drawing something bigger then 20x20 pixel art. So I started making my own program for vector graphics, it was no good so I made another with different approach, it was better but not up to a task and repeated the process a few more times. The thing evolved from clicking points on canvas to typing them in table to writing a sort of programming language. Seriously:
On the right side is code, a sequence of points and shapes made with those points and on the left side is resulting image. It was not the most polished tool but it had potential. Unfortunately it took a lot of effort to keep improving it and code editor was devoid of usual IDE (code editor) luxuries like autocompletion and syntax highlighting. As I was developing programs in SharpDevelop, an opensource IDE, I was pondering an idea of using their code editor for my vector graphics language. And then I took the idea even further, to use C# itself for drawing. On the one end I'd to develop image generator as DLL (much like other Stareater plugins for AI and map shapes) and on the other end was program which continually monitored if DLL has changed, loaded new version of image generator and displayed a resulting image.
It's kind of return to the first program I had back in 2008 but with much faster code to image loop and so far it's serving me well. There is a bit of initial setup overhead for establishing OpenGL logic (making texture, setting perspective, setting rendering flags and drawing textured rectangles) but once set up it really easy to adjust and experiment about. Especially when secondary monitor is available, put C# editor on main screen, image preview on the other and watch the image change as you type.
And there is one more important bit of the story. While I was making all those programs I was collecting images of real stars in order to figure out what to actually draw with my programs. The challenge was to find an image were star was not a simple globe of light and not overly distorted by atmospheric noise and lens. When I finally made a satisfactory program and picked a good looking star the real fun has began, analyzing how colors change from black to blue to white and how to make similar looking stars of different colors. That part might be too geeky so I'll just leave a picture without too much explanation:
utorak, 12. travnja 2016.
Nukes and lasers
Shooting part of space combat is mostly done. Ships can cut each other with lasers and drop nuclear bombs on planets. Colonies can be wiped out too but I'm still testing and polishing that part. Functionally, cloaking and detection is missing and I have to decide how to make inaccurate weapons like bombs viable in ship to ship combat. The idea is to give small and maneuverable ships means of seriously hurting large ships.
Visually there is a lot of work left and I'm feeling like I am stretching Windows Forms (Windows default user interface solution) way past intended purpose. Customization options boil down to either a set of inflexible switches or overrides where I have to do whole component from scratch. There is no middle ground where I could override some parts of default look and functionality but reuse the rest. Yes, I could instead work on adding more visual feedback on hex grid like beam rays and causality numbers but GUI part is bugging me so much. I'm seriously thinking about adopting GWEN.Net (an OpenGL friendly user interface solution) and ditch WinForms as much as possible.
And I see another cloud creeping over. At some point I'll have to improve my rendering engine and basically reinvent part of Unity engine, which poses a question: should I have made the game in the Unity in the first place? I'll try to stick with no as long as I can. Rewriting would probably take way more time then it seams at first glance and I have some experience on implementing scene graphs so it might end up being faster solution. Also, doing it on my own gives me the opportunity to tailor it to my needs. There are some design decisions in Unity I don't agree with and I can work with assumptions that apply only to my project. I'm confident that my current code base is good enough to endure such changes.
It's eating me too but you'll have to suffer through ugly GUI until version 0.5 is finished. I'll put more effort in visuals in the next version.
srijeda, 24. veljače 2016.
Hex grid
At last something visible in space combat! Well, by the time I finish this post it might be complete :). Boring stuff first, some more ground work had to be done in order to trigger space battle for right player at the right time. The way how battle events are pushed to GUI had to be more strictly defined and there were some changes in AI handling. Then there was also a question of how to organize ongoing battle data. I started with what there was in CroVar version and after some experimentation I ended up with game within the game structure. Space combat is going to have similar model-view-controller pattern as the main "galaxy" game and will not be entirely stuck inside the main game. It would pop in to existence, run as separate entity and feed the results to the main game.
Now fun stuff, image above is how game looked on paper a year ago. I've been thinking about space combat for a long time, I've decided to abandon one dimensional simplification from CroVar and do proper 2D tactical TBS. And while I'm at it I could do it on hexagons. Math is slightly more complex then it is for square grid but only slightly and there are few tricks for representing hex grid in memory in a same way as square grid. Image below is how it looks like at the moment, a grid, a star, a defender near the star and an attacker's fleet on the edge (exact location deduced from the direction it came from).
More coming soon!
nedjelja, 31. siječnja 2016.
Preparing space combat
On a way to implement space combat I have implemented conflict detection logic and unstubbed some parts of the game. Conflict detection is a mechanism for finding where and when space battle happens. Under the hood a fleet can have multiple waypoints and with advanced enough interstellar drive it can pass through multiple star systems in a same turn. If one of them happens to have an enemy presence, space battle happens and the fleet ends it's turn there. When the conflict begins is also important, it influences a turn limitation. If at the end of player's turn a fleet was 1 light year away from destination, traveled at the speed of 2 ly/turn and battle happened there then it would have 50% of maximum combat turns to resolve the fight. In case the battle doesn't end by then I plan to make persistent battles which can span multiple galaxy turns. I also thought about making a mechanism where a quick enough fleet can fight in multiple systems. For instance if a fleet finishes one battle quickly and is fast enough to travel to next star system it would be able to fight a few more turns there too. The problem is int that case conflicts wouldn't be isolated and players wouldn't be able to play each conflict to the end before moving on to the next one. It might work by making players play all space battles simultaneously, one turn at the time but that doesn't sound like fun. So I'll go with one battle per fleet per turn limitation and keep the idea in the drawer :). There is also a question of what to do with colony ships that retreated from the battle, do they try to reach a marked planet or do they go home and do what exactly? I'll cross that bridge when I come to it.
Next step toward space battles was making AI build ships so a player can have somebody to attack. In order to implement that I had to change how the game rotates players during the turn. So far I had a "current player" number and only one player could interact with a "game core" at the time. On the other hand AI was supposed to do it's work in the background. Since both AI and human player used the same means of communicating with the game core AI could only manipulate the empire of current human player so for a brief moment there was an AI which filled my building queues with random stuff :). To make AI independent I tossed the concept of the current player out of the core so from the it's perspective everybody is playing simultaneously and it is up to a user interface to worry about who has the turn. Interesting consequence of it is that Stareater is now very close to having hot-seat multiplayer.
Next step toward space battles was making AI build ships so a player can have somebody to attack. In order to implement that I had to change how the game rotates players during the turn. So far I had a "current player" number and only one player could interact with a "game core" at the time. On the other hand AI was supposed to do it's work in the background. Since both AI and human player used the same means of communicating with the game core AI could only manipulate the empire of current human player so for a brief moment there was an AI which filled my building queues with random stuff :). To make AI independent I tossed the concept of the current player out of the core so from the it's perspective everybody is playing simultaneously and it is up to a user interface to worry about who has the turn. Interesting consequence of it is that Stareater is now very close to having hot-seat multiplayer.
srijeda, 16. prosinca 2015.
Colonization
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!
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!
Pretplati se na:
Postovi (Atom)









































