AI War 2:The Paradigm Shift
Contents
- 1 Known Issues
- 2 What's this phase all about?
- 3 Version 2.132
- 4 Version 2.130 Redux: Dutch Cities and Softer Eyeballs
- 5 Version 2.130 Civilian Industries
- 6 Version 2.129 No Shrooms For Ships
- 7 Version 2.128 Don't Lie About Distant Future Waves, AI
- 8 2.127 Cranky AI Exceptions
- 9 Beta 2.126 Dark Spire, Eyes, and Fixes
- 10 Beta 2.124 HRF Pacekeeping
- 11 Version 2.122 Empire Names
- 12 Version 2.121 Savegame Hotfix
- 13 Version 2.120 Improved Lobby Map Experience
- 14 Version 2.117 Ion Cannons And Melee Units
- 15 Version 2.116 GOG Networking Done
- 16 Version 2.115 Imperial Summons
- 17 Version 2.113 Dyson Growth
- 18 Version 2.112 Steam Networking Complete
- 19 Version 2.111 Initial Steam Connection
- 20 Version 2.110 AI Exogalactic War Front
- 21 Version 2.108 Galactic War Units And The Exostrike
- 22 Version 2.106 Immortals and Unresponsiveness
- 23 Version 2.105 Selection Hotfix
- 24 Version 2.104 Negative Build Percentage Hotfix
- 25 Version 2.103 Hotfix
- 26 Version 2.102 Digression For Quality
- 27 Version 2.101 Connection Status: Confirmed
- 28 Version 2.099 Last Rabbit Holes
- 29 Prior Release Notes
Known Issues
- Any bugs or requests should go to mantis: https://bugtracker.arcengames.com/view_all_bug_page.php
- Multiplayer is disabled but coming very soon. We first focused on tightening up the single-player loop (more info here), so thanks for your patience!
Multiplayer Remaining Todo List
Short-Term Work
- Allow clients to be removed and added to factions, either as the secondary controllers of them or the primary. Beyond the auto-adding happening right now.
- "Reset to defaults" on the host causes an error on the client side, and player account destruction.
- After SetUpAnyMissingFactionsForPlayerAccounts(), it doesn't seem to update the client on what their starting planet is.
- Games desync on primary key IDs for all except the starting units, which is a problem we knew we would have and were planning on dealing with. In some ways it's nice to see it happening so immediately, since that makes it easier to chase down.
Before Alpha
- V1 of the desync detection and correction code, which should probably only take a few days.
- Test the sync of ships and factions and planets/pfactions.
- Split out externaldata faction syncs.
- Do central world data syncs, including external.
- Implement fleet/fmem sync.
- Implement interface for watching sync data.
Before Beta
- Sync improvements:
- MAYBE: Refactor the entirety of ExternalData to be easier to manage and to make sure it's consistent between machines.
- We may have already bypassed the problem of this, in V1.
- Make primary keys now be generated from factions, and thus the amount of space for sync to go wrong a lot smaller.
- Maybe: Move fireteams into the main codebase a bit more, and have them have IDs issued by the faction also.
- This may no longer be needed.
- Maybe: Sync fireteams and speedgroups in a rolling fashion kind of like what we're doing with the other pieces.
- Fireteams may already be handled in that rolling faction, but speedgroups should be evaluated.
- See if we need to strip out any parts of fleets to make them more efficient or have fewer of them.
- Investigate regiments aimed at planets.
- Provide a way for specific ships to specify that they need to sync their externaldata to clients on some periodic time period.
- Consider removing things like IncomingShots on ships, as we are not generally keeping shots in sync (they last too little time, etc).
- MAYBE: Refactor the entirety of ExternalData to be easier to manage and to make sure it's consistent between machines.
- MAYBE: Re-code GameCommands to be more efficient and special-purpose. This is probably a job that is a couple of days long, and will potentially lead to widespread bugs for a week or so after it.
- This has become a maybe because, so far, the gamecommands seem very efficient as they are. And for the sync data, which was a big concern, that's being handled out of band.
- The other features on multiplayer, mainly regarding things like donating fleets between one another, and/or whatever else we come up with that is desirable.
- Find and fix as many lingering lobby and other UI bugs as possible.
- When a player joins or leaves the game in a 3+ player game, update the other clients to let them know PRIOR to the next map regeneration.
- Either using OnPlayerJoined() and similar, or SendTheWorldFromTheHostToClients()
- Why are we able to spam "randomize seed" messages and have that get away from us? That seemingly shouldn't happen, but does.
Before Full Launch
- Allow clients to save the game by having a gamecommand created (as always), but having the host then create the save and send it as a package deal to the client, who saves it.
- Get it so that clients are kept up to date on the status of other clients, so that they can make a call similar to how OnServer_GetIsConnected() works on the host.
- This is only relevant for games with 3+ players, but is a nice convenience. If the host is waiting excessively long a specific client, then it might be nice to send that information, but might be hard to get there in time for most situations.
- Whatever changes we need to make to balance in order to make things "feel right," which will be a matter of working with the multiplayer alpha and beta testers. A lot of things we already did in the past, like making science collection a humanity-wide thing that each player gets a copy of, rather than something people have to do individually (what a pain that was in AIWC). We will have to scale waves like we did in AIWC multiplayer, or in some other fashion. But a lot of the difficulty scaling is inherently handled by AIP being higher when you have to take more planets in multiplayer.
- If we're seeing network degradation or other issues due to the constant need to sync errors, then that will be to be investigated and improved. But those things are most of what the focus of the alpha/beta will be on.
- Host and client are still exchanging a bunch of no-op commands in the lobby for some unknown reason. I guess that really doesn't matter, as they are next to no data. This probably does not matter, but we'll keep an eye on it.
Untested Questions
Care to help us test outstanding items we have not had time to get to yet?
- Spectator mode needs investigating further, to make sure it can see all the various notices and warnings we would expect, and chat as normal, etc.
- Two players controlling one faction needs testing, when no empire name selected, to make sure that creates a correct-looking name.
- Same for exactly three players controlling one faction.
- Same with four or five players or more controlling one faction.
What's this phase all about?
We've been preparing for this for months, tightening up the codebase and getting everything ready as much as possible. Now it's time to start having machines actually talk to one another, and then refine from there. At this point, LiteNetLib, Steam, and GOG Galaxy are all fully working as communication frameworks, but now the game itself needs to fully handle all its logic properly on top of those. You can see at the top of this page what the current todo list is. We expect to be into beta of multiplayer in September. An unstable alpha where we do wish for feedback should be starting in the first week of September. Hopefully the alpha and beta periods are both short due to all the work of the last phase, but we shall see how it shakes out.
Once we get into a stable beta period for multiplayer, then we'll let the clock run a bit and Chris will work on adding interplanetary weapons to the base game as a free update (that's the last of the kickstarter stretch goals). This phase should wrap up all our kickstarter promises (including a laundry list of other smaller items).
Badger has already done the bulk of his work for the second expansion, Zenith Onslaught. Chris has done none of his work for that, as yet. Once multiplayer is in the "let it exist in beta and have people bang on it" phase, then Chris can circle in and get his work done for DLC2 along with those base game bits for interplanetary weapons, etc. The full version of multiplayer should launch alongside of DLC2, but we're not sure exactly when. October?
Either way, multiplayer will be in a solid state that is "beta but just because we want more time with more people testing it" for a month or so while the DLC2 work from Chris's end happens. None of the actual multiplayer stuff is delayed in any fashion for DLC2, it's been the other way around.
Version 2.132
(Not yet released -- we're still working on it!)
- Dyson Spheres now must kill all the guard posts on a planet before they can kill a reconquest command station. This should prevent a buildup of guard posts.
- Thanks to TechSY730 and Khankar for reporting
- Fix some bugs with Usurpers owned by praetorians or other AI subfactions
- Reported by GreatYng
- Try harder to make sure waves against minor factions have ships
- Reported by GreatYng
- Fixed some minor typos
- Reported by GreatYng
Multiplayer: Sync Correction V0.75
- New setting in the network tab of personal settings: Network Logging Includes Sync Checks
- During gameplay there are messages sent by the network as frequently as several every 100ms, and these are one of the largest sources of data usage. This lets you see the timing and payload size of those messages, if you think that potentially they are what is slowing things down in a networked environment.
- Stripped out a lot of old code that was related to an old style of sync (aimed at desync detection), and started building in the new sync framework (aimed at detecting micro desyncs and correcting those).
- Decided to move this to a new AIWar2NetworkSync static class in its own file, as after just getting about a third of the way through this logic, it was clear that it was pretty sizeable and overwhelming the rest of the networking code's readability.
- Added in the logic for the server keeping a list of ships that the various clients have told it are divergent.
- The server could be getting overlapping reports from several clients, but we need only one copy of this, because we're going to err on the side of caution and tell every client about each bit of sync data that needs fixing.
- We could always change this in the future if there seems to be a bandwidth benefit to this, but it would probably just mean extra processing on the host for more unique sends per-client. At the moment we judge that to be the resource that is more scarce.
- The logic for removing ships on a client that were not part of the last sync cycle, but also not new during that cycle, has been put in place.
- The idea here is that these ships probably died on the server, and the client didn't know for some reason.
- The logic for having the server do send check data for 1/20th of its ships (or stacks or whatever, as the case may be), but no more than 9000 per 100ms, is now in place.
- This is the meat of the desync detection code, and it is based around only a very few factors:
- Health lost, shields lost, extra ships contained within (of ANY fashion), current planet, and current location.
- We are generally making the assumption that if all of those things match between the client and the host, then the ship is probably in sync.
- In the case of certain faction ships that do things like gather resources or whatnot, that will obviously be very incorrect, but it is correct for most combat ships.
- For those cases where faction-specific data is potentially going to be wrong, it would be prohibitively expensive to add a bunch of checks based on that extra faction data, so we will build in separate tools for forcing sync of these non-combat factors.
- Frankly, other things like fireteam history, which would be missing on the clients, could be synced via other methods later on if we really want to. Though that's generally only used for debugging in most cases, so seems not to be worth doing.
- This is the meat of the desync detection code, and it is based around only a very few factors:
- The logic for clients checking for mismatches with their local data compared to the server is now in, and it sends back the requests to the server to have divergent units corrected.
- On PlanetFactions, there is now FactionIndex and PlanetIndex directly in order to make it easier to quickly find those in case they have been reassigned.
- Additionally, their Faction and Planet member variables are now exposed as get-only properties to keep unexpected things from happening there.
- The way that squads deserialize has been updated substantially to allow for several levels of partial deserialization for various sync scenarios.
- The sync fix code allows for normal-level same-planet sync fixes (which should hopefully look very nice with things sliding visually into new positions if positions differ).
- The sync fix code then also allows for normal-level different-planet sync fixes, which instantly disappears the old spot and puts it somewhere new.
- And finally, the sync fix code allows for catestrophic-level sync fixes, where the two entities aren't even the same (not matching faction or type), and it destroys the old one instantly and as invisibily as possible, and then puts in the new one where it should be.
- This last category is for basically when the primary key ID generators are out of sync between the host and one or more clients. These will be hit with some regularity, but they should not be hit over and over for the same unit.
- The deserialization logic for "fleet memberships" has been split in such a way that we can now sync just some of the data into them (for network purposes).
- We are not using this yet, but will once we get into the fleet sync phase of the sync cycle (outlined below).
- CalculateContentsCount() on squads now takes a required parameter IsForNetworkSyncCheck.
- If that is true, then it ignores any data that is not on the squad (but is usually on the fleet or the "fleet membership" areas.
- This is things like drones or transported ships, and city sockets. These will be something we sync at the fleet level.
- Network_CurrentSyncCycleNonSer has been moved off of the World_AIW2 object and into the AIWar2NetworkSync class.
- Same with the OnServer_SquadsNeedingSyncFixes dictionary.
- The server now cycles through a series of "sync stages," where it will sync different things other than just squads.
- This is useful for us to be able to time-slice syncing of data of different sorts... for instance fleets and fleet memberships data.
- We actually are now going to use this for separating out the squad sync checks and the divergent squad fixes, too, since time-slicing that is good for smooth gameplay as well as also making sure that multiple clients with partially bad sync cause as few excess sends as possible (that's a ms timing thing).
- The code for syncing the squads that were divergent is now in, as noted above.
- The data for factions, and for some of the Primary Key info, is now synchronized from the host to all of the clients every authorized network batch.
- On average this is probably anywhere from 10kb to maybe 40kb, at most. It's easier just to keep this in sync.
- At the moment, for ExternalData on factions and squads, there is a huge amount of inefficiency on the clients in that it is completely recreating objects every network sync right now. We are looking into various refactoring options.
- At the moment we are explicitly not syncing SpeedGroups, since those are complicated and may tend to diverge.
- We are probably going to wind up refactoring these to be by faction, or something along those lines. In fact, there are several major refactors coming, and one of those may be that a lot of the PKIDs may become faction-specific in general.
- Turns out that adding the NetworkSyncStage as a concept was a really good idea, because we not only need to sync squads and fleets, but also planets and some data off the world, too.
- The faction sync is happening once every sync frame, but it's possible we might back off the frequency of some of that if it becomes too harsh. Mainly for ExternalData stuff. But for now we'll see how it does.
- Planet has now had its data split out like squads and fleet memberships and factions and some other classes to have its own DeserializedIntoSelf() method.
- Also PlanetFaction. Whew, wow. For this it doesn't sync the entities during the partial sync, of course, unlike during disk or main network sync.
"ExternalData" Updates That Affect Mods
- The ExternalData framework has gotten a few updates to allow for us to do partial-syncs like we now do with squads and such, versus always just creating something new.
- Any mods that use ExternalData will need to be updated to use the new pattern, although it's not a huge change.
- FireteamRequiredTarget has been updated to have a DeserializeNewFrom and DeserializedIntoSelf, to ensure that what we are doing is intentional.
- Since this is a class, not a struct, it's highly efficient for us to be able to write to an existing class rather than always replacing it, even in single-player.
- The following "external data" has been updated to be dramatically more efficient with syncs during multiplayer, employing a variety of strategies that we're using in the main game stuff:
- WormholeInvasionDataExternal (this one is basic and simple)
- AI_PlannedWave_Data (this one is complex in that it has a list of sub-objects and shows how to handle that properly. It even gets rid of theoretical extras on the client machines)
- DoomData (this is really old style in terms of the data, and is not used actively, but does show a way to handle the multi-part sub-data well).
- ExternalData_AIFactionCommon (this one is ridiculously complicated and used for a couple of factions)
- ExtragalacticBudget and AIPChange as a part of this, and are good simple examples. These don't even have the new bool passed to their sub-objects, because both the DeserializeNewFrom and DeserializedIntoSelf() methods can both validly be used as part of one during-game sync (depends on relative list length, see code).
- StoredAIPurchaseCostByBudgetForSpecificUnits is a good example of where it's better to just use a bit of extra GC (especially with the new time-sliced GC unity now has) instead of doing extra CPU processing to be a hair more efficient with that memory.
- Fireteams themselves have changed from having a constuctor for deserialization to having a DeserializeNewFrom method that makes it a bit more explicit what is happening. We also pulled out the id deserialization so that we could reuse Fireteam objects as much as possible if they are being updated.
- DysonExternalData and DysonAntagonizerExternalData (another two examples of the simplest possible cases for updating a modder might have)
- MacrophageGlobalData, MacrophagePerTeliumExternalData, MacrophagePerSporeExternalData, and MacrophagePerHarvesterExternalData, which are also very simple examples.
- RiskAnalyzerData is even simpler, with no sub-objects to modify.
- AIReservesDataExt is seemingly simple, but is dodging accidentally creating two sparse lookups internally on each sync.
- AstroTrainsGlobalExternalData, AstroTrainsPerDepotExternalData, and AstroTrainsPerTrainExternalData are all pretty straightforward, although we saved ourselves a lookup load on AstroTrainsPerDepotData.
- AutosaveDataExt, even though it's not really even needed on the clients at all. Since it has some sub-data that is in a list, and in string format, we're just not bothering to send that to clients at all during syncs since it is a waste of bandwidth.
- DarkSpireData, which has some complexities with the sub objects DarkSpirePerPlanet. It has special notes in the code for any similar cases with a sparse lookup and sub-objects.
- Two "DZ" items for DLC2, which was wildly complicated to convert compared to most things. It involved sub objects DZResourceConversion, and DZUpgrade, among other nested objects. Mostly it was a good example of just following the existing principles on down, but there is one ConversionBag that was tricky enough that we're just clearing and refilling it in a somewhat GC-wasteful way rather than going into the extra complexity and perhaps incorrectness of doing it another way.
- AntiMinorFactionWaveDataExt, ExoDataExt, and MDCExoDataExt, which thankfully were all trivial examples of the common case.
- ExternalData_GroupTargetSorting, which has nothing formal to save or send.
- InstigatorPerUnitDataExternal and InstigatorDataExternal, which again the simple common case.
- SpawnAnimationData and DespawnAnimationData were very old and probably not used, but simple to upgrade.
- MarauderOutpostRaiderSpawnData is again the simple common case.
- MercenaryUnitExternalData and MercenaryGlobalExternalData, which had some more notable complexity. MercenaryBeaconState upgraded with WorkingHasBeenUpdatedThisDeserializationCycle to handle its situation. MercSpawnRequest just does it the inefficient way since these rarely exist, and only exist for a short period when they do. SingleMercenaryGroupState is a strange bit of data, and gets handled in a novel way. Thankfully MercenaryUnitData was a trivial case.
- ExternalData_FactionCommon is old and strange, but was not too hard to update.
- ExternalData_MinorFactionCommon was super old in its styling, but already was efficient enough.
- NanocaustMgrData, NanocaustPerUnitDataExt, and LastSpawnTimestamp are all extremely simple. The old FrenzyFleet stuff is still kinda-sorta there, but never has data since it is legacy, so that shouldn't cause any GC churn.
- FallenSpireGlobalExternalData and FallenSpirePerUnitExternalData had a few quirks, but mostly were the common case with some minor array clearing and preservation.
- One "NP" item from DLC2 required pretty minimal updates to work with this, hooray.
- ScourgeGlobalExternalData and ScourgePerUnitExternalData were both the common case with a tiny bit of list/dict management.
- Two "ZA" items from DLC2 are mostly the common case but with some collection management added in.
- Two "ZM" items from DLC2 are also mostly the common case with a bit of collection management.
- HRFDataExt and MarauderDataExt both were also mostly the common case with a bit of list management. There is a question mark about the regiments aimed at planets, on this and a few other locations, but they are at worst going to be inappropriately blanked out over and over again on clients in MP, which we can fix later.
- In general, any of the usages of IArcenExternalDataPatternImplementation in mods should be updated to follow the new examples in the main code. The changes are not severe.
- The most important changes are the ones above, relating to SerializeExternalData() and DeserializeExternalData() taking an extra parameter, and then each handling a graceful DeserializedIntoSelf() sub-method (and choosing if there's some data not to sync across during gameplay if required). But beyond that, there are some more changes:
- RelatedParentTypeName has been removed, as it was never used. Same with GetShouldInitializeOn.
- During InitializeData, the object ParentObject is being cast into an appropriate-type Parent object for general usage, (aka GameEntity_Squad, Faction, whatever) that people can then later use. If the type is wrong, it will just come across as null, and we have it complaining if that's the case. You can do the same or omit that part if you don't care.
Third Off-By-Default Mod: More Starting Options By ArnaudB
- The More Starting Options mod by ArnaudB is now included with the game by default (with permission), but disabled.
- Requires The Spire Rises expansion (DLC1).
- Pick between seven starting fleets and twenty starting battlestations for your custom games. These choices are balanced for regular play and are acceptable to use for achievements.
- The eight starting fleets will offer you a more varied combination of ships so you may explore more varied combinations of technologies and playstyles than those incentivised by the default options.
- The twenty starting battlestations will let you play and test every of the many turrets brought by The Spire Arise DLC, which are otherwise completely absent from the default starting options. You’ll find multiple combinations for both offensive and defensive playstyles, balanced for your enjoyment and giving you hints as to what synergies you could make with a few turrets or ships.
- This mod is off by default as to avoid paralyzing the player by offering too many choices.
- You can activate this as a new player unsatisfied with the default options, or as a veteran wishing to vary your experience of the game.
Mod: Civilian Industries Updates
- Civilian Industries 0.6.4
- Full update notes may be found on the forums: https://forums.arcengames.com/ai-war-ii-modding/civilian-industries/msg222774/#msg222774
- A large number of code optimizations, directly mostly at performance and multiplayer readiness.
- An overall nerf to Mobile Ship counts, but a simplified formula will allow easier future modification.
- A rework to the Barracks. Now scales with Mark Level, Command Tech, and can even let you get more Protectors at mark 7.
- Buffs to many Protectors. Balance for them is still being worked on.
- Resources renamed across the board, and structures now state what technology works for what resource.
- A notification will now show when a Raid is about to fire against your civilians, thanks to Chris' recent changes on the notifications front.
- Full update notes may be found on the forums: https://forums.arcengames.com/ai-war-ii-modding/civilian-industries/msg222774/#msg222774
Version 2.130 Redux: Dutch Cities and Softer Eyeballs
(Released August 31st, 2020)
We accidentally forgot to increment the version number in game. So this would have been 2.131, but is just called 2.130 in the game. Sorry about that, this is perhaps a first?
- New planet naming style added, with over 4000 names in it: Cities (Dutch)!
- Most Dutch cities, villages, and hamlets shorter than 10 characters; also includes many local spelling variations. Created by GreatYng.
- Thanks to GreatYng for creating!
- Added a new xml tag, external_invulnerability_unit_required_count, which works with external_invulnerability_unit_type or external_invulnerability_unit_tag.
- This basically lets us say that a unit of whatever sort is still protected by others (such as guard posts), but only if there are more than the number specified.
- The default number is 0, which means the previous behavior of "any guard posts present make this invulnerable."
- For AI Eyes, the number is now 3, which means that if there are not at least 4 guard posts remaining on a planet, you can go kill the eye.
- This is pretty huge, because you can now kill just part of the planet and then kill the eye before going to kill everything else.
- If we need to make further adjustments to the Eyes based on the relative ratios of strength of them versus enemies, we can do that in the future, but for now this is a solid start.
- Thanks to Lord Of Nothing and CRCGamer for reporting.
- Further balance adjustment: all AI Eyes are no longer Mark 7 at minimum. They are now Mark 5 at minimum, and if their planet would have a higher mark (6 or 7) then they will instead have those higher marks.
- This should help to make a bit more variance with them, and eyes to be a bit less of a pain in general.
Bugfixes
- Fixed HRF Nucleophilic Defenders as well as other defender types not being loadable into transports. Additionally they now count as Frigates and benefit from their hull/shield/damage settings.
- Thanks to Darkshade for reporting and -NR- SirLimbo for fixing.
- Fixed a couple of issues relating to getMostCommonPlanetForRegiment() with fire teams, which were likely leading to who knows what other errors.
- The PlanetsForRegiment Dictionary was declared as static, and so all of the regiments were trying to use the same dictionary at once, leading to exceptions as well as probably wrong results. Exactly how much chaos this could have caused is unclear, but with some of the LRP threads stalling out this is certainly not going to help (fingers crossed it was the whole thing).
- Now if getMostCommonPlanetForRegiment() is called again on the same regiment before it finishes, it will throw the error "BUG: called getMostCommonPlanetForRegiment() again for a fireteam regiment before the last call finished. Will break both calls." Hopefully we don't have people getting this, but if we do we need to know about it to fix that. In that case, the workingPlanetsForRegiment dictionary can't work as a member variable at all.
- Additionally, if there's an exception in getMostCommonPlanetForRegiment() it will now throw an exception but then exit more gracefully, letting whatever calling code keep doing its thing.
- Thanks to CRCGamer and TechSY730 for reporting.
- A few versions back, we made some changes to how the icons are rendered on the galaxy map, including planet icons. We made them keep their orientation better, but one of the things that was an unfortunate side effect of this is that the colliders on the lines between planets were often taking precedence over the actual planet or the ships at the planet. That is now fixed.
- Thanks to TechSY730 and CRCGamer for reporting.
- Heavily reworked how Journal_TooMuchAIP calculates both how many planets you have paid AIP for, as well as how many planets are neutered. It was triggering the journal entry far too early, previously.
- Please see the code or here for details: https://bugtracker.arcengames.com/view.php?id=23609
- Thanks to Sigma7 for reporting, and Badger for helping figure out what was wrong.
- Fixed old wording on the AI Eyes that still said "when there are enough fleets present on this planet" to instead read "when it is sufficiently outnumbered on this planet."
Version 2.130 Civilian Industries
(Released August 29th, 2020)
- For determining what your performance is like, the game now uses only one second of data instead of ten seconds.
- This makes the sim speed average a lot more responsive and natural-feeling.
- The "suppress upgrade prompt" setting and keybind now both work on fleet upgrades and not just science tab upgrades.
- There is some extra info in the tooltips and popups to reflect this, as well.
- Thanks to Fritz1776 for suggesting.
Second Off-By-Default Mod: Civilian Industries By StarKelp
- The Civilian Industries mod by StarKelp is now included with the game by default (with permission), but disabled.
- This lets people simply enable the mod by clicking a button in the settings menu, rather than having to find and download the mod from elsewhere.
- StarKelp has been a volunteer contributor to the main codebase off and on for a while, and this mod contains both code and xml.
- Full description of the mod is included in the tooltips in the game, but also here:
- Every empire is only as strong as the people within.
- Protect your people, and they will help your empire flourish.
- From collecting and processing various resource around the galaxy to bolster the economy, to taking up arms on their own to aid your survival, you'll find their help invaluable in the long term.
- As they flourish, so do you.
- Adds in the Civilian Industry faction, a potent defensive faction that can be allied to either a player, or a faction team.
- They will expand alongside their respective ally, and produce a large number of defensive forces to aid their team.
- They gain a new resource type per planet they expand to, and will work diligently to spread these resources throughout their empire.
- When allied to the player; you will find your command station and battlestations have access to a few new structures that you can invest in to greatly incresae the power of your civilian economy.
- Please check Galaxy Settings for many tweaks in regards to how they behave.
- Every empire is only as strong as the people within.
Bugfixes
- Fixed a bug in GetIsWithinRangeOf() that could happen in the selection logic (and probably other places) if a background thread marked a unit as deleted as it was doing the range check.
- Thanks to CRCGamer for reporting.
- It is now possible that your logs will wind up having the message "BUG: overriding speed limit for group X to [a negative number below -1]. Overflow? Setting to -1 instead."
- If this is frequent, it may slow down your game, but the stack traces will let us know where we are going wrong and causing this to happen.
- We fixed one area where MAYBE this could be caused, but probably that was not possible in the place we fixed it. Most likely the problem is in something that is calling GameCommand_CreateSpeedGroup with a command.RelatedIntegers[0] that is greater than the 32767.
- With that in mind, anything that is larger than that being passed into that method is now automatically corrected down to 32766. This may lead to some turbo speed groups, not sure, but at least they won't be erroring... and that IS what the calling code is asking for, so maybe it's intentional?
- At the same time, in some other places in the code where it was checking to apply the speed only if it was "not -1", it is now checking to apply the speed limit if it is "greater than 0." This seems more like the correct intent, and hopefully won't break anything.
- And beyond that, prior to serialization, any speed groups with an OverrideSpeedLimit less than -1 will automatically just set their value to -1 silently and thus avoid popup errors that could be really annoying in savegames for folks. This has been an issue on and off since July 24th, apparently.
- Thanks to Lord Of Nothing (twice over), TechSY730, GreatYng, and Apthorpe for reporting.
- Add a new time_must_have_been_on_planet_before_transforming_if_outnumbered_or_outnumbering, for use with transform_when_outnumbered and transform_when_outnumbering.
- This defaults to 0 seconds, which has been the behavior in the past.
- But now for all of the ships (mostly AI Eyes, but also some guardians) that use transform_when_outnumbering, it now has a value of 2.
- For those that use transform_when_outnumbered, it has a much higher value of 30, to keep them from downgrading their alertedness too easily.
- The AI eyes will still switch between alerted and unalerted status every so often in a general battle, since their alerted status increases the balance of battle in their favor so much, but now it won't be a constant thing and ships can continue targeting them in a reasonable fashion.
- Thanks to whakomatic, Ovalcircle, MasterGeese, Gdrk, and GreatYng for reporting.
- Additionally, previously anything that was transforming via one of those two methods was having its health and shields and cloaking points all reset to full.
- Now, however, when transformed via these two cases ONLY, it keeps the health and shields and cloaking point losses after transformation.
- This makes it so that battles with AI eyes are actually something you can win, even as they cycle back and forth between statuses. And in general this just makes sense, and is important on the dire guardians that use this same sort of mechanic, too.
- Thanks to whakomatic, Ovalcircle, MasterGeese, Gdrk, and GreatYng for reporting.
Multiplayer Work
- GameCommandTypes are now serialized by index rather than name, which chops off the vast bulk of size from most GameCommands, leading to even snappier networking.
- Honestly this is a very small boost in most cases, but this also took like two minutes to add.
- The network traffic logs have all been updated to be able to actually report how many bytes were read in for each message that the host or clients receives. Before it was saying ?? because we were checking prior to doing the reading.
- Note that depending on the networking platform in use, there is sometimes extra buffer data that was read from the socket, but if it wasn't part of the game, we just ignore all that. This is also ignoring packet header sizes, so we're just talking payloads here (but that's consistent with the send records, too.
- In the escape menu, on clients and the host, it now has a new Multiplayer Stats section when you are in multiplayer mode only.
- At the moment, this shows how many messages have been sent or received in total, and how many bytes/kb/mb have been sent.
- These all apply to the current session only. So if you are the host, it is the stats since you loaded up the server and people started connecting. If clients come and go, it's including all of that. If you're the client, it's the amount since the last time you connected; if you disconnect and then come back, it starts over.
- This is pretty important information in terms of figuring out just how much data is actually being sent back and forth, and how it changes during gameplay, so that we can react to any unexpected spikes if there are any.
- At the moment, this shows how many messages have been sent or received in total, and how many bytes/kb/mb have been sent.
Version 2.129 No Shrooms For Ships
(Released August 28th, 2020)
- Nanocaust now prioritize holding planets adjacent to their homeworld
- Thanks to crawlers for reporting
- The nanocaust units now prefer to spawn a bit further from their centers; it looked kinda weird when a giant Nanocaust ship would spawn right on top of a nanobot center.
- Added a lot of extra instrumentation to the deserialization and serialization of factions, since there seems to be some sort of error in there with savegames from specific versions.
- Essentially with this sort of thing on, we can now manually look through the deserialization log and see if we notice where field data stops making sense. It was obvious that it was getting something like "I am hostile to 20 thousand factions," which is nonsense data, but it was not clear where the data was going wrong prior to that.
- From this, we could then see that most of the data reads in the player faction seemed reasonable, but the faction right after them was immediately messed up. This is after a lengthy code review turned up nothing wrong, so it's always possible that it's some sort of edge case that has been around for longer than we thought.
- Added in code to make it so that if an exception is thrown while deserializing a faction, we will now repeat that error better and stop doing further deserialization attempts. It turns out that was what was happening, and a more careful reading of the log could have saved about an hour and a half of work (oh well, things in the future will be easier to debug).
- Thanks to Lord Of Nothing for a very challenging save that led to these changes.
- Fixed an issue with some savegames that had hacked dyson or dark spire ships, where the HackToGrantShipLine_DontDestroyTarget hack had been removed and split into several versions a few versions back.
- We now have added HackToGrantShipLine_DontDestroyTarget back in, in a deprecated fashion, so that old savegames with this data in it can load.
- Thanks to Lord Of Nothing for the save that let us find this.
- Fixed a bug in the prior build where the "flair" overlays for ships in the main view were either black (some machines) or a rotating color set of insanity (others).
- One line was accidentally omitted in the new build of the shader that we made.
- We also updated some calling code to the shader in a way that is harmless but not actually needed for this fix.
- Thanks to Strategic Sage, Isiel, CRCGamer, and TechSY730 for reporting.
- The "Icons Disappear When Camera Lower Than" setting in the main camera window has been updated as follows to have this note
- Note: this setting does nothing (icons always draw) if you have 'Skip Drawing Ship Models' turned on in the Performance section.
- (Also, this is how it actually now works).
- If a player is already on a planet viewing that planet, and a further command was sent to view that planet again (as if they were not already there), then funky stuff happened in various places, including the wormholes getting half-initialized and not drawing properly in scale.
- To solve this, it simply doesn't do anything if you try to re-open your view to the existing planet you are already on.
- Thanks to StarKelp for reporting.
Version 2.128 Don't Lie About Distant Future Waves, AI
(Released August 27th, 2020)
- Fix a bug where the scourge would sometimes suicide into multiple layers of defensive planets in the (foolish) hope of hitting the weak target on the other side.
- This is an intelligence improvement for all factions using fireteams (Hunter, Warden, Nanocaust, Scourge, etc etc).
- Thanks to Crawlers for reporting
- Add some defensive code to the Fallen Spire.
- Put in extra logging for the SpeedGroup serialization and deserialization, to figure out where there are occasional exceptions being logged.
- Thanks to TechSY730 for reporting.
- Sniper Energy Wave on the Dark Spire Eidolon has been renamed to just be Energy Wave, since this is not an infinite-range weapon.
- Thanks to crawlers for reporting.
- DoForKnownWavesAgainstHumanHomeworlds in WaveUtils has been renamed to DoForKnownWavesAgainstHumanWorlds, which is what is accurate.
- A whole bunch of extra array indexing calls into QueuedWaves have been made more efficient in the AI HandleWavesForAI() method.
Interface Improvements
- The planet's tooltip has been updated to show the owner on the same line as the planet name, but positioned way over to the right.
- This keeps things pretty condensed, but avoids some clashes of words where it seemed to be saying something like "Permanently Watched Owner:" as one phrase.
- Previously, there was a chat message going out as soon as a wave was queued, but before it would become visible to the player in the actual interface (based on their chosen galaxy map settings for how much warning to get).
- Now it only shows the actual chat message from the AI as the wave is being revealed to players.
- This also fixes an issue where it was for some reason actually giving the wrong planet name that it was going to attack in some cases, since the announcement came before it finished changing its mind about the real target it wanted to hit.
- This latter one may have been more common in multiplayer, but it's hard to be sure. At any rate, it just tells you real information now.
- The second chat message that goes out (with the audio taunt) when waves are launched now also happens when they are revealed, and no longer duplicates when in multiplayer mode.
Mod Compatibility Improvements
- There is a new DoPerSecondNonSimNotificationUpdates_OnBackgroundNonSimThread_NonBlocking() method that gets called on each faction each frame, and which takes in a note which says if it is the first faction of its type this frame or not.
- This lets us move notifications for factions into their own files, which makes notifications modding-compatible.
- There are some other supporting methods that have been added to handle this, but understanding them is not required for using this,.
- It is worth noting that ALL of the existing DoPerSecondNonSimNotificationUpdates_OnBackgroundNonSimThread_NonBlocking() calls do happen in a loop prior to the new DoPerSecondNonSimNotificationUpdates_OnBackgroundNonSimThread_NonBlocking() being called.
- As an interesting side effect, this actually makes it so that notifications will now work for people in spectator mode in multiplayer for the first time.
- The nanocaust data has been moved out of the human file as an example of how to do the others.
- Same for antagonized dyson spheres, and the dark spire. It would be great to get the other factions moved over to their own files for the sake of cleanliness, but functionally there will be no difference for our things in the main game and expansions now.
- Thanks to StarKelp for requesting the ability to add notifications in mods.
- Added a new method DoPerSecondLogic_Stage0Clearing_OnMainThreadAndPartOfSim_OncePerFactionTypeEvenForFactionsNotInGame().
- This is called on the GetDefaultImplementationForLobbyOrClearingOnly() from the faction TYPES, which means it happens even for the factions not in a game. Great and easy place to clean up, and we know it happens only once per cycle per faction type, and we also know that it happens even if a faction is not in the current campaign.
- This is useful for factions that had some data in a prior campaign, but the player loaded a new savegame and they are not in this one.
- All of the various data from these that was previously in the Human class and in DoPerSecondLogic_Stage1Clearing_OnMainThreadAndPartOfSim() has been moved to the new stage0 for each of the specific class types, which again is more mod-friendly and should prevent the issue of certain mods being unable to clean themselves up between campaign loads.
Multiplayer Work
- When the host is waiting on a client that is behind, it now shows a message saying which clients are behind and being waited on.
Bugfixing
- The galaxy map spacebox background is no longer serialized into savegames. Instead it is deterministically calculated based on the map seed.
- This makes very little difference for single player, although you will notice that reloading the game or going back and forth to the map, or hitting regenerate map on the lobby no longer changes the space background.
- But for multiplayer, this keeps things consistent between all players.
- For existing savegames, you will notice that the spaceboxes become something new and stay that.
- It turns out that the planet spaceboxes were not being serialized at all in savegames before, but their rotations were.
- This was leading to very different planet background views in multiplayer, to a very distracting degree.
- This has been made deterministic, and we no longer store even the rotations in savegames.
- For single player there is no real change except that the savegames are a tiny bit smaller.
- For existing savegames, you will notice that the spaceboxes become something new and stay that.
- Fixed inconsistent sorting between runs of the game (and between differnt clients) for rows in the following tables:
- AIGuardPostAndCommandPlacerTable, FleetDesignTemplateTable, AIShipGroupCategoryTable, and SpaceboxDefinitionTable.
- These led to various MP inconsistencies, including the spaceboxes still being divergent on planets despite the math lining up.
- Fixed an issue where the home planets of other players in multiplayer games just looked like normal planets instead of homeworlds.
- There were a bunch of cases where human factions were still named wrong during multiplayer (and differently on the host and client), saying the wrong player's name or Unknown Player in various cases. Fixed all of those.
- Additionally, in the case of multiple players owning a faction, if they did not choose an empire name, it now says all of their names together (but no more than three) as the faction name.
- If there are more than three players controlling a single faction, that gets too wordy, so it just says "and X more".
- When loading the single player games of other players, you will now see their chosen account names (from in AI War 2, not Steam or whatever) instead of your personal profile name.
Seeing Where Other Players (Or Spectators) Are Looking
- The way that the gimbal icons decide which diffuse color to use is now more efficient on the GPU (this is minor, but hey).
- It is now possible to have a secondary diffuse color for the flair (really used for selection circles now), which is multiplied by the main "other diffuse color" of the icon.
- This lets us do things like change the opacity or color of the selection ring around a ship or planet.
- When you are viewing a planet, the game's way of showing the selection circle around it is the same as it always has been.
- However, when someone else in multiplayer is viewing a planet other than the one you are viewing, it now shows a dimmer and more-transparent selection circle to show you that someone else is looking there.
- If someone else is looking at the same planet you are looking at, then it will show the normal bright selection circle in a faint green rather than white.
- This is something that is deceptively important, because we need to make sure that we know which planets are "tier 1" planets on clients and the host, which lets us verify that ViewedByPlayerAccounts_DuringGame is being set properly on all machines (it is). This keeps the game in the sync, which we can now tell is working properly.
- But also this is just a helpful indicator for players to help with coordination. ("Check out this planet I am looking at in the northeast" is so much easier to say than trying to direct them to a name).
- As an added help, in the galaxy map view when you hover over a planet, it tells you which other players are viewing a planet. This may be players in exclusive control of a faction, or one of several player players controlling a faction, or just a spectator, so it shows you their name as it would appear in chat.
- For games with more than two players, this is fairly important for purposes of clarity. In a two player game it's easier to just infer what is going on.
- When a client is disconnected, other clients and the host can still see what planet that client WAS looking at, and that planet still counts as a Tier 1 planet for processing, but hovering over it will show the name of the player with (Disconnected) behind it on the host.
- Presently clients cannot see the status of other clients.
Disconnection And Re-connection Verified
- We can now verify that after a client disconnects in a disorderly way, the host notices a bit later and then continues on without them (they can choose to pause or not).
- We can FURTHER verify that the client can reconnect to that running game with only a few-seconds interruption to other players who are still going. Even if the client had crashed and had to restart the game or their computer, they are able to get right back in there.
- The original AI War did not remotely have any of these capabilities, but this works on all three networking platforms.
2.127 Cranky AI Exceptions
(Released August 26th, 2020)
This was originally released as a beta on the 26th, but then changed to a main branch release on the morning of the 27th.
- The Dark Spire now responds properly to being hacked by being cranky
- Thanks to crawlers for the bug report
- Fix a bug where the AI was incorrectly combining some Hostile To All factions when spawning extragalactic war units.
- This was leading to more extragalactic war units than one would want.
Exception Fixes
- Added new debugging instrumentation into ImportIntoDynamicTable_XMLDirectory, so that we can find errors that may happen in there from time to time on some machines.
- Also put in some code that should make it load faster for mods and expansions that don't have certain folders.
- Thanks to Ovalcircle for the report of something mysterious in this area on his system.
- Also expanded the debugging instrumentation on ReadXmlFileIntoBatchProcessingLists, same reason.
- Ditto DoForXmlFolders.
- And finally, ditto ActuallyImportAllOfTheBatchedRows.
- Thanks to Ovalcircle for the report of something mysterious in this area on his system.
- ArcenXMLElement.GetNewFor has had its debugging instrumentation greatly expanded, and also has been split into one version that expects a data table, and a new GetNewForNonTable variant that does not expect a table.
- The idea here is to catch various forms of errors early.
- This in turn caused a cascade of other changes to other methods needing variants of each other along these same lines, and having better instrumentation.
- Thanks to Ovalcircle for the report of something mysterious in this area on his system.
- Fixed another rare race condition that could happen with the vis code, this time in SetFormationPositionFromSquad.
- Thanks to NRSirLimbo for reporting.
- If for whatever reason the game was not able to proeprly write your settings data, it was still overwriting your settings file previously. It will no longer do that.
- Additionally, a lot of extra instrumentation has been put into GameSettting.SerializeGraphicsTo and GameSettting.SerializeTo, so that we will know better what is wrong if it is trying to save improperly. These should also be more resistant to saving incorrectly in the first place.
- Thanks to Isiel for reporting.
- If a savegame has somehow been made that has a blank savegame in it, then it will try to load it with the info of the current version of the game, with a warning in the log that this may fail very badly.
- Thanks to Isiel for reporting, and providing a save that was probably made while the game was in an invalid state.
- Fixed a case where trying to load certain saves could fail silently as far as the interface was concerned. Now it actually shows you a proper error message.
- And then fixed a whole bunch of cases where certain code paths on almost-certainly-broken saves would return very genric and unhelpful errors when you tried to load them.
- This doesn't really help us actually load the savegames in question, but tells us more about what is wrong with them.
- Thanks to Isiel for reporting, and providing a save that was probably made while the game was in an invalid state.
- Suppressed a harmless popup that could happen in ReactToShotHittingSquad during cross-thread race conditions. Now it just fixes the data and moves on.
- Thanks to CRCGamer for reporting.
Beta 2.126 Dark Spire, Eyes, and Fixes
(Released August 22nd, 2020)
To play this version, please be sure to choose the current_beta branch on Steam. The central game loop changes we made in the prior version did not blow up, but a few other things did, so we're glad we went the beta route. If for some reason this beta has problems but the prior one worked for you, we have temporarily made the most_recent_stable_beta active and pointing to 2.124. But this version should actually be more stable (knock on wood). We'll be back out of beta by mid-week the week of the 23rd.
- Fix a bug with DS Conquest VGs and the new hack
- Thanks to gigastar for reporting
- Fix a bug with the Full Metal notification
- Thanks to a screenshot from Oval for making me aware of this
- The AI should now attempt to play voice lines for Exogalactic Strikeforces, and when you spot the Nanocaust.
- The DS is no longer allowed to spawn Loci on planets with Dark Spire Wards
- Thanks to crawlers for reporting
- Make the Dark Spire more aggressive about spawning Loci
- Thanks to crawlers for suggesting
- The player can now choose the starting armory for player-allied scourge
- Thanks to crawlers for suggesting
- Improve the hovertext for some scourge units just a bit.
- Fix a bug where new games in the beta weren't starting correctly
- Thanks to Keith and Tynendir for reporting
- Capturing an AI homeworld no longer generates AIP. This only applies to games creates on 2.125 or above.
- Thanks to GreatYng for suggesting
- AI Eyes now trigger based on whether you have more Strength on a planet, not off the number of fleets
- This is not necessarily the final state for Eyes, but having them trigger off of 'number of fleets' didn't make any sense anymore. This is a functional stopgap until someone has a better idea
- Thanks to a number of people for discussing, including Flypaste, Asteroid, Democracy, GreatYng and others
- Fixed typo in multiplayer message.
- Thanks to fwiffoforce for reporting.
Beta 2.124 HRF Pacekeeping
(Released August 18th, 2020)
To play this version, please be sure to choose the current_beta branch on Steam. If this isn't blowing up in major ways, we'll move it back to the main branch within a few days. If it is blowing up a lot, then it may be into next week before we come back from beta. We changed too many fundamental things with the game loop to just release this with no beta, even though we were careful.
- Minor rework to minor faction hacks. Its now more expensive (in line with the previous hacks). The description no longer mentions an AI response. The DS and Dyson units are now upgradable, but not very much. These are intended to be 'cool little tidbits' but nothing to really swing the game
- Thanks to GreatYng and Lord of Nothing for bug reports and comments
- Add a 'Full Metal' indicator in the metal bar
- Thanks to Nyarlathotep. Iä! Shub-Niggurath!
- The hovertext prompt that describes when swapping ship lines will scrap your units has been modified to describe the current behaviour correctly ("Your ships are scrapped if they are loaded, or the flagships are on different planets").
- Thanks to StrategicSage and Ubifan for reporting
HRF Changes
- The HRF ships now have some unique names.
- The HRF now create a structure at game start time that you can hack for a new ship line (using the backported DLC2 tech) and for 1K science
- Fix a longstanding bug where the Human Resistance Fighters would only say their 'defeat' voice lines, not their 'victory' voice lines.
- Thanks to Nyarlathotep. Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn.
- The HRF should now pack a bigger punch when they arrive, but they are a bit less likely to show up.
Bugfixes And Tweaks
- Some minor improvements to the ability of vulnerable Vengeance Generators to be killed
- Hopefully this helps. Thanks to Lord of Nothing for reporting, and Puffin for suggesting the improvements
- Better enforce the 'can't repair ImmuneToRepairs' unit interactions. Still a bit weird.
- Thanks to MasterGeese for reporting
- SerializeByInternalName and SerializeByIndex both now accept FieldName as an optional parameter so that we can see what is happening within them from a serialization logging standpoint.
- A bunch of extra serialization logging has been added into the world and the faction configuration objects, to make finding errors there easier.
- However, it turns out that there were no public errors on this, just an error in a working copy on one developer machine that had a save from between two updates from that same developer.
Milestone: Multiplayer Pacekeeping Functional
- In the event of a campaign switching which player is the host (this probably means one player manually emailing the game to another), the game now tries to do a better job of handling that.
- In the end this should work fine, but we haven't bothered testing this yet as this is probably kind of an edge case compared to most other things we're working on right now.
- All of the "frame number" information for sim frames is now just serialized on the network and never to disk.
- This information is really only useful within a single run of a campaign (aka after loading it off disk and playing until you exit to the main menu or the OS).
- Even if you go just back to the main menu and load back into the game directly after, there's no reason not to start those numbers off fresh again.
- We've thus switched to a number format for serializing these that will "only" allow for 160 hours of continuous realtime play in a given campaign, without exits to the main menu. This is the definition of excessive, and could always be changed in the future if it was needed.
- A variety of variables that really are only for the network, and serialized but not to disk, now have the prefix Network_ so that we can tell those apart with ease.
- In multiplayer, the basics of "host waiting for clients to catch up" is now in place. This prevents the strange lag that clients were seeing, which was happening because they were back in time.
- However, also in multiplayer, unlike the original AI War, it will not definitely wait around for players who are missing. If those players are not connected, then you can unpause and play without them until they arrive. Only once they are present do you have to wait for them to sync up.
- If this latter choice turns out to be problematic for some reason, we can always add a toggle for that or change it. But it seems friendly. Chris remembers nights where 1 person out of 4 player game couldn't make it, so just keeping on playing without them would have been so nice versus having to go in and change the status of their account before playing.
- However, also in multiplayer, unlike the original AI War, it will not definitely wait around for players who are missing. If those players are not connected, then you can unpause and play without them until they arrive. Only once they are present do you have to wait for them to sync up.
- Various of our "simulation profile" variables that were set a loooong time ago in a different way for multiplayer and single player were making multi-player feel sluggish. We've tightened up this some in order to feel better under a pretty general set of networking conditions.
- We may need to revisit this in the future (during alpha or beta) to make these things that people can configure if they are in a situation of, for instance, high packet loss or extremely high or low pings, to get the best possible experience at any given time.
- Various other changes have been made in order to make the client send over commands to the host as soon as possible, and then to make sure that the host causes those commadns to be executed on the FIRST simulation frame of the next batch, not the last frame of that next batch.
- All in all, the game now stays in time sync, across Valve's server relays and back, and things are snappy and responsive on both the client and the host. There are moments of delay that cause a brief "waiting" message to flash up for maybe a quarter of a second every so often, but it's really a minor thing and is something that we can improve with tuning in the future.
- The overall functionality is there to the point that if background threads and floating point math were not knocking things out of sync, this would be a perfectly playable alpha. As it stands, it's quite playable for a few minutes at a time, at least on Chris's two test machines, without things becoming noticeably off.
- It's also worth noting that the simulation speed on the host shows up as being something like 80% right after starting the game, which is misleading because it had one very long frame where it was waiting on the client to connect and sync up. That will be fixed in the future, but it self-resolves the visual artifact within something like 20 seconds of starting, anyhow.
Version 2.122 Empire Names
(Released August 17th, 2020)
- *Makeshift Drones now once again self-destruct when attacking instead of only self-attritioning slowly.
- Thanks to NR SirLimbo for fixing.
- The lobby now once again allows for you to zoom in and pan around, since some maps can be larger than you can comfortably see on a single screen.
- However, every time you generate a new map, it will default to showing you the entire map completely zoomed out.
- It also no longer EVER allows edge-panning in the lobby, as just general usage of the lobby will wind up with you accidentally panning the lobby around if that is in place.
- Thanks to CRCGamer for confirming our suspicion that we'd need to do this.
- Fixed ANOTHER bug with the lines being offset from the planets in the galaxy map, this time when you were zoomed in. The more zoomed in you were, the more off they got.
- This bug was caused by our latest fix to the lines being off when you were zoomed out. Now it should work at all zoom levels. This was an annoying one, to be sure, but we're glad to have it finally lining up all the time.
- Fix a bug where player-allied scourge weren't building properly
Multiplayer Progress
- Added a new Human Empire Name setting on player factions:
- If left blank, will be the name of the first player controlling this faction. If you want your empire to have a different name than your personal name, you can do that here. If multiple players are sharing a faction, then they can give it a name that represents their shared interest in it.
- This can be edited during the game (like player colors can be), or in the lobby.
- When a new player joins as a client to a game, it now creates a slot for them and puts them in charge of it instead of them defaulting to spectator mode.
- It assigns their colors properly, and all of that sort of thing, too.
- Player accounts beyond the first are now removable, which lets players go back into spectator mode, or (later) control a single faction via multiple players helping.
- This makes the default case (everybody has their own faction) set itself up by default, but then lets players back things out into the less-usual cases (shared factions, spectator mode, etc).
- Players beyond the first are now auto-assigned a starting planet somewhat at random, letting them choose something on their own later.
- A whole lot of logic that was very not-MP-safe is now MP-safe.
- When loading a savegame or quickstart into the lobby, or loading the last settings for the lobby, it strips out all human players beyond the first.
- This is consistent with it then recreating player accounts as those come in, too.
Version 2.121 Savegame Hotfix
(Released August 17th, 2020)
- Fixed a deserialization bug in the prior version that made any games saved with a dyson sphere in them not able to be loaded if they were saved in the prior version.
- The nature of the issue was such that those savegames will now load without issue, thankfully.
- Thanks to Lord Of Nothing, CRCGamer, fatcat__25, GreatYng, Djri123, Djri123, mekolab, and goz for reporting.
Version 2.120 Improved Lobby Map Experience
(Released August 14th, 2020)
- Fix a bug where sometimes the AI's ships wouldn't be allowed to retreat
- Thanks to Sigma7 for reporting
- Hopefully fixed a problem where sometimes allied scourge could kill AI Command Stations immediately after a game load
- Thanks to GreatYng and ZeusAlmighty for reporting
- Fix a typo with the Spire and Marauder Beacons
- Thanks to Apthorpe and Ovalcircle for reporting
- Fix a bug where hovering the Hacking resource bar entry would give a negative number during the superterminal hack
- Thanks to GreatYng for reporting
- Improve the Hacking Resource bar hovertext for the case where you have multiple hackers. Note it still doesn't show hacks against planets.
- Thanks to Lord of Nothing for reporting
- The MDC hovertext no longer mentions Exos
- Thanks to Strategic Sage for reporting
- Exogalactic Strikeforce speed updates:
- Previously, Exos had travelled at 1800 speed (as of a few patches ago. Before that they didn't have a consistent speed).
- Now Exos travel at "Average speed of their units + 20%" or "800", whichever is higher. This should feel less like they are speed-racing to your homeworld. For speed-context, 800 is the speed of a Parasite.
- Thanks to GreatYng and Lord of Nothing for discussion
- Fix a typo in the hovertext for larger numbers of planets
- Thanks to Lord of Nothing for reporting
- Remove a mention of Fleet Exp in a tooltip
- Thanks to Lord of Nothing for reporting.
- Take safest path through galaxy now uses the modifier key alt, while take shortest path now uses the hotkey ctrl.
- The prior hotkeys of X any Y conflicted with other functions and changed your unit stances or sidebar status, etc.
- Thanks to Sigma7 for reporting.
Ability To Reset Camera View To Default
- New hotkey in the camera section: Reset Camera Rotation And Tilt
- Default ctrl+R.
- Press this button combo to reset the camera's rotation and tilt to the default values.
- Thanks to dv, Ovalcircle, Bobtree, and many others for requesting.
DLC2 Backports
- The Dyson Sphere Golem can now be hacked like an ARS for one of a small selection of Dyson ships. You only can use this hack once.
- The Dark Spire Vengeance Generators can now be hacked like an ARS as well
- This is a backport of a DLC2 feature that allows for a minor faction to have a structure which can be hacked like an ARS for unique ships. This is usable by modders with only some XML.
- Approximate usage: in the minor faction GameEntity XML, for the ARS-equivalent, set the following
- Assign it the HackForShipType tag
- Make it eligible for the HackToGrantShipLine_DontDestroyTarget or HackToGrantShipLine hacks
- Then add the following additional fields
- grants_stuff_to_be_added_to_player_fleets="true"
- grants_stuff_to_be_added_to_player_fleets_strikecraft_options="X"
- grants_stuff_to_be_added_to_player_fleets_frigate_options="Y"
- Then for the ships you want to have available, set one of these
- <fleet_membership name="AddedToFleet_MinorFaction" ship_cap_group="Strike" weight="100" min="30" max="35" faction="factionName"/>
- <fleet_membership name="AddedToFleet_MinorFaction" ship_cap_group="Frigate" weight="100" min="1" max="1" faction="factionName"/>
- Note the FactionName in the fleet_membership must match the name of the faction (I believe it checks the TracingName for the faction, which is set in C#)
Dark Spire Improvements
- There's now a preliminary Journal Entry for the Dark Spire when you first see them.
- There's now a Journal Entry for when the Dark Spire enter conquest mode (ie from the Fallen Spire campaign).
- This explains what Conquest Mode is, and it's much harder to miss.
- The tooltip for the Locus now prints different text in Conquest Mode.
- Thanks to crawlers for the bug report that prompted these enhancements
Galaxy Map And Camera Display Work, Lobby Map Overhaul
- The galaxy object now has a a FindSpatialCenterOfGalaxyInGalaxyCoordinates() method, which lets us find the center point of the galaxy based on however the planets were seeded.
- Also added FindSpatialBoundariesOfGalaxyInGalaxyCoordinates() to let us find the overall bounds easily.
- But actually we're going to not bother using this, turns out.
- We were also working on a CenterGalaxyOnAllPlanets() method, but we've abandoned that for a different approach. The code is mostly complete and left in for now so that we can revisit it if we find a use for it.
- The old-style cameras have been disabled for a long time (years) in xml, but we've now removed them from the code as well.
- Added extensions GetWorldSpaceBottomLeftCorner and GetWorldSpaceTopRightCorner for UI RectTransforms.
- The chat window in the right hand side of the lobby in multiplayer now uses this and a world space to camera transform to calculate its ScreenSpaceLeft, which lets us, regardless of your screen resolution, DPI, aspect ratio, or custom settings in this game itself, figure out where the UI ends and avoid underlappig it.
- Same thing with a ScreenSpaceRight on the map tab left sidebar.
- Same with ScreenSpaceTop on the footer controls, and ScreenSpaceBottom on the header controls.
- For the galaxy map camera, the zoom now lets you go out farther in the lobby, and even farther in the multi-player lobby, so that it can always fit the map entirely in the main view screen.
- Tested this with the game at 900px wide, 1800px wide, and 2560 pixels wide. In all cases we now come out with a consistent result.
- Fixed up a bit of logic for the dynamic zoom for resolutions smaller than 1200px x 900px.
- In the lobby, the galaxy map camera no longer responds to mouse or keyboard input at all. This is an overhaul that has been requested for years and years.
- Now the lobby always has the map as zoomed out as it can.
- It is also centered in whatever the available space is (depending on if the right-hand sidebar is there or not, that may or may not be centered on the actual screen).
- This is extraordinarily useful, in that it lets you cycle through maps with ease, and there is typically not too much detail that you need to see in them like you would during an actual game.
- The math for how much the galaxy camera should be able to zoom out has been entirely re-coded from scratch, and is now vastly more efficient as well as something we can actually follow.
- Instead of taking something like a thousand loops to get a kinda-bad answer, it now takes typically under 60 loops (often under 20) to get a highly accurate answer.
- In the galaxy map display calculations, and number of strange magic numbers were removed, now that we have the proper math in here. Wow this was unexpectedly hard.
- At very long distance zooms, the planets were STILL being visually offset from their lines that they were above, it turns out.
- This had to do with how we were offsetting the icons in order to avoid z-fighting, and how that was getting magnified by us scaling up the planets at further zoom distances.
- The fix for this might introduced some z fighting, but probably will not because of the way that we are rendering these as "cutout" style transparency, and with GPU instancing determining the order of draw.
- In the lobby, the planet you own is no longer ringed in white selection, as the in-game "planet you are on" is done. Now it just shows the planet color, plain and simple.
- In the lobby, if you have the setting "always show planet names" on, it still won't do that, because that will make the fixed-size galaxy map potentially impossible to read.
- The galaxy map in general shows planet names that are un-owned as being far less blinding white in their text.
- In the lobby, it no longer shows the first owning player name under the name of the planet.
- The visual scale of the actual planet spheres in the lobby is now about a two thirds what it previously was, but the text is almost as large as it was before. If the text is too small, we can adjust it up.
- In the lobby, hovering over a galaxy map link no longer highlights the two planets adjacent to it, since that is visually confusing in that context only.
- Added ShowTooltipNarrow() and ShowTooltipWide() to the IPresentationLayer and IBattlefieldHandler, so that we can trigger tooltips super-directly from deeper-in code.
- In the lobby, hovering over planets now makes it show a tooltip at the mouse cursor that says the name of the planet (since that might be obscured by being very near the top of the screen, now), but also some other information.
- It says how many wormholes there are, and gives a comment if that will be extra hard to defend.
- It also shows the name of any human players who are going to have that as their starting planet, in their appropriate colors based on their faction color.
- There was some funky stuff in the hover logic for the galaxy map that made this super difficult.
- Fixed a funky bug relating to tooltips that were showing the same text as before, but had themselves cleared and then wouldn't keep showing the text anymore until it was given different text.
- The first time this ever manifested was in giving tooltips on the lobby galaxy map, but it's an old old bug.
- Fixed an issue in the lobby where it was not showing the names of planets automatically for planets owned by players other than yourself.
- The map types list in the lobby has always been kind of randomly organized, which was annoying. More recently, it has been in a different order every time you start the game.
- Now it is in the order Realistic, Simple, and then all the others alphabetically.
- Fixed a bug when loading directly into the game and not visiting the lobby where it did not set the dynamic zoom properly in the last few internal builds.
- Also fixed a boneheaded typo in the very most recent internal versions that was making the height of the dynamic zoom calculation slightly off.
- There is still something a bit off with the squares map type and how it displays in the lobby (it is offset upwards and also shown too small), but all the other map types work and so this seems to be some sort of data issue with that map type and not a problem with our central algorithm.
Version 2.117 Ion Cannons And Melee Units
(Released August 11th, 2020)
Balance Work
- Ion Cannon Shots can now:
- Damage both the personal shields and hull of a target in one shot (including killing it outright).
- Kill multiple ships in the same stack in one shot.
- Thanks to GreatYng for pointing out the oddity of Ion Cannons not being able to do these things.
- AOE shots can now hit any enemy bubble shield overlapping the explosion, rather than only being able to hit the shield if the generator (or something it's protecting) were physically within the explosion.
- Thanks to NRSirLimbo for reporting and RocketAssistedPuffin for the save.
- Crippled units (i.e. player flagships) can now pass through enemy bubble shields and traverse wormholes covered by them, to avoid being stranded in hostile territory.
- Thanks to tadrinth for reporting and RocketAssistedPuffin for the save.
- Melee units in attack-move mode will now go after units within a limited range (equivalent to a weapon with range=Normal1), so you have a middle-ground between "only attack your direct target or things actually touching you" and "pursue anything on the planet".
- Also, even when not in attack-move mode, player melee units without orders (and not in hold-fire mode) now automatically move to attack nearby targets. If all such targets die or move away, the melee unit goes back to where it was.
- Thanks to OzoneGrif, wm46, RocketAssistedPuffin, and Ubifan for the suggestions and saves leading to this change.
- Fixed a bug where deathgrip tackle drones had a gun that could shoot immobile targets, greatly confusing their logic. That gun now has the only_targets_mobile_units flag.
- Also fixed a bug where tackle-drone-launchers could give their spawned drones a direct attack order to go after an immobile unit.
- Thanks to tadrinth and RocketAssistedPuffin for the reports leading to these discoveries.
Bugfixes
- Scourge: fix a bug where player-allied scourge were building tons of Builders but no Fortresses (they were mistakenly thinking they were minor faction allied)
- A number of people on discord noticed the lack of Fortresses
- Potentially fix a bug where Regenerator Golems were regenerating things while crippled
- Thanks to crawlers for reporting.
- AI Reserves now will create anti-player zombies.
- Take another stab at 'adjacent planets watched'. Sigh.
- Fixed an issue where on computers without GOG Galaxy installed, they would get a harmless-but-annoying error message at game startup.
- Thanks to Badger for reporting.
- Minor tweak to target list planning; use a case insensitive comparison for zombification.
- The 'total units' count should now include stacks.
- The AI "Great-Turrets" are now simply called "Turrets" again, as at this point balance-wise the player turrets and AI turrets are similar.
- Thanks to GreatYng and RocketAssistedPuffin for bringing this to our attention.
- Exogalactic War Units now use a better spawn-in message than before
- Thanks to zeusalmighty for reporting
- Fix a problem with the Custodian description text
- Thanks to GreatYng for reporting
- The semicolon was previously not supported by our chat log format (our "condensed ascii"), but now is.
- Thanks to Badger and Sigma7 for reporting.
Multiplayer And Lobby Work
- Heartbeat messages from the client to the server and vice-versa are now omitted from all of the networking logs. They were making things far too cluttered for us to be able to see real information when we had network logging of various detail levels turned on.
- Some excessive logging on GOG and Steam with regard to their send result statuses has been removed, as again this was clogging up our network logs.
- The clients now have a secondary FromClientToServer_SignalDoneButHasNoCommands that they can send in place of the FromClientToServer_SendMyNextCommandBatch when they don't have any commands to send (which is most of the time, statistically).
- GameSpecificNetworking now has a DoPerFrameLogic() method, which lets us efficiently set some per-game settings like we do for the arcen debugging stuff.
- New setting in the Network section of the settings menu: Network Logging Includes Frame Auths.
- In the lobby and during gameplay, there are messages sent by the network every 100ms or so to keep themselves in sync, and if you have them included they will tend to crowd out the rest of the messages that are sent. So by default these are disabled.
- New setting in the Network section of the settings menu: Network Logging Includes Command Batches.
- In the lobby and during gameplay, there are messages sent by the network as frequently as every 100ms, but more often some sporadic multiple of that. This is how factions tell everyone what they want their ships to do, and how human players say the same. There's very little that we can say about this in a meaninful way in the networking log level, and again this will tend to crowd out the other messages that happen. So by default these are disabled, but bear in mind that most things that players actually cause to happen are being caused through these batch messages.
- Found and fixed a general issue where the player accounts were not properly being cleared (and fully resetting the player account IDs) during all cases where a game is loaded into the lobby. At a bare minimum, it was affecting the "open a custom game with my last settings."
- That would have eventually led to out of bounds exceptions, over time, and in general was cluttering up some areas important for multiplayer, but it had not had a negative impact on anyone so far.
- Fixed a bug that was causing all sorts of craziness on clients in multiplayer in the lobby, with them not getting their galaxies full cleared.
- This was leading to things not being properly in sync between the client and host, like planet names or locations, and things like extra planets or planets in old locations, or noninteractive planets at a whole other scale visually from the real planets. It was quite messy! All of that is now corrected, thankfully.
- In the lobby, when you change the number of human factions, it now regenerates the map immediately. For other factions it does not bother, never has, because there's nothing different to see at this point in the galaxy.
- The WorldSetup objects now have a readonly SetupTypeName on themselves, so that we can tell what they are.
- ChangedSinceLastMapGenCall on this same object is now a property, which lets us throw out debugging messages when it is being triggered for whatever reason.
- Something has been causing extra calls to be sent through the map generation pipeline in a redundant fashion that makes everything slower than it needs to be.
- Removed the ability to send a WorldSetup object via GameCommand, as that is actually highly antithetical to the way we edit that data as of the last year and a half or so.
- We specifically try never to adjust the entire thing, because several players at once could be editing different parts of it and we want those bits to all merge at once.
- Got rid of the SetupOnly_ChangeSetup GameCommand, which was set to use this sort of thing.
- Got rid of the LobbyWorking_HasBeenChangedAndShouldTransmitChanges() method on WorldSetup, which was being used by a loop in the footer to keep clients up to date.
- The problem with this is that this was far older code, back from perhaps 2017, and it was using an older and more sledgehammer-y approach to try to keep clients and the host in sync. When the lobby was redone in 2019, this became obsolete but was still hanging around and so caused some nontrivial chaos.
- LobbyWorking_HasBeenChanged() has also been removed, as it seemed duplicative and was no longer in use perhaps?
- Oh goodness, this was actually how we were ever updating the long-term stored version of the game (as opposed to the lobby working copy). This was not a good way to do it, but it was not quite as antiquated as we thought.
- Fixed a rare nullref exception that could happen in the ships sidebar if you were not properly on an actual planet.
- Fixed an issue from the last few months (probably) where if you had an error during map generation, it would still try to dump you into the world and then give you tons of other errors. It should have been stopping you and making you fix whatever was wrong.
- This is most common when there are not enough planets for all the factions you have chosen, or a few other rare cases. One such case is just discovered internally, and that's you having a planet starting index that is higher than the number of planets currently in the world.
- Helper_AssignHumanHomeworld() and the AI variant are now Helper_TryAssignHumanHomeworld() and an AI variant.
- It was already quite possible for these to fail if the player had selected something invalid, such as previously having clicked a planet with an index above 40 and then choosing a map size of 40 planets.
- The game now auto-assigns humans a planet that is valid if they don't have a valid option, and it does so in a multiplayer-compatible fashion.
- Previously this tried to do the assignment, but did not do so in a way that worked, and even if it had worked it would have only worked for one player.
- This also includes a new sub-gamecommand, StartingIndex_FromAutoAssignInMapgen, which efficiently lets the UI know what is happening without triggering an extra map generation cycle or accidentally overriding a distinct change made by the player.
- The lobby is now substantially more responsive even in single player, although it seems to be having some extra calls that we are still hunting down.
- Fixed an annoying issue that was causing an extra regeneration of the map to happen when you first went into the lobby in single player or as the host, leading to the lobby load time being half a second or so longer than it should have been.
- Fixed an issue where if one person in the lobby adjusted the following fields, it would not be reflected for the other players in the GUI (but would in the map itself):
- Planet naming style.
- Map type.
- All of the other map sidebar controls were showing things properly and also able to be controlled from any client or the host.
- Do bear in mind that if you manually enter a map seed, it won't appear for the other players until you hit "Regenerate Map," but given that does not actually affect the map until that button is pressed, this should not be overly surprising.
- All of the faction controls and their sub-controls have been workign properly from the start, and still seem to be.
- Same thing with the galaxy option controls (all of them), which is pretty exciting.
- The "Campaign Name" is something that is only for savegame management, and thus is only relevant on the host side. The clients now see "Will be set by host" as the text in that box, and cannot change it.
- The "Start Game" button is also something that we are limiting to be host-only, for a variety of reasons. The biggest is that they need to set a campaign name, but that's entirely host-side.
- Clients clicking this button now get a message that asks them to wait for the host to do it.
- Actually, for the sake of ease of use, the "Reset To Defaults" button and this one are just hidden on clients in multiplayer. Clicking Reset to Defaults on a client results in an error for a lot of good reasons based on how it is trying to accomplish that.
- All of the lobby controls now seem to work properly for both the host and client. There are still some things in chat that are messed up, and we're missing controls for making clients not always be spectators, but we can also get into the game.
- Fixed the harmless but annoying "StartingIndexChanges: factionIndex 1 passed when faction count was 0" error message that would happen on clients after a host gave orders to start.
- The campaign name and its textbox is now just plain invisible for clients in a multiplayer game, again to avoid confusion.
- The right-hand sidebar in the lobby in multiplayer is now split into two scrolling parts.
- The top part has information about the connected players and the factions that they are a part of, and never auto-scrolls around.
- The bottom one has the actual chat messages, and auto-scrolls to the bottom when new messages come in.
- The fonts of both are a bit smaller, from size 12 down to 10.
- From past changes, we can now verify that the proper name shows up for clients on the host, instead of it just saying "Player 2" for them.
- However, text messages from the client in the lobby show up with the color of the client but the name of the host?
- Hitting enter while in the chat textbox in the lobby now actually sends the chat properly, as already worked in the main game.
- In the multiplayer lobby, the top panel now shows the status of the various PlayerAccounts that are in a game. Specifically it shows any who are connected or disconnected, or which ones are you, etc.
- It also shows players that have an account in this game at the moment, but who are absent.
- Fixed a bug where player accounts were being created with the name of the host, not the connecting client, which was confusing all sorts of things.
- The preferred colors from the player profile on each local machine is now sent over and applied to their player account for later reference. This was also causing endless new player accounts to be created, since there was never a match to the connecting client.
- A variety of pieces of code had to be updated to support this.
- Apart from them selecting a color for their faction, this gives them a chosen color in text chat.
- Added a new OnEndEdit() event for text input boxes, which lets us trigger things when a player clicks out of a textbox.
- This now happens for the map seed in the galaxy map, same as with hitting enter, as both now trigger an immediate regeneration of the map (without you having to hit regenerate map manually).
- Faction colors for player factions now come from the network data rather than just the local data, which is important for multiplayer.
- Fixed the bugs with lobby chat messages not appearing properly on the client and host in various ways.
Version 2.116 GOG Networking Done
(Released August 6th, 2020)
- Fix a bug where the 'Watch Extra Hops Worth Of Planets' code was being applied incorrectly
- Thanks to Tynendir for reporting.
- Fixed a bug where Macrophage Spores don't move to new planets when loading a second save game.
- Thanks to GreatYng for reporting, and StarKelp for fixing.
Milestone: GOG Galaxy Networking Integration Complete!
- The Arcen GOG Wrapper has been majorly updated to get your GOG Galaxy Friends list and the status of them so that you can play multiplayer with them if you want to.
- When you are in the GOG networking mode, it now shows the list of your friends, just like it does for Steam.
- Basically all of the functionality is identical here, in terms of how it shows those who are online, offline, and in-game, and lets you filter between them, etc.
- The one difference is that in Steam we show the "in this same game" status as a light green (like Steam does), and in the GOG version we show that status in a purple color (to match their color theme).
- The host computer now is able to open up a lobby for friends when it says "open server."
- This works with all the various NAT punchthrough that GOG Galaxy supports, which we are not entirely clear on the details of. This may be as robust as Steam, or slightly less so, but we honestly have no idea. We'll be interested to hear from you! But either way, it's out of our hands at that point, so it's just information gathering.
- The host is also now properly destroying the lobby when it shuts down, so that others won't try to connect to it and not see it.
- When clicking the Join menu in GOG, the client now sees lists of their friends with four categories instead of just three.
- Friends who are in-game but not in a lobby right now are showed in a dull light purple. Friends who are in game and have an open lobby show up with a bright purple status.
- You can also cycle through all friends, open lobbies, friends in this game, and online friends.
- In the listing of connections, for GOG it now shows a button that says "closed" instead of "connect" next to each friend who does not have an open lobby.
- With Steam, someone could be in offline status but still let you connect to them. With GOG, we have to have a lobby ID to connect to, so there's no way to hide that and still even attempt a connection to someone.
- GOG clients are now able to search for lobbies and correlate those to their friends list, which under the hood is a several-step process.
- We are filtering out any potential rogue lobbies created by bad actors, and correlating them specifically to those owned by your friends.
- It's possible that a friend might jump from the status of being offline (prior to opening the lobby) to showing up as someone you can connect to (when they open the lobby), actually, so potentially this actually does allow for the same sort of quasi-stealth game connections that people can do using Steam.
- That said, since lobbies have to be advertised (to your friends) and we can't have a client just blindly try connecting by userID like in Steam, if you open a lobby and your other friends are actively in GOG looking to join a game of AI War 2, they would see that. Not a big thing, probably, but it's something we've noticed about the nature of these two differing systems.
- You may find yourself having to hit refresh a few times on the client side in GOG, as there is a few seconds of lag before the lobby that the host creates shows up. It seems to be under 4 seconds at the most in current tests.
- GOG clients can now actually initiate connections to a host lobby. And it works!
- The client is aware of getting into the lobby, although it takes a few seconds.
- The client also does gracefully tell them that they are leaving the lobby, and the GOG servers and the host are both finding out about that properly.
- The GOG Galaxy networking client is absolutely fully implemented, now!
- A huge amount of the actual send/read logic was able to be pretty much identical to Steam, which was not super far off from what we did with LiteNetLib.
- Pro tip: if any other developer is ever wondering about SendP2P messages on the GOG network, those can take any size, not just stuff under 1200 bytes. It handles all of the fragmentation and recombination extremely well, and just as fast as Steam or other services.
- The initial connection process to a lobby with GOG is a bit slower from North Carolina in the US than what we are seeing to Steam, ranging from 4-6 seconds on the first creation of a lobby on the run of a game to 2 seconds for ones after that. But once the connection is established and brokered, it's easily as responsive for us as Steam.
- For us, this is routing through the internet and some firewalls, so the NAT punchthrough or relay servers or whatever it is in this case seem to be doing their job. We certainly did not mess with any ports.
- Because of the nature of how data is read in from the buffers in GOG, we actually were able to get slightly more efficiency and speed with how we manage the heap compared to Steam or LiteNetLib. It's probably not usually a huge advantage, but it is something that we appreciate the efficiency of.
- Essentially all three of the networking options have their own pros and cons a bit, but are all extremely good. That's a real relief to see, and to see them all working.
- At this point it is now down to making the game networking actually work properly to have the game run, and that's a networking-framework-agnostic process.
- In a lot of respects it feels like after a large move of house, where all our stuff is now out of the old house and into the new house, but we still have a lot of unpacking and arranging to do. It still feels excellent to be done with the movers and have everything in one location now.
More Multiplayer Work
- Removed some old and unused code that is from the Valley Without Wind versions of multiplayer, checking for disconnections due to inactivity. We are handling that at a lower level, now.
- Got rid of some old code that was mainly in the older version of our engine pre-Raptor, which was checking for "pthread exceptions" that was never something that could happen in the newer engine that we've replaced it with.
- The game now has some self-checking code in there for giving us some actual feedback when it decides that it can't run the simulation or show visuals for more than 3 seconds at a time.
- This is a pretty rare case, but it was the "too many changes and the client machine goes to black screen and unresponsive" issue.
- This may have fixed the issue, although there also seemed to be another issue that was related to this.
- Took out some other unused and old data.
- The "UseSeed" command in the lobby no longer triggers the gamesettings to be saved. That was not useful, and slowed it down for no good reason.
- It turns out that this was blanking out the settings data in a strange way a lot of the time, and causing the black and white view of the game after you reloaded. It also was apparently directly the cause (somehow) of the infinite black screen on the client after this was triggered.
- Put in a lot of extra error handling for the steamworks networking in particular in case it has internal exceptions while trying to send something.
- The cumulative effect of a lot of these changes has basically fixed a ton of issues in the lobby, including:
- Clients not being able to use certain buttons or dropdowns.
- Certain dropdowns not showing the right values to clients.
- The client and the host getting a different view of things after certain buttons or dropdowns were used.
- For a while there I was thinking that I was maybe going to need to make some of the controls for the lobby host-only, but now that's definitely not the case!
Version 2.115 Imperial Summons
(Released August 4th, 2020)
- You can now have multiple copies of the Devourer and Zenith Trader in a game
- There's no technical reason for this limitation, and we're encouraging Zenith stuff because of the coming Onslaught
- Quickstarts are sorted alphabetically again, instead of when the quickstart was created
- Thanks to ArnaudB for the bug report
- Add some defensive code to the Dyson Sphere
- Thanks to GreatYng for reporting.
- Fixed a cross-threading nullref exception that could happen during unit unselection (probably due to it dying).
- Thanks to GreatYng for reporting.
Imperial Fleet Summoning Changes
- The AI now generates some weaker bonus exos against miscellaneous player targets (energy producers, MDCs, GCAs, etc), just to keep things exciting.
- Fix a bug where Exos were trickling into their targets instead of moving as groups.
- Start the Exos the moment you finish the hack, instead of some random time < 30 seconds from when the transceiver finishes.
- Blame MasterGeese for these changes
Multiplayer And General Lobby Work
- The "partial map generation" code for giving a preview in the lobby now does even less work, bringing our mapgen times down to 200ms or so on average.
- Because of this, we've also moved the mapgen code during partial-map-generation onto the main thread, to keep things as fast as possible. The full map generation still happens on a dedicated background thread.
- During the lobby, the way that we handle the execution frame loops is now entirely new, and basically skips over a lot of things that were artificially introducing lag.
- This makes the lobby perform far better in general, and also makes the map generation times absolutely flyyyy compared to what they were before, on single or multiple player maps.
- This is leading to a number of substantial bugs in the lobby, temporarily, but will make the lobby performance far superior in both singleplayer and multiplayer as we get those resolved.
- The silent "generate partial map" or "generate full map" complete messages now tells you how long it took.
- The way that mapgen works, it now has a couple of different contexts that it passes in, so that each one has its own random number generator that is not dependent on the others.
- This lets us ensure that there is consistency between runs of the same code on different machines, and on the detailed version (for play) and the non-detailed version (for viewing in the lobby).
- This is largely solving the issue that we just have started having in this latest round of internal builds with a difference in the final map and the original map.
- Renamed the Generate() method on map generators to GenerateMapStructureOnly() to be more clear, and also make our code more eaily searchable.
- Adding a planet to a galaxy no longer requires passing in a context object at all. It now generates its own internal random number generator for its initial variables based on the galaxy map seed, its index, and its original position.
- One of the side effects of this is that now when you change which planet you want to be your starting planet, it will keep the name the same instead of shuffling them around.
- This sort of name-stability has actually never been in this game before, and always was mildly annoying. But in multiplayer lobbies it was going to be even more annoying. "I'll take Adam." "Okay, sure." "Well, I clicked it and now it is called Brian, but that's the one I meant." "Wait, what?"
- When you are loading a savegame or a quick start as a template into the lobby, it now immediately regenerates the map rather than using the old map, because it's highly likely that the new structure will be different in some fashion.
- This then also solves the problem of clients being different from the host on first connect, probably; that was kind of a compound problem in general.
- Fixed an order of operations issue that could lead to the occasional "No human players found to seed homeworlds for!" error in the lobby in general, but more recently in multiplayer more frequently.
- Possibly fixed the issue with later player accounts in multiplayer being renamed incorrectly to "player 2" and such.
- There is still a fair bit of duplicate data happening between data structures, and some lobby/startup code that is blatantly single-player-specific that we need to get sorted out.
- Dramatically cut down the time it takes to generate planet random seeds, but still with keeping them consistent as you click around the galaxy, by pre-generating the random seeds as the first 300 calls to the "broad random" for the galaxy. Any seeds needed after that will be generated the slow-but-unique way. This means mainly things like nomad planets or other things that are late additions. When just adding a planet or two, it's not so slow as to be a problem.
- Until now, if you loaded an existing savegame it would automatically put you in control of the first player account, even if your profile name did not match.
- It now continues to do that when you are loading as a single player game, which is enormously helpful for testing and just in general, really. But in multiplayer, it now tells you a list of what the available profiles are,
- In general, if you are loading something as a template, it now clears all the old player account data and loads in your own current name as the new first player account (and further players are already added properly as they connect).
- Fixed up the way that planets are shown as colored in the lobby galaxy map, so that it will work well with multiplayer and also with the new faster single-player-generated stuff.
- Improved the logic for it properly setting you to be viewing the new planet you've selected after you make a selection in the lobby. Another thing that did work, but with the revised logic had to be made to work all over again.
- This concludes the fixes to all the known bugs that we are aware of that we've introduced into the lobby today.
- Fixed another nullref that was happening only on the multiplayer custom games after today's changes.
Version 2.113 Dyson Growth
(Released August 3rd, 2020)
- Fix a null reference exception if the game wants to spawn a Relic but you own basically every explored planet
- Thanks to Lord of Nothing for reporting
- Fix a bug with Dyson Sphere units not marking up
- Thanks to GreatYng for reporting
- Fix a typo in a Battlestation description
- Thanks to ovalcircle for reporting
Multiplayer Work
- Fixed one oversight that was causing the factions tab chat to not show its chat text properly, unlike map and options in the lobby.
- As text messages come in inside the lobby, it now scrolls to the bottom of the chat window, as you would expect.
- The maximum length of chat messages in the lobby is now 1000 characters.
- GetLocalPlayerFaction() is now GetLocalPlayerFactionOrNull(), to support spectator players.
- Additionally GetFirstPlayerFactionOrNull() has been added, and GetIsFriendlyToLocalFaction() and GetIsHostileToLocalFaction() have been updated to work based on that in order to extend support for spectators even further.
- Planet visibility is no longer determined from your local faction (since for spectators that might be null, and for all humans it is identical anyhow). It now just uses GetFirstPlayerFactionOrNull(), since that's slightly more effient and supports spectators.
- Huge areas of the AI have been updated to allow for spectators, generally giving them information that mirrors that of what the first player is seeing (objectives-wise and so on).
- In other areas, it simply updates things to not erorr out when you hit hotkeys, etc.
- Spectators also can't run "cmd" messages from chat; it will just show the text as if it were not a command.
- GetLocalPlayerFaction() on the planet object has been removed, as that did some risky caching for multiplayer in general, and also was not really compatible with spectators.
- Fixed a couple of errors where non-sim-but-background-fation-AI code was referring to the local player faction. It now refers to the first player faction.
- Probably this would not have made much difference, unless the game switched hosts partway through or something like that.
- The chat controls in the lobby now work, though there are some bugs in them still.
- The correct name for each player faction now shows up for even for players who are in spectator mode.
- Player factions in spectator mode now see in the lobby chat area that they are in spectator mode.
- Both the lobby chat and main game chat now support more characters in their text -- basically anything that our "condensed" ascii format is allowed to display.
Version 2.112 Steam Networking Complete
(Released July 31st, 2020)
- The description of the Ensnarer Battlestation now explicitly mentions that it can use AI Great-Turrets
- A number of people have reported this as a bug over the years, so hopefully that won't happen anymore
- All of the Fallen Spire ships, including those in the Spire Railgun Shop optional mod, have had their health and shields doubled, but their firepower halved.
- This should make battles with other mega-units last longer, which feels more appropriate, but keep their "damage over time" the same.
- When these were going toe to toe with the AI Exogalactic War Front units, they seemed to disappear too quickly, making them feel weak. This should keep their effectiveness the same as before, but make the battles take about twice as long with those large ships, so that it doesn't feel like instant evaporation at least.
- The one unit not adjusted is the Spire SuperDreadnought from the Spire Railgun Shop mod. That was already maxed out as a "kills everything and is basically invincible" sort of ship.
- Thanks to a variety of players for weighing in on the feel of these units, and Badger for suggesting this adjustment.
- Rather than having a slider for the number of planets in the galaxy map view, there is now a dropdown.
- This prevents the intense "regenerate map spam" and lag that was inherent in using a slider, along with making it easier to choose a certain number of planets.
- We have made it so that it only gives you multiples of 2 below 60, multiples of 5 below 100, and multiples of 10 above that. This makes it easier to quickly peruse the range.
- Each entry has some commentary on what it will mean to the feel of the map if you are hovering over it in the dropdown with the number of planets expanded.
- Actually, it wasn't even regenerating the map after you changed the number of planets, which was really confusing! You had to hit regenerate map. Now there is no confusion.
- All of this is easier to use as a player in general, on top of being something that is easier to deal with in multiplayer for sync purposes, too.
- Fixed a longstanding bug where dropdown selections that were open could persist when leaving the lobby or changing tabs within the lobby.
- Thanks to MaverickPenkenn for reporting.
Milestone: Steam Networking Integration Complete
- Fixed an issue where multiplayer clients disconnecting from a host would try and fail to save the last settings from the lobby. Now it does not save the lobby settings from a session you are just a client of.
- All of the networking frameworks have had their "send to anyone here and myself" code consolidated into the network authority, so when an interface is partially implemented it won't wind up stalling out waiting on the host.
- Less code duplication is also always good, but it wasn't clear that this was a complete commonality until we got partway into the Steam framework implementation.
- A new ArcenSteamClientConnection wrapper has been created to keep track of the Steam connection on servers.
- This now properly is registered while the steam connection is alive, and all of the "waiting for player to connect" and "player disconnection" events now happen properly.
- For some reason, we are not getting the "host has accepted you" callbacks on the client end, but that doesn't really matter. As we start actually having our challenge-response data sent via the higher-level networking code, that bit will become irrelevant as it establishes itself within part of one second anyway. It's just a curiosity, or potentially something that is only meant to trigger host-side. Frankly the documentation is sparse in points, both from the Facepunch C# wrapper and the Valve C++ baseline, so this might be working as intended.
- Substantial progress on the Steam network transmission of data. Still not quite seeing it register yet, but we're getting close.
- The full suite of network logging has been integrated into our steam networking wrapper, now.
- When a Steam host shuts down the connection, the steam client computers now definitely notice and react to that. The inverse was already working from the start.
- Figured out the missing information on how to get data from the facepunch steamworks wrapper (call Recieve() to trigger the other events), and are sticking with the derived classes methods rather than the interface method, since for relay connections it seems like the interface method is not fully implemented.
- With this in place, we're now getting messages on the client machine, and they are properly decoded! The host for some reason still doesn't get messages back, but this is progress.
- Fixed a bug in our connection status window code that was causing it to stop showing a timer on connection stages after the earliest ones.
- With LiteNetLib, that all flashes past so fast we could not tell that was even happening. With Steam currently stalling out with the host not getting messages, it became apparent.
- Previously it was possible for our socket mode to be off, and silently ignoring messages we were sending.
- This was initially done to make it so that any lingering messages that would try to be sent after a disconnect would not cause visible errors, but in this case we've wound up with the socket state being off on the steam networking, despite it being active, and this thus resulting in client messages being composed but not actually sent. That was not obvious because of the lack of error messages.
- Figured out a stupid mistake in our own code, indeed a single line of code, which was preventing the client from sending data properly back to the host.
- Steam networking is now fully functional in terms of sending data back and forth. There is some sort of issue with the world data not getting across properly, but we have to now verify whether that's limited to Steam or also happens on LiteNetLib.
- Added in a substantial amount of extra error tracking in our univeral and game-specific network message handlers.
- This helps us to find out where errors actually are.
- In the case of steam, right now we are getting some exceptions when the host tries to tell the client what their player profile number is.
- Fixed a simple typo that was having us send a junk message via both frameworks to the client when they first connected.
- In both cases, this led to the galaxy map not showing up properly on the very first world connect. But in the case of Steam networking, it also led to an exception because the byte array was too small.
- This extra smallness is actually more accurate, and basically it was only not erroring with LiteNetLib because the buffer array was larger than needed because they are pooled.
- This is an interesting difference between these two networking frameworks, but neither one is particularly "wrong. But it does make Steam slightly more sensitive to certain errors in a way that is useful, because it's an error in both cases that manifests in other places.
- Anyhow, this seems to argue for us to internally use Steam as our main testing framework, additionally because that means we are round-tripping out through the internet and Valve's servers and back rather than having the speed of a LAN.
- This also means that the Steam networking library is fully completely integrated, which is a very major milestone! Now it's all game logic, regardless of what is going on with the two networks.
- Also worth noting that it's under 3 seconds to connect a client to the lobby in our test case, using the Steam relay servers, etc. On the LAN it is under one second, so that's pretty killer.
More Multiplayer Work For All Frameworks
- "Planet GalaxyMapVisuals in CenterGalaxyViewOnPlanet null!" will no longer happen. It was a thing relating to trying to center on a planet slightly too early, and the population of the galaxy map still having failed.
- We are now bypassing that and using the raw internal transform offsets to calculate the correct camera position.
- In response to the initial challenge from the host, the client no longer just sends their profile name. They now also send their list of installed and enabled expansions and mods.
- The host then compares that list to its own installed and enabled expansions and mods. If there are differences, then it rejects the client connection and does a popup on the client and a chat message on the host side explaining why.
- It also notes in there that both parties can enable or disable expansions or mods in the Game tab of the Settings menu to get things to match.
- Please note that, yes, in some cases there will be mods that are enabled but which "wouldn't do any harm" because their functionality won't be triggered in the campaign in question. We don't have any way of knowing that, so we have to err on the side of caution.
- When it comes to expansions, there are none that "wouldn't do any harm," because all of them add some ships and features to the game in general that all players need to have. For instance, the first expansion adds a bunch of new turret options that are available to choose from in any game you play with that expansion on.
- At any rate, we've gone out of our way to make it easy for people to disable expansions and mods so that they can play with friends who don't have those same expansions or mods. The last thing we want is for the only solution to this sort of thing to be someone reaching for their wallet or having to faff about in the filesystem.
- Low-level chat messages that are sent to everyone from the host are also now sent to the host themselves. Previously, they could not see messages of this sort, turns out.
Version 2.111 Initial Steam Connection
(Released July 30th, 2020)
- Fix a null reference exception in my new spire relic code
- Thanks to Chuito12 for reporting
- Nanocaust: Make the AI wait a bit longer before unleashing Exogalactic units on it. Remove some deprecated code
- Also the exogalactic units won't hang around to kill the entire nanocaust, so there's a chance it can recover.
Milestone: Initial Steam Networking Connection Between Client and Host
- The Steam versions of the game now initialize relay access on startup, to make it so that the first connection using Valve's relay network will be extra fast.
- If you wind up not playing any multiplayer, this is absolutely harmless. If suddenly it is flagging your firewall on game start on the Steam versions of the game, though, that might be why.
- The basic connection through Steam's newer networking sockets connection is now in place, using their relay servers as recommended. This is the approach that absolutely bypasses NAT traversal and anything else of that sort, and in fact hides your IP address from anyone you are playing with. The claim is that their backbone is faster in most cases than the general internet one.
- If need be, we can make a "Steam over IP" version that allows for their networking sockets stuff to run more directly over UDP, and only fall back to their relay servers if there is a problem. This would be a lot like LiteNetLib, except with much better NAT punchthrough making use of ICE and STUN and all those things.
- For now we are sticking with Valve's recommended practices.
- Beyond just getting the initial connection up, we don't have anything there yet, but on the server we can see the Steam username of the client who requested to connect and who forged the connection.
Version 2.110 AI Exogalactic War Front
(Released July 29th, 2020)
- Spire Relics now have additional text in their descriptions explaining either A. whether the relic is on route to a particular planet , or B. that this relic must build on this planet
- Thanks to Lord of Nothing for suggesting
- All of the units that were previously named "Galactic War [name]" are now just named "[name]"
- However, in the tooltips for them, their faction should now say "AI Exogalactic War Front" in whatever the hunter fleet's color is, rather than saying the AI Hunter Fleet.
- This lets us keep the shorter name, while making their sub-group and source a lot more clear.
- This does need testing, so please let us know if it doesn't show up correctly somewhere. This is using a new xml feature called "override_faction_name", which lets us use a different faction name for some units in a faction, but without actually creating a new faction.
- Thanks to Ovalcircle for leading the discussion that led to this.
- Spending a ton of science will now increase a player faction's Overall Power Level very slightly.
- Remove some inaccurate description text for the Rorqual Hejira
- Thanks to GreatYng for reporting
UI for Steam Networking
- Added the new ArcenNetworkConnectionOption class, which we are using as a basis for things like lists of your Steam friends that you can connect to.
- On the network authority, there is a new PotentialServerOptions, which is used to list out such things. This can be used for anything that we need to list a variety of to connect to, not just friends in Steam and GOG. This is in contrast to the "type in an IP" method that we use with LiteNetLib.
- Started building out the Steam networking framework layer, currently based on the ISteamNetworking implementation that most games use.
- We MAY opt to also start supporting the newer ISteamNetworkingSockets framework that Valve has rolled out more recently, but that would be an alternative networking framework in AI War 2 that you could choose between.
- The fundamental premise of those two Steam networking setups is really different, and while the newer one would in some ways be easier for us to implement, it seems a lot less familiar to the average Steam player, involves IP addresses potentially, and is maybe less battle-tested, but who are we to say.
- Previously it was still possible to have some exceptions happen silently in the Engine_Universal main loop, and they would log to disk but not show up in your face. Fixed.
- It was also possible to get some silent errors when clicking buttons and other UI elements, turns out. This made the application just seem not to respond to the click, but now it properly shows the error if there was one.
- Also it was possible for certain errors in the UI call stack to prevent the display of the error window.
- When you try to connect to an IP address, or you change your active networking framework, the game settings now get saved immediately so that that is remembered even if you shut down the program right away.
- There is now a screen that will be used for Steam and GOG connections, from the client side, and in Steam it now:
- Shows a list of all your Steam friends, with ones that are in AI War 2 at the top, then ones that are online, and then the rest below that.
- Lets you sort to just ones that are in AI War 2 or online.
- Lets you refresh the list to check for updated statuses.
- There is a connect button for each friend, but that is not functional yet. Just haven't gotten to that part yet.
Version 2.108 Galactic War Units And The Exostrike
(Released July 28th, 2020)
- Completely rework the way Exogalactic strikeforce leaders work, to allow per-AI-Type customization. No functional change right now, but intended to support some new AI types for DLC2
- HandleHelperJournals() has been split out into a bunch of sub-methods, since they can error in rare cases and it would be nice to know where the error generally is.
- Fixed an issue where we were not letting negative risk analyzer data be saved properly. Turns out that has a good reason to be negative at times.
- Thanks to Badger for reporting.
- Added a new UI feature that is a throwback to some of the functionality we had in various past games: the "center screen message"
- This is basically a message that can show up near the top center of the screen, and stay there for a bit or for as long as needed.
- It won't block the mouse, and it is over everything except modal popups and tooltips.
- This isn't something we would want to use all THAT often, but for cases of things like "hey the server isn't responding, why is MP stalled," this is exactly the sort of UI functionality we need.
- Fixed a harmless bug where, for the last few months since we've been doing multithreaded loading of camera xml files, the "PrivateVisExtensions" assembly would sometimes have annoying but unimportant errors appear on startup.
- Essentially, it turns out that loading classes from a custom dll is not entirely threadsafe. Go figure. The fix for that is simple, and it doesn't slow things down, but now we know.
- Thanks to GreatYng for the first report of this we'd had outside of ourselves running into it.
- Fix a bug where macrophage achievements weren't triggering if you killed all the Telia
- Thanks to GreatYng for reporting and StarKelp for the fix.
- The in-game credits have been updated to include two more individuals who are key DLC2 testers.
- Added new GetWasWorldStartedOnGameVersionOlderThan() and GetWasWorldStartedOnGameVersionAtLeastThisVersionOrNewer() to world, which let's people find out in a really efficient way if a world was started before some certain point.
- We can't be accurate past a month or so ago, because we were not tracking the original savegame version back then. But it's useful for looking at saves older than the more recent ones and altering them if need be.
- This is now used specifically to fix this macrophage disabled stuff only on older savegames than 2.108.
- Fix a mispelling in the Mesopotamian planet names
- Thanks to Lord of Nothing for reporting
- Fix a typo, "reciever" to "receiver"
- Thanks to Apthorpe for reporting
UI Changes
- In the Load Menu, campaigns are now sorted by 'most recent save game in that campaign' rather than alphabetically
- Thanks to Puppet Master for the suggestion.
- The default sort for the load menu is now by date.
- Rename 'Exogalactic Strikeforce' to 'Exostrike' and 'Extragalactic War Units' to 'Galactic War Units' in UI. Having "ExoGalactic" and "ExtraGalactic" was a perennial source of confusion
- Note that internally the code uses the old names for the moment
- Thanks to a discord conversation involving relmz32, Oryutzen and NRSirLimbo
Dyson Sphere Buffs
- The Dyson Sphere's ships should now really level up after the hack
- Thanks to GreatYng and zeusalmighty for the bug reports
- Dyson Sphere hack descriptions now say "This hack will make the Dyson Sphere very unhappy with you for a while" to clarify the behaviour.
- Thanks to Apthorpe for suggesting
- The Dyson Sphere now gets additional income (ie it can build ships faster) that scales with AIP. As AIP goes up the Dyson and Antagonized Dyson get stronger
Multiplayer Work
- SendMessageToAllClients() has been split into two methods: SendMessageToAllClientsWhoAreFullyConnected() and SendMessageToAllClientsRegardlessOfConnectionStatus().
- We really don't need heartbeats and frame auths and so on going to clients who are still connecting in.
- Also added a GetCountOfClientsWhoAreFullyConnected() that lets us know if there are any clients who actually have gotten all the way in (and thus we should send world data)/
- And added GetCountOfClientsNeedingWorldData() that lets us know we should make everybody wait for a bit until those people connect in. Otherwise everyone won't be on the same page.
- Added a OnServer_IsAtPausedSpotWhereGameWorldCanBeSent() that lets us wait for a break in things happening (usually only 400ms or so at most) to then have a clean slate to send a world state to a connecting client without that state changing between them being sent the state and them getting it.
- Along with this, if GetCountOfClientsNeedingWorldData() is more than zero, then it now pauses authorizing more simulation frames until the world is fully taken in by the new clients who are joining.
- When a multiplayer game is stalled out for some reason, it now uses that central screen message to let you know what is happening, and if possible, why it is happening.
- The game itself will have stopped having any action at this point, though you can still scroll around and look at things and give orders. But nothing is proceeding on the enemy side, so you don't have to worry about it being in your way.
- When a client is first connecting into the lobby, it also uses this, to basically get the host and any other existing players to wait a moment before making more changes, etc.
- On the host, this is already set up to give some context about the exchange under the hood that is happening with the new client.
Multiplayer Transition To LiteNetLib
- Okay then... we are switching network libraries when it comes to our non-Steam/non-GOG transport layer. Instead of FORGE Remastered, we'll be using LiteNetLib.
- FORGE has grown a lot over the years, but the version we were using was from 2018...ish. We looked into updating our version of the code, but were not thrilled with how complicated it was going to be. Since we had working AI War 2 multiplayer on FORGE at least as recently as 2017 (in an alpha state), staying with the existing code made a certain amount of sense.
- However, we started running into really long delays with something as simple as sending 10 bytes to say what our profile name was. This was taking upwards of 14-18 seconds between two machines sitting three inches apart and both within five feet of a powerful wifi router. We verified that the polling was happening hundreds of times per second, and that massive amounts of data was being sent via sockets. But in the internals of the old version of FORGE we have, it was taking it quite a very long time to assemble that into a full message, despite all the churn of hundreds and hundreds of data reads that were apparently all just empty headers and then noise.
- Time for a new approach. It's worth noting that the current version of FORGE still lists all the most internal classes as "in development and lots of dire warnings," so that was another reason for switching up frameworks.
- We chose LiteNetLib at this point, and within 40 minutes of dropping that in, we had the first successful connection between the machines on using this framework for the game. It was just a simple "hello client" message in basic unicode, but it arrived extremely instantly, as expected.
- Next steps are going to be doing some cybernetic implants on LiteNetLib, rather like what we did on FORGE, to make sure that it integrates with AI War 2 properly and our network authority, and that it communicates as directly as possible with our own pre-formatted bitstreams. Most of that should be part of one day of work, at this point. We shall see. Then it's back to the actual larger "build out the multiplayer part of the game" work, but minus the lag that was tripping us up the last day or two.
- It's also worth noting that, with this switch, we had to unfortunately also lose the awesome NAT punchthrough work that Doug Fields did for us with the FORGE interface back in 2018, but LiteNetLib has some of that of its own. And hopefully most people use Steam or GOG if they are behind firewalls of any complexity (since relay servers then become required, and that's where the free relay servers are).
- NetPeer in LiteNet now inherits from ArcenNetworkClientConnection.
- For now, we are using our own methods to generate the ConnectionIndex, rather than using the existing peer.Id. There may be some numeric conflicts, otherwise, but we can also change this later.
- We also are initializing everything on the Arcen-integration side, keeping our own clientsOfServer list for quick access, and then calling the game-layer RespondToNewConnectionAcceptedByTransportLayer() that will kick things off.
- PrepareMessageForSending() has become WriteLogOfSend().
- Added a new SendToSpecificPeer() method onto LiteNet's NetManager. Not sure why that variant didn't seem to exist.
- Wiring back up our LitNetSocket wrapper class:
- SendMessageToHost_Inner() done.
- SendMessageToAllClientsRegardlessOfConnectionStatus_Inner() done.
- SendMessageToAllClientsWhoAreFullyConnected_Inner() done, using the new SendToSpecificPeer() method.
- SendMessageToSpecificClient_Inner() done, using our own ConnectionIndices for now.
- Booyah! Exclamatory phrases are not the norm in our patch notes, but this is an exciting moment. LitNetLib is sending messages, and doing so with speed and accuracy and a minimum of fuss. The username travels three inches in well under a second, as should be expected.
- At first, I was getting some very strange data sent across, and I figured that this was going to be an endianness problem, but actually all of the .NET/Mono data is the same endianness from the look of things. Which makes sense, given that otherwise savegames would not work from computer to computer.
- After spending the night with that rattling around in my brain, this morning I decided to definitely do some profiling of the data before I started messing with the #ifdefs.
- First thing I noticed was that I'd chosen to use the RawData byte array, and immediately next thought was "I better check there's not a network header in there." Turns out, yes, there's a UserDataOffset. The first four bytes are not my data, and so of course it would give gibberish as if the endianness was wrong. Just starting my reads from the proper offset makes everything work instantly.
- All of this is from a Mac to a Windows machine at the moment, but my I'll be testing three-way with my linux machine as well. Right now laptop is sitting closed under the Mac.
- LiteNet logging now gets funneled to our own main logging pipeline.
Continued Multiplayer Work
- A fair bit of work has been done to make intentional disconnections from the client or server tell the other side more quickly.
- This should help to avoid some disconnect-and-reconnect issues that are otherwise inevitable, and it just makes things feel more responsive.
- Additionally, when you use the in-game controls to exit the program as a while, it now takes one extra half second to lets Steamworks and GOG actually do their exit logic properly, rather than rushing out the door.
- This should hopefully help with any cases of the game still being thought to be running on Steam in particular after it closed.
- When you exit the game, while it is doing its brief exiting stuff it now throws up a center-screen "exiting.." message.
- Got rid of OnServer_WaitingOnConnectionIndices, as this was basically a duplicate of something we are doing better and more cleanly a new way, now.
- UpdateDebugText() and all of its related variables have been removed.
- This was the sort of thing that, in all of our prior games before Raptor and moving to 3D, you could hit F3 and get output information from. But it has never really been used in AI War 2 properly.
- Got rid of WorldTransmissionMessageType, as it was needlessly complicated.
- This was essentially us breaking the world transmission data into multiple parts and then sending those in parts. Historically there were two reasons for this:
- Back in AI War 1, we were using the Lidgren network library, and even though it was trying to work around the MTU (typicaly 1200 bytes) of various networks players might be on (or passing data through indirectly), it was often having bottlenecks and slowdowns with how it sent fragmented messages through the network card. Our theory at the time was that it was flooding the buffers of the NIC, rather than giving it data at a more reasonable pace. Network cards have grown enormously in the last 11 years, as have the OSes that control them, so that's not really a concern now. All of the newer network libraries that we would be using to send data should be able to handle 1MB of data without incident.
- Secondarily, for AI War 1 and for the A Valley Without Wind games, we were sending enough world data that you could see a noticeable wait time, and by handling this above the network transmission layer we could give you visual feedback on transmission progress (even though the whole act of that actually slowed it down). Eleven years later, we have networks that are vastly faster basically everywhere in the world, and the world savegames for AI War 2 are much more efficiently packed than AI War 1 was. So sending a file like this really is like a midsize image on any website you visit, now. Not really a progress bar sort of situation, especially if the progress bar itself causes slowdown.
- This was essentially us breaking the world transmission data into multiple parts and then sending those in parts. Historically there were two reasons for this:
- ConnectionStage has moved from being just a UI-only element to being ClientConnectionStage as part of the ArcenNetworkAuthority, so that clients can better keep track of their connection status. Usually this is less than a second or so, anyhow, but we still need to keep track of it in case something goes wrong in particular.
- The host now properly sends the world data to the client, for the first time in three years or so.
- The client is having some trouble understanding it thus far, so now is a good time to build in error handling (it was just silently failing, until now).
- Added a new SendLowLevelChatMessage() method on the network authority, which is used mainly for sending back and forth arbitrary messages from clients and the host to explain about the status of things. These can be echoed to all other clients or not, as the case warrants.
- If the client fails to load a world sent by the host, then the host and any other clients all get sent a low-level chat message about that, the client gets kicked out (since they never made it fully in), and the client gets a nice error message on their screen and in the log.
- This way we can solve whatever the problem is, and nobody is left sitting wondering why things are slow (when in fact they errored).
- When you are loading a quick start, or loading a savegame as a template into the lobby, it now clears the chat log. This was definitely not information that needed to persist from a prior game to the new lobby!
- These sorts of chat log messages, which are kept over the long term for the game (up to a limit), are no longer shown in the lobby at all.
- Instead, we now are using LocalMomentaryDisplayLog, which is something that doesn't get sent with savegames, and which normally is just "stuff showing on your sidebar during the game for a little while."
- This is perfect for the lobby, and in the lobby we are just showing the last 100 of these, and not clearing them until you reach the game itself.
- These things are actually shown by timestamp, not by gamesecond (which isn't ticking yet), so that's just extra perfect for a lot of reasons.
- This also leads to privacy for people who were talking before someone new joined -- you only see messages that were sent after you were connecting -- although that's not hugely important in most cases.
- Got rid of ArcenUI.Instance.CurrentNowUTC, since that was putting all of our lobby chat messages in the British time zone. We didn't use this anywhere else, and it was puzzling that we used it at all.
- NatPunchEnabled is now true on the server and client for LiteNetLib. We'll see how well that works.
- Added a new debug setting to the network section of the settings menu: Write Network World Serialization Logs
- When sending a game world across the network to a client, write NetworkWorldSerialization.txt, and when getting one from a host write NetworkWorldDeserialization.txt -- both in the PlayerData folder (but on two different computers). The only real reason to turn this on is if a client is unable to join a host and gets an exception; this lets us do a diff of the two files and figure out what is different about what the host is trying to send and the client is trying to read.
- Note these logs are often huge, sometimes hudreads of MB each. Compressing them into a zip or tarball and then uploading them somewhere we can download them to find out what is happening is a good idea. Hopefully as a player you will never need this, but this is basically a way for us to test the network world sync process, which otherwise can be incredibly opaque and take a lot of time to hunt down.
- Used our new network world logging capabilities to fix an error in network world transfer where it needed to send the game version in a different format.
- The client now looks at the game version very early on, and if it does not match it sends a message back to the host telling the host what the problem was.
- Basically: If the client can't join because of a version mismatch, that gets shown and things happen properly.
Milestone: World Sync Between Host And Client
- Milestone! Initial transmission of the world data from the client to the host now works properly.
- When a local player account is missing the following methods no longer throw errors:
- SwitchViewToPlanet
- OnClient_SendClientBatchToServer (actually still errors, because it's useful to have it do so).
- PlayerAccount is now more strongly linked to the new ArcenNetworkClientConnection, and its connected status is now a method called OnServer_GetIsConnected().
- There is some duplication of concepts here, but when you factor in the way that things like viewing of planets are synced in multiplayer, this is a worthwhile separation of concepts.
- If two players with the same profile name try to connect to a game at the same time, it will now prevent the second one from joining and tell everyone why.
- Bear in mind that these are AI War 2 profile names, not Steam or GOG or what have you. Everyone needs to have a unique AI War 2 profile name in the current game, but they can change up their names however they want and global uniqueness doesn't matter beyond the current game you are in.
- In situations where a player 3 joins after player 2, and it's the first time player 3 has been in this particular world, player 2 now gets told by the host about player 3.
- And of course all the more complicated permutations of this. It's the new FromServerToClient_SendNewPlayerProfile.
- This is needed specifically so that all clients can know which planets are being viewed by other players, so that which planets are "tier 1" processing is honored and identical everywhere. Among other later needs.
- Clients connecting to a host are now properly told what playeraccount they have been put in charge of.
- This makes PlayerAccount.Local not null on their local machine, and lets them give orders and whatnot from their spot there.
- Errors that happen during the main sim step will now be more visible in multiplayer contexts.
Milestone: Initial Sharing Of Lobby Between Host And Client
- Milestone: Clients are now able to load into the lobby, and they and the host both see most (but not all) changes that are made.
- Clients are not yet assigned to any faction (making them just spectator-mode for now), and there are some specific bugs with certain data that isn't synced correctly just yet.
- Map generation can no longer happen in the lobby except on the host.
- We have no real way to be sure that map generation is deterministic between machines, so we need to do a world sync each time anyway.
- When the map is regenerated on the host during a multiplayer lobby, it recreates all of the playeraccounts needed for each of the player connections that exist.
- And when the map is regenerated on the host during a multiplayer lobby, it now re-syncs the entire world data to all of the clients so everyone is up to date.
- This also solves the "authorized through frame number" issue, which was really just a smaller symptom of this larger issue.
- Both the client and host are now verified able to add, remove, and edit factions and have that properly affect the world.
- Window_ServerMultiplayerConnectionStatus has been removed, as we no longer use that. We've been using the new center-screen messages instead, or the chat sidebar, as needed.
- In multiplayer games, the save button is now disabled and says: Cannot Save Game As Client
- If you click it, it gives you this message: Unfortunately, only the host can save games in multiplayer. To save on bandwidth as well as on processing power between your machines, there is a LOT that is calculated only on the host machine. If you were to save a copy of the game on your client's end, loading it would lead to a lot of wrong and missing data.
- Additionally, autosave is now something that does not happen on multiplayer clients. Just the host.
- The header of the load quickstart and load saved game menus now make it clear if you are loading for multiplayer or single-player.
- Also on these screens is a new "[Multiplayer Questions?]" bit of text up at the top that appears only on the multiplayer version, and which has some helpful mouseover text.
- Rather than having an annoying explanatory popup to click through every time you open the various ways of hosting or joining a multiplayer game, it now puts that extra information under the "[Multiplayer Questions?]" section up at the top of those screens.
- At the top of the lobby screen, it now says if you are joining as a client or a host to a multiplayer lobby, as well as having that same "[Multiplayer Questions?]" bit.
- This includes the following new text in its mouseover text: Except for the host, all players are spectators by default. There is only one human player faction by default. Any number of players can share control of a single faction, or each player can have their own faction that they control on their own. You can mix and match as you like.
- The connect by IP window has been completely reworked visually so that it matches the rest of the game and doesn't look like the old temporary style that we were using in 2017 (because that's what it was).
- This also lets us put extra information on that screen to help anyone who might be confused.
- The client connections status window is now patterned as a continuation of the connect by IP window, and it's nice and graceful and in the new style.
Version 2.106 Immortals and Unresponsiveness
(Released July 23rd, 2020)
Bugfixes
- Put in field names for the risk analyzers saving, so if they have trouble serializing we can see which field it was.
- Also then made it so that the total increase and net increase both are automatically clamped to 0 instead of a negative number so that they won't throw an exception when trying to save.
- Thanks to GreatYng for reporting.
- When stacks are split, they now have their "time on planet" and "time alive" set to be whatever the original stack was. Same with the amount of cloaking points they have lost, and the number of cloaking points they have left.
- This prevents a variety of abilities from triggering, including the "invincible if only on this planet for x seconds."
- We also made it so that dying to remains does not reset the "time have been alive or on this planet" counter, for similar reasons.
- This keeps the vanguard hydra heads from being insanely impossible to kill, among other issues that are probably pretty much all in the player's favor to have resolved.
- Thanks to crawlers for reporting.
- Added some extra debugging information for the status of gamecommands that are queued, to see if there are clogs happening. At this point, we can't replicate any evidence of that, though we have some reports from multiple players of it. So maybe the problem either takes a bit to manifest, or is in a different area of the code than we expected.
- AIP should no longer increase when things die to remains if you have the "ships of X type die to remains instead of dying entirely" galaxy map option on.
- This is untested, but should work.
- Thanks to crawlers for suggesting.
- Found and fixed the core typo from a few builds back where remains that were being rebuilt were being set to have the cost of the rebuilder, not themselves. This was previously massively overcharging players for building most things, but then once we put on a band-aid to fix that, it started giving it to them for basically free.
- Thanks to Lord Of Nothing for the report and save.
- Fixed a bug from the last few versions that nobody seemed to notice, where the galaxy map was not centering on planets properly when you first went into the game after loading a savegame. This had to do with when we were calculating the position of the planet, and that not always being calculated before we tried to center on it.
- Fixed a bug where it was possible that a client would send more commands to the host than it would tell the host about, and thus the host would not know to read the extra ones (or vice-versa). In single-player you are both the host and client, so it still applies.
- This was happening because of multiple threads adding to the queues of commands at the same time that the queue was being drawn down.
- This was actually something that probably could have happened since more or less forever, but it was substantially more likely in the last few versions because of some efficiency improvements we made.
- Additionally, we have now switched to using a ConcurrentQueue for each of those collections, rather than a regular Queue. This should also help with potential contention.
- There was also the possibility that we might not be able to get enough commands out of the list for some reason to then send more, and we are also now guarding against that.
- Previously, this problem was manifesting as orders not being carried out when you gave them, sometimes or all the time. And things like "save my game" and "pause or unpause" not working anymore.
- We were able to duplicate this in one savegame after some time, but no longer can. Given the intermittent nature of this sort of thing, we can't say for sure that it is solved -- but the logic of what was going on makes sense, and the fix we put in should hold that at bay. It's one of those "can't prove a negative" things, at the moment, so fingers crossed it just never shows up again.
- The characteristics that we observed while this happens, if it happens to you and you want to see what you can tell us:
- In the escape menu, under the memory pooling performance, the number of raw commands were steadily climbing. One or two every few seconds. This should never happen in that way. Increases happen, but not a steady drain flow like that.
- In the escape menu, further down under the Commands Queued By Type, you may see some null warnings up at the top of that list, now. That wasn't there when we observed it, but it would be if it ever happened now.
- Thanks to zeusalmighty, Puppet Master, Gdrk, and GreatYng for reporting and giving advice on how to reproduce it.
Multiplayer Work
- In our copy of FORGE networking, we've removed some useless extra code that was for the UniversalWindowsPlatform framework, which we won't be ever using.
- In our copy of FORGE networking, we also got rid of a very useless set of "pending" messages on the UDPClient and UDPServer, which were ostensibly to help with reliable messaging, but in reality was just doing some useless event handling and invocation, and some useless cross-threading locks. It just put the things in the basket and took them back out, never checking the basket or doing anything with it. Thankfully, there is a second basket for reliable UDP inside the UDPPacketComposer, so this was just extra redundancy.
- Added a new ArcenNetworkClientConnection abstract class, which we now store on ArcenNetworkAuthority in a ClientConnections list.
- These are connections, not yet correlated to specific players. But it lets the network pipe connect up a specific connection with a specific player (or reject that connection if it's not okay).
- Each individual networking framework (ArcenSocket descendent class) is actually responsible for keeping track of these connections and populating them.
- But the actual network authority does the job of authenticating them into a given game and handling the challenge/response work, figuring out a match to a player slot in the game, etc.
- With this in place, we can now get rid of GetNumberOfConnections(), because that's now moved out of the socket and into the network authority.
- This is a substantial refactor, in that it will really make Steamworks and GOG a lot easier for us to work with as networking frameworks, faster.
- NetworkingPlayer in FORGE now inherits from ArcenNetworkClientConnection, and is the first version of a networking framework using this new pattern.
- On NetworkingPlayer, rather than having a public { get; private set; } for some of the immutable connection things, we now use them as public readonly. This is both more efficient in performance (slightly), but also prevents sync issues between this class and its new underlying abstract class.
- This class gives the information it needs to the base class, and doesn't bother registering the host NetworkingPlayer as an underlying client connection at all, keeping things simple.
- A bunch of stuff with the FORGE networking logging has been replaced with wrappers around our own logs, so that if there are internal exceptions those don't just go nowhere invisibly anymore.
- Trimmed out a bunch more old FORGE code that has been commented out for years from the look of things.
- RespondToNewConnectionAcceptedByTransportLayer() is definitively game code, not part of the actual networking transport layer, and it has been moved into the central codebase and away from any specific networking framework.
- "Hello friend, you've connected: what's your profile name you want to play under?" Etc.
- A fair bit of the "initial chatter" of clients connecting to a host and the host responding are now logged to the debug log no matter what.
- There really is not that much that is said, and this will certainly help someone at some point who is having some sort of connection issue.
- When clients are connected to the host, now the host not only shows the number of clients, but also sees their profile names that they have chosen to connect with.
- A bunch of event-driven stuff on the FORGE networking has been made a bit more inline, improving performance a bit and also reducing certain areas of complexity.
- The initial challenge-response work, and "what's your name" work, is all functional again. This is stuff that will be identical regardless of the network framework.
- The host can now properly see the profile name of the client, and is poised to send the client back all the world information.
Version 2.105 Selection Hotfix
(Released July 22nd, 2020)
- The game still loads various xml files asynchronously, and loads icons and music and sound in that fashion, but it no longer tries to load the ships, shots, or wormholes in that way.
- This was just too unreliable, because of some issues in the unity engine. It didn't affect all players, and not all the time -- but enough that it majorly affected the stability of the game for some folks, and that's too much.
- This also removes the potential for the really long (15-30 second) lag time when you are first opening a new game or the lobby if things didn't load during the loading period.
- Thanks to Ovalcircle for the most recent set of reports.
- Previously, the game was using a standard List<> object for keeping track of selected ships, and that sometimes ran into inefficiencies and cross-threading issues.
- In the prior build, we tried to fix some of those cross-threading issues, but wound up making things not actually deselect properly.
- To fix all of the above, we've now switched to the much more flexible and robust ArcenLessLinkedList<> object, and adjust the code to handle this. This is both more efficient (not that efficiency is a major problem here), and does not fall victim to the various cross-threading woes that the old style could.
- And, naturally, as part of that, this also resolves the frankly infuriating selection issues in the most recent build of the game. Sorry about that one!
- Thanks to ctl0ve, CRCGamer, Chuito12, and Burner for reporting.
- Previously, the tech menu only showed techs that would actually benefit a ship you have at present, or which you could capture.
- This was very confusing to a lot of players, as they would not see the entire tech tree and thus think that something was missing or broken.
- In some other cases, possibly due to changes in the recent past, you CAN build something (like a command station), but since you have not done so yet, it would not show up.
- All of the techs now always show up, but the ones that are for ships that would not benefit you right now still show up as red and not researchable.
- Additionally, the tech color shows up as white when it benefits ships you have, gray when it benefits ships that you don't have right now, and lighter gray when it benefits ships that you could capture.
- Please note that since citadel upgrades don't benefit battlestations anymore, the citadel tech not showing from the start was working properly.
- Thanks to Strategic Sage and CRCGamer for reporting the confusion.
Version 2.104 Negative Build Percentage Hotfix
(Released July 21st, 2020)
- Somehow or other, it became possible for some self-building ships to go very negative in their build percentage (instead of counting up to 100%, they would be way in the negative percentages of building process).
- This seems to be a new bug in the last day or so, based likely around some changes that we made to improve the cross-thread reliability of the game. The problem is, upon manual code review of the areas that would be relevant, we just can't see anything that looks like a bug.
- Ultimately what is happening is that the SelfBuildMetalRemaining is getting absolutely giant in value, far larger than the original metal cost of the ship that is constructing. This was probably an integer overflow from it going really negative first, and then wrapping back around, but it's hard to be sure.
- We've put in some extra defensive code to make sure that if it goes negative at all, it marks itself as complete. We've also put in protections so that if you "owe more than it is worth" in general, that it will assume that there was an overflow and just go ahead and finish it now. These two changes should help to keep the problem from happening again, and fix the cases where it was already in progress.
- While we were already at it, we put in a small general improvement that prevents you from being overcharged for the last tiny percentage of constructing a ship. If you had a bunch of engineers building, and each frame cycle they normally would do 1.1% of the construction of a ship, and charge you accordingly, then you might wind up in a case where you had only 0.2% remaining work to do, and yet got charged the full 1.1% rate. It is now careful to only charge you for what you would owe, so the 0.2% rate in this example.
- Hopefully there are no other errors in any of the metal flows, with things like drones building, anything engineers would claim or repair, etc. The code looks clean, but then again the code for the self construction also looks clean. In the next couple of days, please let us know if you see anything else that seems amiss with how metal is being charged against you. So far we can't duplicate anything like that anymore, now.
- Thanks to CRCGamer, deso, and Puppet Master for reporting.
- Some code from yesterday dealing with cross-threading protections let us unfortunately sometimes wind up with runaway DoForSelected loops. This is now fixed, and it has several kinds of self-repair in place to prevent this from happening now.
- Thanks to Gunner for reporting.
Multiplayer Connection Work
- Reworked the NetworkTrafficLog.txt multiplayer output to actually be a lot more informative.
- GetNumberOfConnectsCurrentlyActive has been replaced with GetNumberOfConnections, which lets the network framework tell us a lot more about the general status of things happening.
- Instead of just a generic number of players that exist, we can see how many are disconnected, how many if any are the host, how many are clients, etc, etc.
- In the lobby, the host now sees how many connected clients there are, and if there are any disconnected ones, how many disconnected ones there are.
- Previously it just showed one number that included the host and also disconnected clients all wrapped up into one.
- It still isn't detecting disconnects properly in FORGE, but we'll get to that.
- The host now only bothers sending heartbeat messages if it has at least one non-host client machine connected.
- Removed some old "desync detected" code that was not fitting with the new plans for multiplayer.
- Figured out some of why the client was not detecting itself as properly connected, and so was not getting messages from the host at all in the last few builds after the connection.
- The way that gamecommands are queued and then given out to player simulations for both single-player and multiplayer is now more efficient.
- We're using queues now instead of lists, and this gives us a lower chance of accidentally losing a command, as well (not that we know of that ever happening before).
- This has several performance benefits even for single-player when there are a lot of commands going around.
- Added a new FromServerToClient_AuthorizeThroughFrameNoCommands in addition to the FromServerToClient_SendNextBatchOfCommandsToExecute, to slightly save on space (1 byte per message) and make the logs clearer.
- The network log no longer has a time delay built in where it logs only 100 items at a time. It just immediately dumps items to disk.
- Realistically there is only substantial traffic every 100ms or so anyhow, and the delay in logging was incredibly confusing as a programmer working with it.
- The network polling interval has been updated from 20 times per second to 100 times per second. In practice it will actually be variable, but the polling is extremely lightweight (the part that is on the main thread), and having absolutely minimal delays in getting and sending messages is what will keep things moving smoothly.
- To make network logging even more efficient and clear, the old ArcenNetworkLogEntry is now ArcenNetworkSendLogEntry, and is now a struct instead of a class. This runs lightning fast and doesn't affect RAM usage.
- We also now are then logging data that is gotten in (which we call TAKE) along with data that is sent (which we call SEND).
- This way we can see the conversation between several machines all interleaved on a single machine's log, and thus figure out why they are saying what they do, and if messages are getting there, etc.
- Surprisingly, the way we were logging things previously really didn't lend itself to that, so it was easy to go down rabbit holes of wrong information (thinking data did not get to a machine when in fact it did).
- Furthering clarity on the networking side, we're now ignoring loopback messages-to-self on the host in our logs, which previously we were not doing.
- This way we don't get drowned in a sea of stuff that "I'm telling myself in order to be the same as everyone else," and we can just see what is actually passing between machines.
- The loopback stuff has been demonstrably working fine since more or less forever, unless we broke it today, since single-player relies on that.
- Fun fact, after all these logging changes, we can now actually see how well parts of the networking are already doing.
- As one client connects, the host is able keep talking to itself and/or others without breaking stride, letting the potential connection wait for the challenge and acceptance (not yet reimplemented) before it loops in the new client to the rest.
- This is a great example of how we can keep people from accidentally messing with the sessions of friends by trying to join during a game, etc. It's the sort of thing that only matters among friends, but it keeps it clean.
- On top of that, we can see now that the reason for the host not noticing when a client disconnects is because it's ignoring the client that has not fully gone through the challenge-response process yet, and so the mystery of how it was "sending messages that failed but didn't flag the client as disconnected" is easily solved (answer: it wasn't sending messages to that particular client yet, because it is smart).
- In general, by improving our logging quite a lot we can see what is actually happening and make sure all of this works properly. The vast majority of this is network-agnostic, which is doubly great. These particular logs will look substantially the same between FORGE and Steam and GOG.
- As one client connects, the host is able keep talking to itself and/or others without breaking stride, letting the potential connection wait for the challenge and acceptance (not yet reimplemented) before it loops in the new client to the rest.
Version 2.103 Hotfix
(Released July 21st, 2020)
- Fixed a bug from the prior version where the dark spire serialization fix was making any savegames with dark spire in them -- new or old -- not able to load.
- Thanks to valinor000 and stanazolol69 for reporting.
Version 2.102 Digression For Quality
(Released July 20th, 2020)
- Using the "Increase Max Dyson Strength" hack will now also increase the Dyson's general mark level
- Some minor buffs to the Dyson's income, mostly at higher levels
- Thanks to a discussion started by zeusalmighty
- When picking music (through the debug menu), the hovertext will now give you information on most of the tracks saying the original source
- Improved the speed of some dictionary lookups by precalculating the ArcenAssetBundlePath CombinedPath.
- This also required us to change their member variables into properties, and in return that meant that the general string fill methods needed to be adjusted to new FillBundle and FillPath methods for xml reading.
- This doesn't affect as much code as it sounds like.
- We also adjusted the various debug logging points to use the combinedpath, which is cleaner and easier to read, but not much faster since that almost never happens.
- Fixed a bug that could happen with entity order serialization in rare circumstances if threads were fighting over putting items back in or taking them back out.
- Since multiple threads do in fact often use orders, at once, this is one of the few collections prone to that.
- Fixed a variety of exceptions that could happen based on cross-threading bad luck during the exit of the game either to the OS or to the main menu, all in the metal expenditures code.
Ship Behavior Improvements
- Fix two problems related to shields recovering from being bumped by Astro Trains
- Human Home Forcefield Generators can now recover from being bumped.
- Thanks to Lord Of Nothing for the bug report
- If a forcefield generator is bumped twice in short order, it will now do a better job of returning to its original location. This isn't perfect, but it's a pretty intense corner case
- Thanks to Puppet Master for the bug report
- Human Home Forcefield Generators can now recover from being bumped.
- If there are only non-combatant enemies on a planet, ignore any requirement in the targeting code that particular targets need to be combatants. This prevents ships in FRD from discarding reasonable targets incorrectly.
- Thanks to ParadoxSong for the bug report
- Actually support Targeting tracing now; you need to set Targeting tracing and the Debug setting that lets you set the PrimaryKey for the unit you want to follow, and you'll get some actual logging.
- Not for the faint of heart; intended only for developers who want to get their hands very dirty.
Bugfixes
- Fix a bug where the 'delete campaign' button wasn't giving the campaign name
- Thanks to OvalCircle for reporting
- Fixed a rare and harmless (but annoying) cross threading exception that could pop up with argument out of range exceptions in RenderShip.
- Thanks to CRCGamer for reporting.
- Fixed a rare nullref exception that could happen in DoRemovalChecks() on shots, mainly a cross-threading thing.
- Thanks to Lord Of Nothing for reporting.
- Fixed two possible spots in DoForSelected() where cross-threading issues could sneak in and cause an exception in rare cases.
- Thanks to Lord Of Nothing for reporting.
- Fixed an issue when loading savegames that have a missing planet naming scheme. It will now default to the default naming scheme if it can't find the one that the world was started with.
- Thanks to Oryutzen for a save that demonstrated this.
- Fix a bug where the imperial spire wasn't Watching previously explored planets for you.
- Thanks to Lord of Nothing for reporting
- Fixed an error in TextMeshPro where it would still give us "Unable to use Ellipsis character since it wasn't found in the current Font Asset" invisible errors that would fill up the debug log even if warnings were disabled.
- This was, in very long play, a memory leak as well as a performance drain, and it was generally invisible.
- The ellipsis character was typically something it was trying to find specifically for purposes of showing cut-off text, and some fonts just don't have that in them. So no wonder we couldn't actually find the ellipsis character used in our own text files.
- Thanks to Puppet Master for providing the log file demonstrating all this.
- Fixed an issue where the stationsRemainingBeforeDepot on astro trains could go arbitrarily negative, thus causing an error on save. It now stops at 0, and thus seems not to cause the issue anymore. But on the change that an astro train does have a data exception during save anymore, it will now log what field is having the problem and we can fix it.
- Thanks to Lord Of Nothing for the report and save.
- The game has been updated so that the debug logging that is DoNotShow now ONLY goes to the ArcenDebugLog.txt, and not to the unity Player.log. The unity Player.log is kept in memory in a very unfortunate fashion, and in long gameplay this will be extra RAM used that should not be. Probably also extra slowness.
- We added a new DoNotShowButSendToUnityLogEvenOutsideEditor Verbosity option that lets us have the old behavior of going to both of those logs, but we are not using that anywhere at the present time.
- All of this is going to make it even more important that we have both kinds of logs from players if they have an outright game crash, now. But generally speaking, if it's an exception popup but not an outright crash, the ArcenDebugLog.txt has always been enough and will continue to be. It's only when the game crashes all the way to the desktop that we need the Player.log, typically, and now we'll just still need the ArcenDebugLog.txt in addition to that. However, any ShowAsInfo or ShowAsError logs to the main ArcenDebugLog will still appear in the Player.log, so potentially even that won't be true.
- For a developer using the unity editor, it still logs everything to the actual unity log because that's for short testing cases and super useful to see output in realtime.
- At any rate, we are trying to strike a balance between getting the logs we need, easily on the part of players, but without having any accidental extra usage of memory on very long play sessions.
- All of the dark spire per-unit data is now saved in a format where we can tell which field is having trouble if one does.
- The dark spire data "lastTimeAttemptedLocus" was trying to save as an int16 and would overflow any time a game saved that was more than about 32000 seconds in. Fixed.
- Thanks to RockyBst for reporting.
Memory Leak Fix From 2.099
- New setting on the debug menu: Show Pool Counts In Escape Menu
- Used for searching for memory leaks, particularly between loads of a savegame. If pool counts keep rising after each load, then something isn't getting put back in the pool properly and is instead persisting lost in memory.
- ArcenGameObjectResourcePools must all now have a unique name, and they register themselves in a central place that identifies how many of them there are.
- These pools also now keep track of how many objects they have ever produced from themselves, so that if we are leaking objects from them we can tell. And we can tell if we are leaking pools themselves.
- After seeing all of these in the new debug menu option above, we can clearly see that none of these are leaking and they are all behaving just wonderfully. Hmm. But we have a leak somewhere, so let's expand this...
- Created a new CountedPoolBase abstract class that sits under the ArcenGameObjectResourcePool, and takes its counting capabilities and puts them there so that we can also use them for some other pool types.
- This is also now used on a new "Shot Instance Renderer Pool Of Pools" so that we can tell if we are leaking there. And now ships and squads, too.
- Also this is now used on LoosePool, which is the underlying basis for ship, shot, and squad visualizers (different from instanced renderers) now.
- Despite all this, no memory leak was found in any of these pools. They are all working wonderfully efficiently.
- ExternalizedPool now inherits from CountedPoolBase.
- Same for TimeBasedPoolBase (and thus TimeBasedPool itself).
- And same for BasicPool.
- And holy cow, there's some sort of memory leak with the time-based pools, looks like, based on this. That makes sense, as we recently reworked some of their functionality to fix a bug with them. Apparently we introduced a new bug at the same time.
- Added a new setting to the debug menu: Show Details Of Time-Based Pools In Escape Menu
- Used for searching for memory leaks or other bad behavior on a certain very high-turnover series of pooled objects. If pool counts keep rising, or other numbers seem off, then we know we have a memory leak or a performance problem.
- Thanks to Puppet Master, RockyBst, Lord Of Nothing, and NRSirLimbo for reports that led to us finding this.
- Fixed a MAJOR bug from version 2.099 that was leading to a memory leak in general, and performance problems as well (the longer you played the slower it would get).
- Our entire "time based pool" logic was not actually properly processing because we forgot a single line of code, go figure.
Slow Load Or CTD Fix
- Since we started using the asynchronous loading of asset bundle items using unity (the last few weeks), there have been some intermittent problems with certain random items not loading in properly. This is some sort of funky bug in Unity, we're pretty positive.
- We solved that problem a week or so ago by checking the async request's asset property, and if it was not invalid, forcing it to finish loading even though it was stuck.
- On most machines, this was causing a really annoying lag of 10-25 seconds while Unity did whatever it was doing to finish that load. That was really annoying, but only happened the first time you loaded a savegame or quickstart or custom lobby after starting the program, and not every run of the program, and not on all machines.
- More recently, we discovered that the very act of checking the async request's asset property would cause an unrecoverable error deep in unity and an immediate crash to the desktop.
- Killing two birds with one stone, we're no longer checking the async request asset property at all -- thus avoiding the crash -- and instead just do a normal synchronous load when we detect a failed load. This leaves the one async request in limbo kind of forever, but that shouldn't be a problem; if it ever decides to complete, it will see that it was already completed and just do nothing.
- In the meantime, not only should this avoid the crash, but it should also avoid that awful lag spike that happened for those for whom it didn't crash.
- The downside is that on our dev computers we haven't been able to replicate the error at all today, so we can't verify that this 100% works. It should work, and you should see in the arcen debugging log slightly differently that says "PrototypeObject failed async load and so loaded synchronously for [some stuff] (this is not a problem, but is odd)"
- If you're one of the people who were frequently seeing either the crash, or seeing the older "PrototypeObject fixed and loaded late for [some stuff] (this is not a problem, but is odd)" message, then we'd love to have a confirmation of you seeing the new message and all being well.
- Thanks to Sol and RocketAssistedPuffin for reporting.
Version 2.101 Connection Status: Confirmed
(Released July 17th, 2020)
- Carriage returns and newlines are now supported by the "condensed" string format. This will prevent tutorial messages from turning those characters into question marks when they are dumped to the chat log. Note that this will only affect chat log messages logged in this version and on, not past versions.
- Thanks to ParadoxSong for reporting.
- The left and right click functions of the metal display have been switched to be more natural.
- Thanks to Waladil and Galian Gadris for suggesting.
- The "Spire Railgun Shop" mod that comes packaged with the game has been updated to use the icons from their new locations, and will no longer error.
- We've reworked our "Window_PopupScrollingColumnButtonList" a bit to add some new handy features for us.
- In the factions selection window, when you are adding new factions, it now still lets you see factions that you can't add because there is only one per galaxy, but now it shows them in red, doesn't allow you to select them, and explains why in the tooltip.
- In the debug menu in the escape menu in the main game, the change music submenu now shows the current selection in red (with the note that you can't change to it because it is already playing), and it shows all of the options sorted alphabetically except for the current track, which it shows as the first item.
- Also fixed a bug where the music you selected to play would not actually be the track that played; it was choosing a random other track.
Scourge Updates
- The hovertext for the Scourge "Strength" in the game lobby now tells you what the strength does (more scourge ships/structures, and faster).
- Add a "Sandbox: Extra Strong Mode" for the scourge
- This is not balanced for regular play, but is intended as a sandbox thing.
- Thanks to Avenger1649 for suggesting
- Fix a bug where the scourge were periodically suiciding Defensive Fireteams into player positions.
- Thanks to ParadoxSong for the save.
- On intensities >= 5, the scourge can create cloaked "blockade running builders" if the player has tried to blockade the scourge into a small region of the galaxy
- Thanks to ParadoxSong for the suggestion
- On intensities >= 6, the scourge is intended to sneak a builder off to another part of the galaxy at the beginning of the game, to make it much harder for the player to blockade them in. This was not working on some map types, including the X type.
- Thanks to ParadoxSong for the save that exposed this problem.
- These changes should make the scourge much harder to deal with in general, and on the X map type in particular.
Initial Multiplayer Connection
- AllowOtherPlayersToConnect was a setting on the World object in the past, and thus something that was getting saved into savegames and that dictated how a lot of things worked for player connections.
- We've removed this concept, and instead are making it based on the menu choices you make on the main menu.
- We now have a DesiredMultiplayerStatus on ArcenNetworkAuthority, which lets us recall if you wanted to be the client, a host, or just left alone in single player.
- The basic shells of SteamSocket and GOGSocket have been added to the game. The in no way function yet, but this will allow for them to be built out in the future.
- The SpecialNetworkType has been moved into ArcenUniversal, and is now copied onto ArcenSocket along with the InternalName of the row that created the socket.
- There is now a list of AllPossibleSockets on the ArcenNetworkAuthority to allow it to swap between sockets as needed, and particularly by type.
- When you open the multiplayer menu, if you have that enabled, it will now set a default network framework for you based on the status of your game at that time.
- If you are logged into Steamworks, it will set steam as the default network.
- If that didn't work or wasn't true, and you are logged into GOG Galaxy, it will use that as the default network.
- If none of those worked, then it will pick the first "other" network type, which in this case would be Forged.
- All of the options in the multiplayer menu for hosting a savegame, quickstart, or custom game now properly do those things identically to as if it was the single-player menu, but put you into host mode first.
- The single-player menu puts you into single-player mode, and makes sure that your ArcenSocket is set to NullSocket.
- When you try to go into one of the client or host multiplayer areas from the multiplayer menu, it now properly activates your most recent chosen network framework, or switches to the first available one that actually can function right now on your system and gives you explanations for why it did that.
- Essentially there is a fair bit of under the hood plumbing now for the frameworks to register themselves with the network authority class and explain about their availability.
- If you are looking to connect to another machine, then the "connect as client" tooltip now gives you information about what to expect based on your currently-selected framework.
- Are we connecting by IP? How much of a hassle will that be? Is it going to be by selecting a friend on Steam or GOG? Etc.
- For IP-address-based networking frameworks, either starting a host mode or client mode event now pops up with a message explaining what information you need to give to the client players or get from the host.
- This is not really the preferred networking method unless you're having a LAN party, and the game makes that clear, but it also goes out of its way to address the most likely areas of potential confusion for people who are using these frameworks.
- Fixed a few bugs, and added a bit more debug logging clarity, so that the host can once again properly open a socket and wait for connection.
- This was working up until a week or so ago, and was simply messed up a bit when we reworked things to support multiple networking frameworks. There were lots of lonely hosts never getting any client requests ever since the game has been in public beta.
- When you quit out of the multiplayer lobby back to the main menu, it now immediately disconnects you as a host or client, to avoid confusion of lingering connections.
- When you are in the lobby in multiplayer, the chat sidebar/log now appears again. At the top it says if you are hosting multiplayer or a multiplayer client.
Choosing A Networking Framework
- The main menu has been updated so that the "network" button at the top of the multiplayer menu now updates its text to show the current network.
- The network button at the top of the multiplayer menu on the main menu is now fully functional. It shows available network frameworks, and gives you explanations for each one, as well as showing unavailable ones in red with an explanation for why they are not available right now. It lets you select from available ones, which then get set as your current socket when you try to host or join a multiplayer game.
What Is My IP Address If I Need It?
- In the networking section of the settings menu, it now has helpful informational displays of your local IP addresses and your public IP address.
- To get your public IP address, we have to make a public call to the url http://checkip.dyndns.org, so this may flag your software firewall to ask permission when you go to the networking tab now.
- Our goal is of course for you to not have to use your direct IP addresses at all in this game, but if you're playing on a LAN then that would be one great example of when you'd want to use this.
- At any rate, each IP address is stored in a textbox that you can copy-paste from, which is very handy when sharing with friends.
- There are also lengthy explanations about what the public IP address is for, and under what circumstances to use it, as well as the local IP addresses, plus special notes for any IPV6 addresses that it detects.
- Getting this data is time-consuming for your computer, so you will notice micro-lags every few seconds while you are on the networking tab, now. This is normal and should not impair your use of the functionality.
Milestone: Successfully Connecting A Client To Host
- The old interface for network connections by IP address is restored and works again. We'll have a different one for connecting via friends list on Steam and GOG, later, but this is the one that gets used for Forge and any other IP-based network frameworks.
- Connections are now able to be established from one computer to another, for the first time since 2018!
- We added the ability to see how many clients there are connected to a host in the lobby (including the host), so you can see the connection tick up.
- Next up is them actually exchanging enough information to get the client into the lobby and have them see shared world info and be able to chat and all that. But this is milestone one!
Version 2.099 Last Rabbit Holes
(Released July 15th, 2020)
- There is now a galaxy setting to grant players Watch vision for 1, 2 or 3 hops from all command stations.
- Thanks to uhamster9 for inspiring this addition.
Fixes And Tweaks
- Improved the way that time-based pools are incremented in time, so that we're never having accidental cases where we miss one.
- Also made it so that they actually work as intended when the world is being cleared (running 16 seconds' worth of time at once). This then keeps the pools smaller if you repeatedly load savegames.
- On the escape menu, under where it shows you the various numbers of objects in memory, it now shows you the number of galaxy planets and planet links activated and in existence.
- This lets us tell when these have a memory leak, if there ever is one with them.
- Additionally, galaxy map links are now pooled for the first time ever, as the discarding of them was previously a definite memory leak. Normally this just happened between saves and loads, but it was also possible to happen when nomad planets moved.
- In addition to the existing time based pools, we now have a new ExternalizedPool.
- This is now used for the galaxy map links, and actually we have stopped the galaxy map planets themselves from using the super-old IArcenGameObjectResourcePoolable and they also now use this.
- The way that planets for the galaxy map are initialized, and the way that their positions are set, is completely overhauled.
- This is more efficient and properly uses pooling (which never was working properly before, it turns out).
- It also makes the position of planets automatically react to them having moved in the game sim, without having to do anything special.
- The arcencolors asset bundle has been removed, with its contents simply rolled into arcenui. Ultimately this is a bit faster to load, and saves a bit of disk space and RAM also.
- Also removed the aiw2squads bundle, and the examples bundle.
- The examples bundle simply has its example content still there, but not in a bundle (it's to help aspiring models modders).
- The squads bundle is old data that we've not used in forever, and so has just been cleared out. It wasn't huge, but wasn't worth being there.
- Also removed the aiw2squads bundle, and the examples bundle.
- Starting to load a savegame (including for a quickstart or the last settings for a lobby) now writes to the log when you start the process, and at the end of the process writes how long it took.
- Added a new debug setting: "Write Detailed Savegame Timings"
- When loading a savegame, including the 'last settings' for the lobby or the basis for a quick start, keep track of detailed timing data and write that into the normal debug log so that it's clear what is taking longer and shorter amounts of time.
- It turns out that chasing "why savegames now take 16 seconds to load sometimes" was a snipe hunt. The serialization sizes logging, when enabled, actually was causing that amount of slowness. With that off, it loads in about 2 seconds.
- The extra instrumentation that we added for the savegame timings is still nice, but ultimately was not a useful bit of time spent at the current moment.
- Fixed an issue that could happen in the lobby in particular where it could not properly save your prior settings because the fleet ID or speed group ID was lass than zero.
- This pretty much could only happen if you already had another error first.
- Fixed an exception in SeedNormalEntities that could happen if you rapidly tried to regenerate maps in the lobby in just the wrong way.
Under The Hood Improvements For Icon Modding And RAM Usage
- The last of the icons from the ExternalIcons folder have been moved into the unity project that generates the asset bundles, simply to dispel any potential confusion about the fact that they can be edited directly and that have some change on the game without recompiling asset bundles. This was a frequent modder confusion.
- That said, the ones that were in the Official_1 folder are now in a CentralIconBits, and can now be used in the UI for the first time if we ever want to. That means things like health bars and whatnot could in theory be used in the ui if someone wanted to, whereas before they could only be used on gamespace-level icons.
- Cleaned out a variety of unused icons from the arcenui asset bundle, and in general tidied up some of our organization of working files versus final files.
- Also standardized the naming of certain things.
- Broke the "official icon dictionary" out into six dictionaries:
- One is for the "central bits" like health bars and so on, and would be the same for all ships.
- Two are for the overlays, like for saying what kind of starship or guard post something is. There can be more than one of these, and the fact that these are split out like this demonstrate the modding capabilities and how things can combine.
- Three are for ship icons and their borders, and there can be more of these modded in as well. As with the overlays, not only does this demonstrate how such mods would work, but it also has the side benefit of slightly less VRAM usage in a few cases.
- The way that GUI icons are discovered from the xml based on their gamespace-icon counterparts is completely revised, and is now based on extra information in the ExternalIconDictionary entries.
- This is a lot more flexible, and allows us to load icons from multiple asset bundles and/or multiple files within the same bundle.
- The naming for finding icons is now much more complicated, in the sense that they don't all come from a single dictionary called "Official."
- So there were over 1100 places in the base game and expansions where we've had to modify to point to the new dictionaries. Any mods would also need to be updated to point to the new places, unless they want to start using their own icons (once we put together a tutorial for that).
- The external sprite dictionaries have been updated to be able to properly load in in multiple threads.
- The game is now able to load the xml files for external icons from any mod or expansion, in:
- Expansions/[ExpansionName]/GameData/ExternalIcons/[thefile].xml
- XMLMods/[ModName]/ExternalIcons/[thefile].xml
- XMLMods_NonDistributed/[ModName]/ExternalIcons/[thefile].xml
- It's worth noting that these are xml files that are generated by Texture Packer, not xml that we create.
- These files are referred to in the "ExternalIconDictionaries" xml as something along the lines of xml_path="Official_CentralIconBits.xml"
- It will then search the main game's folder (/GameData/ExternalIcons/[thefile].xml), then all the expansion folders, then any activated mod folders for a file with that name that was specified.
- This allows for mods to be self-contained when it comes to their icons, and it allows expansions to have their own icons that are not packaged with the main game (not that we have imminent plans to do that).
- On the icons used in the game, we previously were not using any compression, which made them absolutely massive in size (80mb for the main dictionary).
- This was done in order to preserve quality, but we're also using GIANT icons in order to allow for really super-high-res displays of the future, as well as square ones to allow for ideal mipmaps, etc. So the lack of compression was hugely overkill.
- We're now using compressed textures, which turns what was 80mb into more like 8mb. This has a very direct impact on performance and VRAM usage, so particularly on low-spec machines they will likely run far better.
- The game now automatically constructs custom "gimbal materials" for the in-gamespace icons, in as many combinations as are needed for the things that it has drawn for you so far.
- The total number of materials always in the past was "one," but it was using a single large dictionary and a lot more VRAM -- and it had a finite amount of space for things. There was a solid chance we were going to run out of space in that one dictionary as part of implementing DLC2. But either way, mods were not possible. The new number right now is 8, looks like.
- Now it may make a handful of materials, depending on how many mods you have installed that have custom icons, and several for the core game and expansions itself. But these are vastly smaller, and while this does increase the number of "draw calls," each material is still mostly instanced together (there are a few mesh differences depending on if there are health bars shown or whatever), but the overall load on the GPU pipeline is lower.
- All of this is automatically handled by the game in as efficient a pattern as possible, and if you're curious how many combination materials it has created, you can see that in the escape menu at the bottom of the list of memory pooling info.
- A new debug setting, "Log Gimbal Icon Material Creation", has been added:
- When this is on, any 'gimbal icon' material creation events will be logged as to what was created and how long it took to do so.
- Turns out that this uses an immeasurably small amount of time for each material (less than 1ms each), so that's awesome.
Under The Hood Improvements For Mods With Code
- The game is now able to load dlls from mods or expansions, rather than just from the central game folder.
- This works just like the external icon files, and basically looks for the dll in the central game folder first (/GameData/ModdableLogicDLLs/[thefile].dll), and then looks at expansions and then installed mods if it can't find them.
- The paths are:
- Expansions/[ExpansionName]/GameData/ModdableLogicDLLs/[thefile].dll
- XMLMods/[ModName]/ModdableLogicDLLs/[thefile].dll
- XMLMods_NonDistributed/[ModName]/ModdableLogicDLLs/[thefile].dll
- We really don't have a need to do this with expansions, but the flexibility is nice.
- With mods that are more than just xml, however, this finally lets a modder distribute just a single folder that has everything in it, and not have to worry about putting some things in central game folders.
- This is only partially tested, but should work.
- It's worth pointing out that expansions and mods already did (and still do) have the capability to load asset bundles (icons, music, sound effects, models, textures, shaders, etc) from their folders.
- The structure for those is /GlobalBundles/ in the main folder for anything not platform-specific, /AssetBundles_Linux/, /AssetBundles_OSX/, or /AssetBundles_Win/ for the things that are.
- Inside the folders for expansions it is: Expansions/[ExpansionName]/[OneOfTheAboveFolders]/
- Inside the folders for mods it is: XMLMods/[ModName]/[OneOfTheAboveFolders]/ or XMLMods_NonDistributed/[ModName]/[OneOfTheAboveFolders]/
- None of this is new, but it's worth mentioning for now.
- This is only partially tested, but should work.
Larger Gamespace Icons And Fixed Galaxy Map Line Offsets
- We also now have a non-billboarding version of our shader for purposes of our icons on the galaxy map.
- Our core shader does on-GPU (read: hyper efficient) billboarding to always fully face the camera. This is very useful in the main view where you are moving around the camera a lot but always want the icons to face you.
- The downside, however, is that with a largely-straight-overhead camera like the galaxy map uses, this billboarding would cause there to be a perspective shift where the icons for planets would get offset from the lines leading between planets no matter what we did. It also caused them to move relative to the text that was next to them.
- This offsetting of the lines to the planets was one of the largest "visual papercut" issues that we've had for a really long time, and it is finally fixed!
- The ship icon scale has been adjusted from a default of 1.5 to 2.2, and will affect all prior settings files.
- It's description has also been updated for the personal settings tooltip: For the icons in the main display area (not the sidebar), how large should they draw? Default is 2.2. If you go too large, it can be hard to see things because they overlap too much. If you go too small, they can get extremely blurry because of flipping to a lower mipmap. The larger your screen DPI, the smaller you can go without losing clarity.