Difference between revisions of "AI War 2:Multiplayer Alpha And Beta"

From Arcen Wiki
Jump to navigation Jump to search
 
Line 1: Line 1:
 
== Known Issues ==
 
== Known Issues ==
  
* Any bugs or requests should go to mantis: https://bugtracker.arcengames.com/view_all_bug_page.php
+
* Any bugs or requests should go to our [https://bugtracker.arcengames.com/ mantis bugtracker]
 +
** If you need to submit log files, those can generally be found under your PlayerData folder in the folder your game is installed in.  The most relevant one is called ArcenDebugLog.txt.  You can send us the whole thing, or just strip out relevant parts.
 +
** In rare cases, mainly if your entire game crashes (that almost never happens), we will need your unity player log.  That gets overwritten the next time you run the game after a crash, unlike the other log.  These can be found here:
 +
*** Windows: C:\Users\username\AppData\LocalLow\Arcen Games, LLC\AIWar2\Player.log
 +
*** macOS: ~/Library/Logs/Arcen Games, LLC/AIWar2/Player.log
 +
*** Linux: ~/.config/unity3d/Arcen Games, LLC/AIWar2/Player.log
  
* '''Multiplayer is disabled but coming very soon.''' We first focused on tightening up the single-player loop ([https://forums.arcengames.com/ai-war-ii/from-the-dev-notes-on-where-i'm-at-regarding-multiplayer-right-now-(729)/ more info here]), so thanks for your patience!
+
* '''Multiplayer is in public alpha, as noted below.''' There is a [[:Category:AI War 2: All About Multiplayer|detailed multiplayer guide]] that we are working on building up.
  
=== Multiplayer Remaining Todo List ===
+
* Feel free to [https://discord.com/channels/240637654717300736/242012213580136448 join discussions on discord]!
  
==== Short-Term Work ====
+
== What Does Multiplayer Alpha Mean? ==
  
* Client bugs in lobby:
+
[[:Category:AI War 2: All About Multiplayer#Initial Caveats And Related Resources|Please see this link for details on multiplayer.]]  This wound up taking up too much space in this document, so all of the multiplayer-relevant bits have been moved to the other page.
** Not able to change planet count.
 
** Map sub-types not shown correctly after they change.
 
** Clicking regenerate map does not work on client.
 
** Randomize seed from client does work, but causes host and client to diverge.
 
** After several regeneration attempts from client and host, client gets black screen with no responsiveness or errors.
 
*** Possibly this causes the settings for the game to get completely zeroed out, which then leads to the strange black and white view the next time you log on.
 
** Chat sent from client shows up twice on host and not at all on client.
 
** Chat from client shows up on host as "Player 2" rather than the proper name.
 
  
* Show when clients are in spectator mode, or what faction they control.
+
== What's this phase all about? ==
** New section above chat textbox that shows all of the player accounts for all clients and the host, with the proper names in place.
+
 
 +
Multiplayer is fully playable at this point, but still has a variety of glitches and doesn't have all of the features that we intend to have in the long term.  So hence it still being in alpha status.  But we greatly welcome folks to play, and hopefully give us reports on what is going wrong if something does go wrong.
 +
 
 +
We expect to be to a fully-polished non-beta status for multiplayer in November or December, if things continue as they have.
 +
 
 +
Our second expansion for the game, Zenith Onslaught, has a whole heck of a lot of it completed, but still needs more doing.  Badger has done all of his parts for it, and has [[AI_War_2:Sunset_of_The_Badger_Era#The_Badger_And_Puffin_Legacy|retired like Puffin before him]], so at this point we are down to basically a one-person show again (me, Chris) on bugfixing, finishing multiplayer, finishing my parts of DLC2, and finishing the last of the kickstarter obligations.  So if the schedule slips some, it's likely because I had trouble juggling that, or wanted extra time to make things truly shine, whichever.  But at the start of this phase, things are feeling very positive.
 +
 
 +
== Version 2.646 ==
 +
(Not yet released -- we're still working on it!)
 +
 
 +
* Civilian Industries Update
 +
** Updated for the latest version of the game.
 +
 
 +
== Version 2.645 Hotfix ==
 +
(Released December 3rd, 2020)
 +
 
 +
* Fixed a wide array of exceptions that could happen, particularly as of the last version, if you had a partially failed save or quickstart load.  If the playeraccount was missing, which is the real bug, then certain other parts of the code would spam tons of errors and obscure the real one.  They no longer do.
 +
 
 +
* Fixed a one-line typo with the recent changes to delayed invasion support for the nanocaust that was causing all older quickstarts and savegames that included the nanocaust to not be readable.
 +
** Thanks to Cel for reporting.
 +
 
 +
== Version 2.644 So Many Good Things All At Once ==
 +
(Released December 2nd, 2020)
 +
 
 +
* Added a new "Invert Mousewheel UI Scrolling" setting to the HUD section of personal settings:
 +
** Description: Normally when you spin the mouse wheel forward, any scrollable areas you are hovering over in the UI go up; spinning backwards goes down.  This lets you flip that functionality.  OR, in the case that your hardware or OS is inverted for whatever reason, this lets you correct it to work like everyone else.
 +
*** Note: if you also want/need to invert how your mouse wheel works when zooming the game view, then be sure to also set the 'Invert Mouse Zoom' option in the All Cameras section.
 +
** We also updated the other setting to also mention this one, so that if you find one of them you can find them both.  We left them as two separate settings since some people might want one and not the other if this is a personal preference and not the "backwards linux mousewheel" bug.
 +
** We thought that this was something we could not fix without unity taking care of it on their end, but we took a peek at some of their old decompiled source code and found an efficient way to find all of the objects that need reversed scrolling and update them in cases where that is indeed  needed.
 +
** Thanks to Blu3wolf, The Main Man, whetstone, TechSY730, Matruchus, Elos, carewolf, and others for raising the issue again.
 +
 
 +
* Remove a mechanism where fireteams would deliberately overestimate turret strength; turrets are no longer under-valued strengthwise so this mechanic was now making the Hunter even more timid.
 +
 
 +
* The Hunter is no longer allowed to retreat from a battle involving the AI Overlord. They must fight to the death there. This includes Exogalactic War Units.
 +
** This has been reported in a number of places, but most recently by Waladil on discord
 +
 
 +
=== Delayed Invasion Support ===
 +
 
 +
* Marauders can now be requested to do a "delayed invasion", ie they won't start attacking until a ways into the game.
 +
 
 +
* The Nanocaust can be set to invade at a random time during the game, or immediately. This replaces the old "Non-Immediate Nanocaust are seeded as beacons" paradigm.
 +
** If not explicitly requested, the nanocaust will appear in a beacon.
 +
** This change means the Nanocaust now works "correctly" in the game lobby.
 +
** This resolves bug reports from ParadoxSong and Isiel. Possibly others as well
 +
 
 +
* Also you can request the nanocaust to appear on a player planet. This is a terrible idea unless they are your allies
 +
** Requested by Arc-3N-4B
 +
 
 +
=== Galaxy Map UI Additions ===
 +
 
 +
* On the galaxy map bottom left bar, there are edit planet and ping planet buttons, but for now those are just going to have a "coming soon" tooltip on them.  We'd rather not delay the rest of this release another day just for them.
 +
 
 +
* The new default for when icons and text on the galaxy map stop drawing is 10, rather than 1.5.  It will update existing settings for you.
 +
** This makes them always show, even if it does get crowded.  Trying to use galaxy map filters with them disappearing was an exercise in anger management.
 +
 
 +
==== Planet And Unit Search ====
 +
 
 +
* Added a new "GalaxyMapTextboxFunction" xml table, which lets us (or modders) define "a thing that uses a textbox on the galaxy map to do something."
 +
** That is vague somewhat on purpose.  But mostly we expect it will be used for searches of various sorts.
 +
** For now we have implemented one for finding planets, and another for finding units.
 +
 
 +
* There is a new bottom-left UI element on the galaxy map view.  This has a number of functions built all into one.
 +
** First of all, it has a new find planet option, which is extremely responsive and lets you search for planets by partial text, darkening all others that are not including that text.
 +
*** It also shows the names of all the planets that come back as possible matches, even if they would not normally be shown right now.
 +
*** It does not try to do any centering on the planets it finds, as it might find many.  But at any rate, this is a very dynamic and simple way to find planets by name.
 +
** Secondly, it has a function that lets you search for planets by name of a unit (ship or structure).
 +
*** Any icons shown at planets will be shown in this mode, regardless of zoom distance.
 +
*** Even better, it actually hides all of the icons that would normally be shown, and instead shows the first ship icon of each match that it's finding on that planet (if there are 100 v-wings, it will only show the icon for one of them, but you're usually not searching for something like that).
 +
 
 +
==== Fleet Status Window ====
 +
 
 +
* Added a general new Window_BottomLeftSelfUpdatingTextWindow, which works pretty much like Window_ModalSelfUpdatingTextWindow from a code standpoint.  However, this lets us give a non-modal (aka non-input-blocking) onscreen view of some sort of information over there on the left where chat and such would be.  Tooltips and chat and similar will block this view, but otherwise it stays open until you close it, which can be useful for information players want to have at their fingertips and that a modder or developer wants to provide them.
 +
 
 +
* Over the last couple of weeks, Badger has been working on a Fleet Status display that was kind of hidden up there on the attack buttons in the top resource bar.  There is now a dedicated F Stat button on the galaxy map that you can hover over to find out about this function, and left click or right click to get information on local fleets or all fleets.
 +
** This is the first usage of the new Window_BottomLeftSelfUpdatingTextWindow, and it lets you keep an eye on your own status of fleets, or the status of allies in multiplayer, that sort of thing.
 +
** This is no longer openable off of the resource bar, but instead just off this new galaxy map button.
 +
 
 +
==== Galaxy Map Display Modes ====
 +
 
 +
* Galaxy map display modes make a triumphant return! 
 +
** All of the prior ones that were there were really old, not having been altered since... goodness, September 2017.
 +
** When we updated the game to a new UI style in 2018, these were disabled and we never got back to adding them in until now.  With that said, we're revisiting what they actually do, or replacing them.
 +
 
 +
* Normal display mode (what you've seen always for the last few years):
 +
** Ignores what factions you select on the left dropdown.  Shows your strength on the right of each planet, and enemy strength on the left at each planet.  Unit icons shown below the planet are a general mix of high priority units.
 +
 
 +
* On all of the galaxy map modes, it now is sure to keep showing your own fleets, since those are useful to be able to select and click and such no matter what else you're looking at.
 +
 
 +
* Metal Production display mode:
 +
** Shows how much metal the selected faction(s) are generating at this planet in gray, and how much is available but not used by that faction in red.  Unit icons shown under the planet are one per type of metal generator.
 +
** Useful for seeing which planets have more metal that you might want to capture, where your main metal production is, and where your metal production has taken damage.
 +
 
 +
* Energy Production:
 +
** Shows how much energy the selected faction(s) are generating at this planet in gold, and how much is available but not used by that faction in red.  Unit icons shown under the planet are one per type of energy generator.
 +
** This is useful for seeing where you're generating energy in a visual way, AND for finding large energy generators that you might want to capture out in the rest of the galaxy.
 +
 
 +
* Science And Hacking
 +
** Shows how much science and hacking points are left to be gathered on each planet.  The only unit icons shown under planets are player fleets.
 +
 
 +
* Strength:
 +
** One of the most useful display modes!  Shows how much strength the selected faction(s) have at each planet.  The only unit icons shown under planets are player fleets.
 +
** This is the really important filter!  This is how you find out just how strong the hunter is, wherever it is, or easily pick out exactly where the warden is hiding.  Assuming you have up to date intel, of course.
 +
 
 +
* Strength With Top Ships
 +
** Mostly the same as the Strength display mode.  However, this is much more cluttered because of the icons showing the three strongest units of the relevant faction(s) being shown as icons under each planet.  So this is less useful than the general Strength display mode for seeing an overview of everything, but it's great for observing what the big hitters are at various planets all at once.
 +
 
 +
===== Faction Filters =====
 +
 
 +
* On the galaxy map, there are now detailed faction filters for EVERY faction, including normally-not-listed ones, all organized into various categories with proper explanations.
 +
** This actually took WAY longer to create than we expected, but it gives the ultimate in flexibility in all that.
 +
** The nice thing is that this only fills in as you actually encounter members of each faction, so this starts out smaller but then grows substantially as you find sub-parts of the AI, etc.  So for example, you likely will not see any Praetorian Guard entries for a while, and you would not see AI Reserves until they have struck you at least once, etc.  No tamed macrophage unless you actually meet one.
 +
 
 +
* Factions in general can no longer override CheckIfPlayerHasSeenFaction(), which we have upgraded to properly support beacons and other things of that sort.
 +
** There is now a new DoOnFirstSightingOfFactionByPlayer() that factions can override to get the same sort of effect they used to have.
 +
** You may need to let the game run for about one second before things will properly show up in terms of factions that should be visible.
 +
 
 +
* Added a new FactionGroup class, which lets us start displaying/discussing factions by whatever arbitrary categories.
 +
** For now we have All, My, Allied, Hostile, and Beacon as the categories, with tooltips explaining each.
 +
 
 +
* Added a new FactionFilter struct, which lets us mix actual factions with faction groups, and display them in a nice list that we can also sort.
 +
 
 +
* Badger's fancy SortFactionsForDisplay() has been removed off of Human.cs and is now on BattlefieldVisualSingleton.
 +
** However, it should never be directly called anymore.  It should now be retrieved from FactionFilter.GetLatestSortedFactionCompleteList() to get that result which is cached and only updated once every 10th of a second.
 +
** This now lets us get that from other parts of the code that are not in externalData, too.
 +
 
 +
* Beacon factions that have not been summoned yet now show "(Beacon)" in front of their names.
 +
 
 +
* Added a new is_considered_visible_part_of_the_ai_faction_for_filter_purposes for factions, which lets us have certain sub-factions like the AI Hunters and such show up more prominently in the list of factions in the galaxy map filters.
 +
** Also added is_considered_player_allied_for_filter_purposes for purposes of getting the Outguard to show as a player Ally even though they are usually invisible.
 +
 
 +
=== Updates To Included Mods ===
 +
 
 +
* Fixed the spire railgun shop mod to use the newer xml that is about spire ships not working when not on a PLAYER planet, instead of a specific owner faction.  This was a change we made for multiplayer compatibility, and it changed an xml tag.
 +
** Thanks to Badger for reporting.
 +
 
 +
* Kaizers Marauders improvements:
 +
** Removed the ability to assign negative budget and in return changed and integrated the Invasion Time setting from Vanilla
 +
*** Assigning negative Budget would work, but had its issues: Marauders were forced to start out very small, the timing was estimated at best and could vary incredibly
 +
** Now the player can choose Immediate, 1-10 hours and Random /Early/Mid/Late/Very Late game and Random All, which translate to 0-2, 2-4, 4-6, 6-8 or 8-10 hours of actual game time, with Random All being 0-10 hours
 +
** Essentially the mechanic is that in beacon mode the beacon will self-destruct when the time mark is reached, BUT the player can still destroy it earlier. During this time Marauders gain NO Invasion Budget
 +
** When not in beacon mode Marauders are prevented from doing any invasion logic until their time has come, but they passively accumulate more budget and will invade with quite a few forces. Note that they do NOT get any bonus budget from owning no planets as that would likely lead to much, much greater invasions yet...
 +
 
 +
* AMU now has a new function: parseFIntFromStringUpToFirstSpace(). Can parse numbers like 1 / 1.6 / 100.738, etc. If more than 3 decimals are used any excess is discarded.
 +
 
 +
=== Bugfixes ===
 +
 
 +
* Fixed divide by zero exception that could happen in the risk analyzers faction.  This was not related to any recent changes, it just was apparently rare.
 +
** Thanks to Isiel for reporting.
 +
 
 +
* Previously, mod names with spaces in them would cause the settings file on your machine to become corrupt and unable to be loaded.  This should no longer be the case, although we've not tested it.
 +
** Thanks to ArnaudB and Isiel for reporting.
 +
 
 +
* The capsule colliders on the lines between planets on the galaxy map no longer size up or down.  This can mean that on very far zoom on very large maps it can be hard to get your mouse exactly over the line, but it's still very much possible and this is hardly a crisis.  The main thing is that these no longer get in the way of the planets themselves, which may have been happening.
 +
** We investigated the planets themselves getting off on scale, but did not find any evidence of drift, and were already using the careful approach that we were considering "switching to."
 +
** We did also find a number of cases of places where things like notifications might have been getting in the way, with text that was extending beyond their bounds.  We fixed all of those as well, in case those were what the problem was.
 +
** Thanks to AxiomExotic, afterthought, Vortex, Karlant, and Badger for reporting the problem with the hitboxes on the planets on the galaxy map still being there after long enough sessions of play.  This may not solve it, but it does remove several areas of potential problems that were in place.
 +
 
 +
* If a dropdown list is extended, and the number of items in the list changes, it now refreshes with the new options included.  Previously, you had to close and reopen the dropdown list.  That was potentially not possible to have happen as a situation before, but with the list of factions on the galaxy map it now is.
 +
 
 +
* Fixed another issue with dropdowns still staying open after you switch to a different context where their parent window area is no longer visible.  This was super noticeable with the new galaxy map controls.
 +
 
 +
=== Balance Tweaks ===
 +
 
 +
* Fixed Veteran Sentinel Gunboat having lower damage than normal, due to being missed in a long ago previous update.
 +
 
 +
* Fixed Cloaked Mugger having less health than the normal version, due to being missed in a long ago previous update.
 +
 
 +
* Reduced range of any Tier 1 Extragalactic units that were above 8,000 (before global range modifier) to 8,000.
 +
** Due to mentions of most Turrets being incapable of fighting these, and these are the tier that will be hit in most normal games, excluding modded ones and Fallen Spire runs.
 +
 
 +
* 'Ram' Auto Bombs swap their armour damage bonus for a new one, that works against armour of +90mm. Mass damage bonus increased from 5x to 7x.
 +
 
 +
* Altered Parasitic starting fleet. Normal Parasites are replaced with 25 Parasitic Pike Corvettes, 1 Mugger is removed, and 40 Stalkers are added.
 +
** The Why:
 +
*** Too many Parasites and not much damage led to this being a very slow start.
 +
*** Thus, some Parasitic Pike Corvettes were swapped in for some extra firepower, but keeping zombification.
 +
*** 2 Muggers is actually in excess of the normal cap size, so 1 is removed.
 +
*** Stalkers are added to give this fleet more single target power, making up for the loss of the Mugger, and lets it fight things such as Sabot and Nucleophilic Guard Posts early on (things which counter said Muggers).
 +
 
 +
* Dire Tesla Guard Posts weapon jam works on armor <= 90, rather than <= 101.
 +
 
 +
==== Turrets ====
 +
 
 +
* Altered "large" Turret energy costs to have the same "cap scaling" as the "small" Turrets.
 +
** E.g a Pike Turret cost 2,250 energy. A Crusher Turret cost 37,500 energy.
 +
** A full cap of Pikes would be 5, costing a total of 11,250, compared to the full cap of just 1 Crusher Turret, still 37,500.
 +
** Now, the Crusher Turret costs the same as that full cap of Pikes.
 +
 
 +
* Mini Fortress energy cost halved.
 +
** An exception, due to a report about its power, this has less of a change (66% reduction often).
 +
 
 +
* Crusher Turret magnetic pull range increased from 4,200 to 6,500 (before global range modifier of 0.8x). Crusher weapon range changed from 1,000 to 1,700, hits 20 targets instead of splitting damage evenly, net DPS the same.
 +
** The last part lets it focus damage more, rather than spreading it out so much it doesn't help to kill anything off.
 +
** Also hopefully improved its pull targeting.
 +
 
 +
* Acid Turret effect increased from 50 to 65, shot count 3 -> 5.
 +
** Will attempt to add Mark scaling to the effect, requires code investigation.
 +
 
 +
* Increased target priority of Bulwark Turrets a chunk.
 +
 
 +
* Doubled the self-build rate of the "Raid" technology Turrets, excluding Blitzkrieg which is a "large", and did not have the appropiate build rate for its size. It now does, and then that is doubled, leading to it being 6x what it was before.
 +
 
 +
* Fusion Turret reload time reduced from 2s -> 1s, damage 700 -> 350, loses shield bypass. Instead, gains a 12x damage bonus versus personal shielding.
 +
** This replaces the ability to quickly destroy structures (not too useful on defense) with instead a highly supportive role, potentially useful combined with Imploder and Subverter Turrets.
 +
 
 +
* Fuseball Turret range 10,100 -> 15,000.
 +
 
 +
* Makeshift and Blitzkrieg Turrets no longer spawn units on death. Instead, they use the "drone guns" present on Combat Factories, as well as Tesla Torpedo and Tackle Drone Frigates (they have infinite range).
 +
 
 +
* Makeshift Drone damage reduced 33%.
 +
 
 +
* Increased Vampire Turret damage 25%.
 +
 
 +
* Shredder Turret range increased from 4,200 to 5,200 (before global range modifier), damage increased roughly 30%.
 +
 
 +
* Increased Imploder Turret damage 50%.
 +
 
 +
* Doubled Deathgrip Turrets tractor count, increased range from 4,200 to 5,200 (before global range modifier), damage increased 20%.
 +
 
 +
* Increased Jammer Turret damage 50%.
 +
 
 +
* Increased Translocator Turret damage 50%.
 +
 
 +
* Doubled Tritium Sniper Turret damage, halved multiplier.
 +
 
 +
* Increased Fortified Tesla Turrets cap sizing to the same as normal 'small' Turrets. Reduced health by 40%.
 +
** Cap health is the same, cap damage is up 66%, but in the hands of the AI they are easier to kill (who don't get any more or less from current).
 +
 
 +
==== Aggro Invisiblity, And Drones In General ====
 +
 
 +
* Added a new cannot_target_or_alert_ai_reinforcement_spots option for ships, which provides the following new ability:
 +
** AGGRO-INVISIBLE: Enemy target ships and structures (mainly guard posts) that contain guards cannot detect this ship, and this ship cannot fire upon those targets.
 +
*** Once those targets have been alerted and have released their guards to fight, those targets can then be attacked by this ship.
 +
** Thanks to Strategic Sage and zeus for inspiring this addition.
 +
 
 +
* The new Aggro Invisiblity ability has been given to all of the sniper ship variants, sentinel gunboat variants, sniper frigate variants, sniper guardian variants, and sniper turret variants.
 +
** This prevents them from engaging guard posts and similar unless those guard posts are already aggro'd, and thus not alerting an entire planet just because you bring them along.
 +
** Why have this on the guardians?  Mostly for AI Civil Wars, but also in case you capture some.
 +
** Why on turrets?  Mainly for purposes of beachheads.
 +
** Thanks to Zoreiss, AnnoyingOrange, Asteroid, Fluffiest, and others for reporting.
 +
 
 +
* The various drones that had been switched over to the "drone gun" format as of a few weeks ago have been returned to the regular drone behavior.
 +
** Thanks to discussion with Strategic Sage for letting us know how much the new format was not great.
 +
 
 +
* Pretty much all drones use the new Aggo Invisibility ability.
 +
** They can still go hit things right next to guard posts without causing an issue, and they can even hit guard posts that have already emptied their guards.
 +
** Guard posts can even still shoot at these drones if the guard post has any weapons, though the drones can't shoot back until the guard post is aggro'd by something else.  These drones would not bother going near the guard post unless there was something else there to shoot, though.
 +
** Thanks to Puffin for helping set all this up.
 +
 
 +
== Beta 2.642 Nearing Beta For Multiplayer ==
 +
(Released November 30th, 2020)
 +
 
 +
* Fix a bug where the Incoming Exo Notifier would show the wrong % when it was sync'd with something
 +
** Thanks to afterthought for reporting
 +
 
 +
* The Metal Flow Planning screen works again
 +
** Thanks to Crabby for reporting
 +
 
 +
* Scrapping an MDC or GCA now correctly triggers the AIP increase
 +
** Previously if an MDC was about to be killed, you could scrap it to dodge the AIP increase
 +
 
 +
* The tooltips for savegames in the save and load menu now includes what players are in the game in question (with that colorized), and also includes what size the savegame is on disk.  The former is particularly useful when you're trying to remember which games you were playing with what other players.
 +
** We also shifted how we are finding the last write time for each file, which hits windows security less hard and thus makes opening the load game menu vastly faster when there are a bunch of files on windows in particular.  This may also be somewhat faster on linux and OSX, but on windows in particular if you had dozens or hundreds of savegames, it could take a second or two to even open that window.
 +
 
 +
* The way that error windows appear has been updated to be a lot more legible, as well as a LOT more dramatic and scary-looking.  Wow that's a lot of red!
 +
** This was one of the last parts of the game that was not just in AN old UI style, but in the old UI style from the first prototypes back in 2016.  Go figure.
 +
 
 +
* There is a secondary error message window now, which is used when you try to load a savegame or quickstart or do something in the lobby or joining a new game and have some sort of error doing those things.
 +
** Those errors tend not to be fatal, and also tend not to repeat infinitely, and so it gives you a simple "ok" button that you can use to close the error and which then clears the history of how many errors have happened this game.
 +
** In recent versions of the game, you could try to load one broken save, get a message saying it's broken, then load a valid save and have a permanent blot on your UI saying that there were something like 2 errors since you started the game.  Now that doesn't happen.
 +
 
 +
* The metadata for savegames is now loaded asynchronously, except for its file size and last modified date.  The actual rest of things that are shown in the tooltip data is loaded very fast, but not on the main thread.  This means that the load menu opens even faster, on any OS.
 +
 
 +
=== AI Intelligence Improvements ===
 +
 
 +
* Fix a bug where fireteams going after MDCs could get hung up on not wanting to attack planets between the MDC and the Hunter.
 +
** Hunter ships required to go  after a particular target (like an MDC) are now allowed to explicitly attack planets on the way
 +
*** Thanks to ArnaudB for reporting
 +
 
 +
* Tsunami CPAs will now wait a minute or so after launching to gather their forces before they attack. The goal is to make the initial CPA punch a bit stronger; previously they were trickling their forces in piecemeal and not providing as much of an impact as desired.
 +
** It will still look just like the same behaviour to the player once the attack starts, there will just be a bit of a pause between the CPA spawning its ships and then those ships actually hitting your planets.
 +
 
 +
=== New PKIDs Approach For Multiplayer ===
 +
 
 +
* '''WARNING TO MODDERS!'''  We don't suggest you just do a global search and replace for your various places in the code that are now calling methods marked as obsolete.
 +
** As tedious as it is, you should go through those line-by-line and swap them over to the new non-obsolete variant, which will note that it returns null in MP.
 +
** With all of these calls, it's up to you to check to make sure that if the method you just called returns null, you ignore whatever happens next.
 +
** In general, if there's anything that is changing more data about the entity that was just created only-on-the-server-but-null-on-the-client, then have it skip that logic, but do all the rest of the logic.  A general return out of the method you are in is not usually the desired approach (but it does vary by situation).
 +
** The faction data will catch up on the client either way, and all of those changes you make to the entity after the null-return-point will be passed over to the client as well.  However, if you don't handle the null-return-point, then players will get nullref exceptions in your mod only in multiplayer, which will be frustrating for everybody.
 +
** The one exception is CreateNew_DuringMapgen.  You can just search and replace for that with CreateNew_ReturnNullIfMPClient unless you were using it wrong to begin with.
 +
** There may be entire methods now where you want to check if ArcenNetworkAuthority.DesiredStatus == DesiredMultiplayerStatus.Client and just return before it even thinks about making any entities.  See things like ReactToPowerLevel() on the AI for examples.
 +
** TLDR: This is a minor pain in the rear right now, and looks a bit tedious to do.  But this is far simpler and far less tedious than getting bug reports from MP players that you have to chase down for your mod in the future.
 +
*** If you wind up with questions, then @ chris on the Arcen discord channel.
 +
 
 +
* Added a rather complex new ArcenDelayedDeserializationBurst class, which uses a really efficient way to store network message for future deserialization.
 +
** We normally reuse our deserialization buffers, so it's an extra delicate class.  As long as nobody ever tries to use this in some new way beyond the way it is currently used, all will be well.  The code is filled with dire warnings in the comments.
 +
** The capability that this adds is essentially for us to have slightly time-delayed execution of network data unpacking from the host to clients, if the host is a bit more than 1 sim frame ahead of the client.
 +
 
 +
* The MayCreateEntities bool has been marked as obsolete, and is never set now, as all threads (even long-range planning ones) are now considered A-OK for immedidately creating entities as much as players want to.
 +
 
 +
* SpawnEntity and SpawnEntityOrReturnNull have both been marked as obsolete (and will block modders from compiling against them), but will still for the moment keep working with existing compiled mods.
 +
** This is how we're going to try from now on to handle when we change the specifications of things that would break mods, where we can.  It gives modders a chance to catch up.
 +
** In this case, it now wants you to use the new SpawnEntity_ReturnNullIfMPClient() method.
 +
** The same is true for the various CreateSquad methods, all of which now want you to use CreateNew_ReturnNullIfMPClient.
 +
 
 +
* GlobalLastSquadIDSourcePrimaryKeyID no longer exists in savegames.
 +
 
 +
* The ability to generate PKIDs for speed groups, fleets, squads, shots, and otherIDs are all now exclusively host abilities.
 +
** If a client tries to call these, it now returns -1 for the client and throws a visible error message on the client.
 +
** A bunch of cases where we were syncing these over to the clients are removed.  We no longer care, for the most part.
 +
 
 +
* The game now has a new "Fast Blast of Created Objects" that the host sends to clients.
 +
** In these cases, essentially when you go and try to create something that requires a PKID that would be consistent on the clients and the host, the clients just skip doing it, but the host does it and then sends it to the clients asap.
 +
** The host is usually a few hundred ms ahead of the client at minimum, and so if it's on a future frame number from them, then it tells them at which frame to unpack its new data.
 +
*** If the client is closer to the host in time, and the frame gets there late, it still just unpacks it and can sort out minor discrepancies later.
 +
** The idea here is that a LOT more things are just being done on the host, and skipped on the client, and the client is getting the information in small download packages that it inserts into its own sim at the appropriate time.
 +
*** There is some very slight divergence in sync caused by this, but it's pretty darn slight in most cases.
 +
*** The great news is that this uses less network data, and substantially less CPU power, on clients than having wrong IDs assigned does.  This lets us just send the correct object once, rather than creating the wrong object, discovering it, requesting a fix, getting the correct object, and deleting the wrong object.
 +
** This is a fundamentally different approach to object creation, and in some ways this has a bit more in common with an MMO architecture, except things are faster and more responsive than your average MMO.  But this is now blending a third general model of network code into our existing interesting stew of models.  It pairs really well with the other bits.
 +
 
 +
* On GameCommands, we now have the ability to specify how many entities of various sorts we plan on creating (or potentially creating), and then the host provides available IDs that will be consistent on the client and the host before the execution happens.
 +
** This is yet ANOTHER approach, but is one of those cases where we take the most efficient networking approach for any given type of data event.  That is surprisingly optimal, it turns out.
 +
** The idea is that which networking model is superior is really contextual, so we look at the context and use the best one in any given circumstance.  Any errors we make are already handled by the sync code (that's not new), but this cuts down on the number of errors.
 +
 
 +
* Added a new "Log Decoded Network 'Fast Blast' Sync Data To Disk" setting to the network section, which does what it says on the tin.
 +
 
 +
* The way that shots appear, and the way that shot sound effects are triggered, have both been updated in order to support the new way things function in multiplayer.
 +
** We were looking in particular for silent shots, or shots that did not show things like their AOE effects.  Those are all working.
 +
 
 +
=== Other Multiplayer Miscellany ===
 +
 
 +
* Unrelated to the rest of this, the clients now send their GameCommands completely separately from their "finished a sim frame" messages.
 +
** This lets the client send the GameCommands in a more timely fashion, thus reducing command lag on the clients.
 +
 
 +
* Fixed an issue that we don't think anyone hit, but where if you were playing one multiplayer game and moved to another one it could execute some commands from the prior game on a delay.
 +
 
 +
* Fixed a wide array of minor glitches and annoyances that would give clients warnings or errors (visible or otherwise) in multiplayer.
 +
 
 +
* A lot of classes serialize themselves more clearly, ranging from shots to wormholes to gamecommands and beyond.
 +
 
 +
* In the event that the host sends over world data that errors, the client should now wind up back on the main menu.
 +
 
 +
* Fixed a number of small serialization issues between multiplayer, including errors when new planets are created.  The creation of new planets and their various links between one another are now verified to work properly between the client and host.  Aka the Dark Zenith invasion in DLC2 (spoiler alert, though that doesn't tell you much).
 +
** We have NOT yet verified if nomad planets work properly in multiplayer now (displaying properly on clients to match the host), and would appreciate if someone checks that out once this build becomes public.
 +
 
 +
== Version 2.638 Why Do We Fall, Master Wayne? ==
 +
(Released November 25th, 2020)
 +
 
 +
* strength_multiplier_for_turrets has been 2 since we added this, but that seems to overestimate their power a bit.
 +
** We've adjusted this value to 1.55, per discussion on discord and a suggestion by TechSY730.
 +
 
 +
* Added a new strength_multiplier_for_armed_guard_posts, which lets us adjust up the strength of guard posts to be more accurate if it seems to be undervalued.
 +
** We're starting this off at 1.25.
 +
** Thanks to TechSY730 for suggesting.
 +
 
 +
* We also added a new strength_multiplier_for_non_combatants, which lets us adjust down the strength of anything that doesn't have any guns.
 +
** Sometimes things without guns still have a lot of health and shields, and that's really not something we want to consider as strongly since it can't hurt you directly.
 +
** This would affect forcefields, any sort of captured buildings, and things like unarmed transports.
 +
** We're starting this at 0.4.
 +
 
 +
* A new balance_seconds_after_transport_change_before_can_switch_back has been added, with default value of 3, that prevents players from putting ships into and out of the same transport more frequently than within 3 seconds.
 +
** In multiplayer, we need a small bit of time to refill the list of pooled IDs for upcoming player transports.  In reality that only takes a second or two to refill, but potentially less than a quarter second.
 +
** Originally we had thought to have this be an even larger window, like 30 seconds to prevent players from messing with the AI by popping in and out of transports, but there's already a 5 second no-firing time limit that covers that.  And folks on discord made their feelings about that change pretty clear (it was not welcome).
 +
 
 +
* Home forcefield generators can now be scrapped just like all other FF generators.  From back in the pre-fleet days they were not scrappable because at the time you could never then rebuild them.  Now you should be able to rebuild them, so you can also scrap them.
 +
** Thanks to Democracy for reporting.
 +
 
 +
* Updated AMU
 +
** Now uses all the new Icons for Metal, Energy, Hacking, Science and Strength
 +
** Removed the SimpleStringBuffer as it is now less efficient compared to the ArcenCharacterBuffer and ArcenDoubleCharacterBuffer
 +
** Gave the latter two 35 new functions, most of them adaptions from the SSB or shortcuts from formating inside the AMU Core
 +
** Thanks to NR SirLimbo for adding.
 +
 
 +
* Updated Kaizers Marauders
 +
** Tooltips, based on the above logic, are now faster and produce less GC Churn
 +
** Also dynamically rounded the percentages in the outpost description to show up to, but not always 3 decimals
 +
** Removed an extra line inside the Player-Owned Kaizer full descriptions.
 +
** Thanks to NR SirLimbo for adding.
 +
 
 +
* When a stack dies and is going to spawn something on death (such as hydra heads as one example), then the new things that are created come out pre-stacked in the same ratios as the original.
 +
** So for instance, if a stack of 3 is vaporized, then a stack of 3 heads is created.  If each should create 2 heads on death, then 2 stacks of 3 heads are created.
 +
** This is a lot kinder to the CPU and performance in general during heavy death situations with hydras aand similar.
 +
 
 +
* Before you can start hack, the game checks that you have enough hacking points. This check now also counts active hacks.
 +
** The goal is to make it harder for players to wind up with negative hacking points.
 +
*** Thanks to ultamashot and NRSirLimbo for reporting
 +
 
 +
* A ship in an exogalactic strikeforce now shows "Exogalactic Strikeforce" instead of its faction name when hovered over
 +
** Previously it was really hard to tell if a unit was in an Exo or not.
 +
 
 +
* Rework the way Exogalactic War Unit spawn locations are chosen to prevent the case where the AI was accumulating large numbers of Exogalactic War Units on its homeworld, if they were required to go after factions with other things in the way.
 +
** If the War Unit is against the player, the war unit spawns at the AI homeworld.
 +
** If it is against a non-player faction then if there's a safe path for the war unit to get to the target faction from the AI homeworld, it will spawn at the homeworld.
 +
** If not it tries to find any warp gate with a safe path to the target.
 +
** If it can't find a safe path at all then it will spawn directly on a suitable target. Minimally tested but seems to work
 +
** Only applies to newly spawned Exogalactic War Units
 +
*** Thanks to a number of people for pointing out that Exogalactic War Units could get stuck, most recently zharmad and ArnaudB
 +
 
 +
* Since we are not actually using the SquadIDSources, it makes sense to provide older methods that the various code mods like Civilian Industries were looking for.  StarKelp is not able to update that this week anyhow, so we made some changes to make sure that his stuff still is compatible with the new version of the game anyhow.  So far as we can tell, Civilian Industries seems to work again.
 +
 
 +
=== Bugfixes ===
 +
 
 +
* Improved the error handling on incoming_damage_modifier to be more clear.
 +
** Thanks to NR SirLimbo for reporting.
 +
 
 +
* Fixed an exception where any damage modifiers that were hull only would throw an exception when you tried to apply them.
 +
** Thanks to NR SirLimbo for reporting.
 +
 
 +
* Fixed an unusual error that was possible to happen in ReinforceSpecificPlanet().  Not sure why this was happening, but there's a vague chance it may have been related to mods.  At any rate, it's no longer possible to get the exception.
 +
** Thanks to Isiel for reporting.
 +
 
 +
* Fixed an issue where cluster bombs would not spawn more bombs because they were not dying from enemy fire.  Now the only reason that sub-bombs won't be created from things like this is from a unit intentionally being scrapped.
 +
** Thanks to Puffin for figuring out what this problem was, and to ArnaudB, Isiel, and Democracy for reporting.
 +
 
 +
* Fixed an issue with the name generation for multi-owner factions so that it now properly says the names of the multiple owners.  Previously, each party was incorrectly just seeing their own name as the owner.  Of course, in these situations it's best of all to give your empire a specific name, but you don't have to.
 +
 
 +
* Spire cities should now work if they are on planets owned by other Players
 +
** Reported by NeverZero
 +
 
 +
=== Improvements To Error Handling ===
 +
 
 +
* Put in a bunch of wrapper methods for various faction methods that are commonly used by mod factions.  These wrapper methods let us gracefully catch exceptions from the mods and then disable that part of the modded faction so that the game can continue without you having an endless spiral of exceptions.
 +
** For instance, in this build of the game we have broken both Kaiser's Marauders, the AMU, and Civilian Industries.  Rather than having those be absolutely unplayable savegames with infinitely logging errors, it now pops up some errors the first time, then shuts off the brains of those particular factions.  So you'll see those factions stop working and just kind of sit around (or use whatever intelligence there is that is coming from the central NPC logic), but the savegame itself won't be a total loss.
 +
** It's still best to stop playing after you have exceptions like these, but it doesn't make you completely dead in the water.
 +
** We also implemented a neat new thing where we are able to detect even caught exceptions inside these methods, so if the mod author is doing their own error handling, we still find out about the error and shut off that faction.
 +
** It's worth noting that this applies to base game and expansion factions just as much as it does to mods, frankly.  In general this is pretty handy for letting parts of the game essentially have a stroke and die without turning off the rest of the game or leading to endless errors that cause lag.
 +
 
 +
* In the list of factions in the escape menu, if a faction has had any sort of fatal error, it now shows "FATAL ERROR IN FACTION" next to it, with animated red and orange colors going past.
 +
 
 +
* Whenever you have an error message popup, it's only showing you the most recent error out of potentially a long series of errors.  Now the game has a first line there that is "Errors since start," and that counts up as more errors are logged.  It may count up while you're reading an exception, for that matter.
 +
** The idea is to make it so that people don't just see the last error and think that's it.
 +
 
 +
* If you have had an exception happen in your game in the last 5-10 seconds, then it now shows the count of errors since the start in the chat sidebar.  This way you can't miss the fact that errors have been happening recently, and if you're in the unfortunate situation of having ongoing errors every few seconds then you will see that counting up and be aware of it.  Sometimes people would hit "ignore all" and not realize why their disk was still being slammed by errors, and the fact that things were probably not working quite right.  Now it will be impossible to miss.
 +
 
 +
* Similarly, if any factions that have partially shut down from having errors, it now has a count that just won't go away up in the chat area that says "Factions Shut Down From Fatal Errors: 3" or whatever the number is.  This is not so obtrusive that you can't keep playing, but it's obtrusive enough that maybe you'll realize you should stop playing if you care about those factions doing anything.
 +
 
 +
=== Failed Experiment: PKID Generation Revisions For MP Client Smoothness ===
 +
 
 +
* An older approach that we were going to take with Primary keys, with a new PKID struct and a PKIDGenerator class, has been stripped out.  It was going to be too unwieldly to implement, and would have made filesizes and network data a bit larger.  We have come up with a better approach since coding that.  It was never used, but the plan was to use that to keep multiplayer sync in better shape.
 +
 
 +
* We only care about PKIDs for squads in terms of where things are diverging so much, so we've got a new SquadIDSource class.
 +
** The squad creation methods (in the codebase, "squads" are all ships and buildings and units) now mostly require a SquadIDSource to be passed in.
 +
** These sources keep some certain number of "for future use" PKIDs either for the faction or some other scope, and usually for some sort of sub-purpose on a faction.
 +
** These are serialized to disk and across the network, and every sim step have their pools replenished and synced over to other players from the host.
 +
** In the event that a source has run out of IDs to distribute, it has a fallback source which is usually the "failover" pool of IDs on the faction in question.
 +
*** This first level of failover means that it is more likely to not have collisions when trying to find something to fill in for a source that was too thinly populated at the time of being called. 
 +
**** A single faction is more likely to mostly be synchronous relative to itself in terms of actions, so desyncs between clients are less likely.
 +
**** But additionally, even if it is a desync, it winds up limiting the scope of the cascade of desyncs to mostly be limited to that one faction rather than affecting many factions all at once.
 +
** In the event that the failover has ALSO run out of IDs to distribute, then it goes back to the main central ID generator that has always been used up until now. 
 +
*** This is almost certainly going to cause a minor desync, or several minor ones, in multiplayer.  However, these are going to be corrected by the same process that currently corrects multiplayer and makes it work as smoothly as it does.
 +
*** Right now, MP clients are seeing things like every new ship that is spawned getting duplicated and then recreated, or just shifting spots.  This is annoying in terms of how constant it is, but overall even with it having a desync EVERY time something is created, it's not that in-your-face that you can't play just fine.
 +
*** So at any rate, there are multiple levels of prevention aimed at stopping this in the first place, but when it does happen it's not the end of the world and the game just recovers and keeps going like it has in all the MP versions prior to now.
 +
** The goal with all of this is to make things more smooth for clients, particularly when they are building ships from a factory or placing turrets and similar directly.  And a secondary goal is to reduce some extra sync fix network traffic.  But in the grand scheme, long-term sync is already assured by all the other characteristics of our multiplayer engine.
 +
 
 +
* To support the new SquadIDSource class, there are a wide variety of sources that are placed throughout the codebase for various purposes.
 +
** As noted, all of the CreateSquad() and SpawnSquad() methods now require a SquadIDSource to be passed in, but if you don't then they will work out how best to get an ID to work around that lack.
 +
** However, for modders and faction coders, the way to update your code is relatively straightforward.
 +
*** If you are doing something in the "long range planning" that creates a squad directly, just know that you're already immediately creating a desync, since that only runs on the host.
 +
**** The game will recover from this automatically, but it will be wrong on the client with these new units you just created for 1-5 seconds, and may be wrong with some other units created around the same time.  So ideally don't do that.
 +
*** If you are creating squads directly in the "stage 2 or 3" methods, then you will now want to almost always use CreateNew_ForFactionBackgroundGeneration().
 +
**** That method gets its own SquadIDSource inside itself, and there are loads of queued IDs in that source, so your risk of causing any desyncs at all with this is remarkably low.  And if any do happen, it's probably not going to bleed over to something the player notices very easily.
 +
**** There is also a version on faction that is SpawnNewUnit_ForFactionBackgroundGeneration() that takes the place of what was SpawnNewUnit() before.
 +
*** If you are creating squads during part of mapgen, such as initial seeding logic for instance, then you should use the CreateNew_DuringMapgen() method.
 +
**** This method entirely bypasses the SquadIDSource class, and just generates IDs directly.  Mapgen only happens on the host, prior to syncing to everyone else, so there's no need for those sort of ID queues there.
 +
**** If you mess up and have a method that uses CreateNew_DuringMapgen() both during mapgen and after mapgen, then you've probably introduced a minor desync with whatever is created, but again it's something the game will auto-correct within 1-5 seconds.  The good news is that it should not really affect any other units than the ones you used this way.
 +
**** Conversely, if you mess up and use CreateNew_ForFactionBackgroundGeneration() or similar during mapgen, then it will just do things as normal with not even any slight ill effects.
 +
 
 +
* In single player and multiplayer, you can now see the ID stores and the statistics about the ID usage in the memory pooling section of the escape menu.
 +
** All savegames are a bit bigger now, maybe about 100kb or so.  It's a fairly small addition in general, but in one example save we have an extra 65 thousand IDs pre-generated for use in specific scenarios.  We can see even in a single-player game if it's ever hitting the central stores, etc.
 +
** You might wonder why we are also using this in single-player, but in general this does not cause a performance hit, and we have always tended to do everything the same between single and multiplayer even if that's not strictly required, so that we could maintain as few differences and as consistent of performance as possible.
 +
 
 +
* The PKID Sources are now fully synced over the network in multiplayer, and they are centrally stored for reuse and assignment within savegame and across the network.
 +
 
 +
==== The Actual Result, With Intriguing Data ====
 +
 
 +
* For now, after all the immense amount of work to get SquadIDSources working (and the two days after it to figure out the one-line networking error --which wound up having us greatly expand a bunch of debugging tools for multiplayer in general at least), we're currently choosing not to bother filling the SquadIDSource objects at all.
 +
** With this in place, they wind up adding an incredibly minor amount of overhead, but no actual functionality.
 +
** The fundamental premise of these is to try to reduce collisions of PKIDs between the clients and the host by having them queued up and ready to go, but that... really doesn't seem to happen.  There are too many things in motion constantly, perhaps?  It's honestly kind of hard to say exactly why this doesn't work, at the moment.
 +
*** The most obvious answer is that the timing is too tight, but the Sources being filled with a certain number of values in advance really should be working around that.  So that would seem to indicate that maybe there's some secondary problem, like the order of the queues getting messed up during sync, or something like that.
 +
*** A more subtle answer, which is probably the correct one, is that we have two different timescales of network communications.  On the one hand, we have the network sync info, which gets applied immediately.  On the other, we have GameCommands, which get applied 100-200ms later.  It's seeming likely that the sync of the queues is removing key entries from the client before the client can actually make use of them, since the client may be on a 100ish ms lag from the host.  This could be solved in a variety of ways, but would need more testing.
 +
*** However, seeing these in practice, the savegame sizes go up dramatically, and there is a notable slowdown in performance on the clients, which we didn't really expect.  Part of it just has to do with how many factions can be in the game, particularly factions that are minor-use or only have a few units in them (tamed macrophage, etc, which may not even be active).  This whole thing adds a definite per-faction extra cost in terms of data usage, and running out predictions for a long games is fine... but doesn't really feel great.  What's notable is that turning this off feels like a breath of fresh air in terms of performance immediately after, so that says something right there about how advisable this is.  Is this worth fixing?
 +
*** Deciding if this is worth fixing or not is not something we want to decide late at night after three very frustrating days of staring at this and related problems, so for now we're just leaving it empty and pushing out this release so that folks can have the many many other fixes that we put in this build.  This build has been delayed long enough by this blasted feature.
 +
*** If this particular approach for PKIDs isn't used, then what do we do?  Well, there are a variety of options.
 +
**** On the one hand, we could do nothing.  The sync code already corrects divergences, and is doing so with a minimum of bandwidth and no extra savegame file size, etc.  However, it does cause minor jitter on new ships on the clients, which we don't like.  So that' not our first choice.  It seems like a lot of people don't notice this much, but at the very least for directly-placed human ships we can do better.
 +
**** So, on that note, we can adjust the way that units are created.  Right now, there are many places where the simulation creates a unit, and it tries to do that in lockstep on the clients and the host.  This... may simply be not the way to go.  We've contemplated this before, for a long time in fact.  It may be a lot more tenable to make it so that the "create unit" code actually only runs on the host, and then that data gets synced over to the clients asap.
 +
***** Originally this was something we had discarded because it would require a huge refactoring of all of the code for all of the external factions and mods.  Not just a search-and-replace sort of change, but a really deep dive shift in the creation of all units.  That is highly undesirable for many reasons.  One of the reasons is that it would negatively affect the feel of the game on the host, and in single-player, because in theory we would be creating new units via GameCommand, which is something that happens on a delay.
 +
***** The thing is, creating units only on the host doesn't mean it has to happen in a GameCommand.  Actually one of the things that this entire code branch with the sources has demonstrated is how VERY fast we are able to get information over to the client.  Normally we want to have new things get created and sent to clients via GameCommands in an orderly fashion as part of the main sim loop... but the thing is, the sync code is really freaking good.  In almost all cases, if the ships actually appear 100-200ms early on clients, that matters... why?  In reality, it doesn't seem like it matters much at all.  If that causes a minor desync, it's still far more minor than the desync that we're getting right now with units having wildly wrong PKIDS.  Likely their position or other stats would be slightly off on the client, and that is REALLY trivial to fix within seconds, and happens automatically already.
 +
***** Overall, even though the PKID Sources approach was a complete dead end (probably) in a direct sense, this does provide some ways that we could theoretically reduce sync errors when it comes to even things like shots, which we've been concerned about for a while with IncomingShots being off since we don't consider shots worthy of sync (they last too short a time).  But if we used the back channel data to generate shots only on the host, and had those synced to the client only once, on creation, that might be very interesting indeed.  One of the possibilities with shots and even units is that we add a new SimFrameStartedExisting or something to that effect, and if that's in the future then the client just keeps them as invisible and not part of the client sim just yet.  That would allow the host to give early "hints" to clients, who then have data ready to go as soon as the appropriate sim frame rolls around.  Heck -- the clients don't even have to have fancy new logic for holding those units in abeyance.  They could simply keep the data in its packed form until the appropriate frame.  This would be very lightweight.
 +
***** Ironically, this even paints some ways in which the "only create ships from gamecommands" approach of the "long term planning" code that is host-only is something that we might need to do away with.  That would make things a bit simpler on modders if we go that way, and it would even allow us to in theory shift some of the per-faction processing onto non-sim-blocking threads.  The only reason that those need to be sim-blocking right now is in order to maintain sync in multiplayer.  But the thing is, we never expected for the general baseline sync to be this good... or for there to be such an effective faster-than-sim backchannel for the host to shuffle data over to the client.  Despite this being our third coded multiplayer model over the span of 7ish released multiplayer games, this one really takes the cake for being the most advanced, and it has revealed some interesting new avenues to consider.
 +
** So the bottom line is, at first this really felt like a huge waste of time, on top of being a monumental disappointment.  After taking a break for an hour or so and putting my kids to bed and thinking about it some more... this is actually pretty interesting data, and suggests that we may be able to be even more "fast and loose" with things than I ever expected, and thus really take the potential worry away from modders and faction designers, lower the network load, keep the savegame sizes small, and still improve sync.  Having the host be fully authoritative over PKIDs was not something that seemed like it would be possible without introducing input lag on both the client and the host... but we already have the most minute (100-200ms) of timing lags between the client and the host, so that actually opens up a ton of options.
 +
*** Crazy sidebar?  One of the things that particularly bugs me about playing multiplayer right now, as the client, is the input lag.  There's a lot of strictness that we have going on with trying to keep the client close to the host in timing, and making sure that GameCommands are executed at just the correct timestamps in the correct order, etc.  But what if... we didn't care?  Why not let the client instantly ask the host for things, and the host instantly execute them, and tell the client to also do the same?  Sure it would introduce some new timing inconsistencies, but... so what? 
 +
*** Also crazy, still sidebar?  This is even a way to potentially get around dropped packets and other situations with high latency or high ping.  Let the host just get ahead, who cares, have the client blunder on without permission and catch up with what the host wants in a few hundred ms after the network blockage has cleared.  This pulls the game further and further away from even pretending to be a lockstep multiplayer model, but to be frank, the performance that we're seeing, that we're able to get, is what makes that a feasible thing.
 +
*** Want to stay in crazy sidebars?  Things like FInt, our fixed-integer math struct and its related code, could largely be removed from the frequent sim calculations.  There are some MUCH faster floating-point math functions, several of which use SIMD, that we use right now only for non-sim purposes.  But it's already clear that the amount of drift we see in a few seconds is next to nil, and we're syncing things so frequently that any real drift that mattered would be correct within seconds, and typically would be smoothed out by the very awesome lerping that the vis layer does to keep things smooth in general.
 +
** So... yeah.  This experiment was a huge disaster, on the surface.  On the other hand, it took me through every piece of the code that creates units at the moment, and gave me an enormous amount of data on how some of the data is able to be passed around faster than game commands.  I will need to weigh my options carefully, and probably focus on gradual improvements over time since the baseline is already pretty good right now.  But making things more host-driven ought to be one easy quick improvement for sometime very soon.
  
* Allow clients to assign themselves (or be assigned) to player factions.
+
=== More Multiplayer Technical Work ===
** As many clients can share a faction as want to, no problem.
 
  
* Add ability to name factions, separate from the name of the player controlling them (since it can be controlled by several players)
+
* Removed some debug lines on the network clients about wrong key syncs (which always showed as zero because we wound up never deciding to check for that).
 +
** The adaptive system for sync that has continued to evolve out of seeing real data basically made that irrelevant.
  
==== Before Alpha ====
+
* The new sync of the PKID sources is now split out into its own separate sync cycle (for time slicing purposes mainly), separate from the faction sync.
 +
** Also separated out the "external data" of factions rather than having that be in the "Faction basics" sync.
  
* 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.
+
* The "Show Network Sync Details In Escape Menu" option in networking has been moved to the top of the other networking features, as it is the most helpful one by far.
 +
** It has also been given the prefix "Helpful: ".
  
* Get GOG integrated as a networking framework, now that things are working on LiteNet and Steam.
+
* Added another new setting to the network section, as well: Log Decoded Network Faction Basics Sync Data To Disk
** This will be a moderate challenge, because GOG has a different API from either of the other two. Right now the main thing we are waiting to hear back on is fragmentation and recombination logic, which we hear is in there, but that we don't see how to use yet.
+
** Description: Same as the 'Log All Decoded Network Sync Data To Disk' setting, but only writes data for the faction basics that are periodically synced. If something gets awry with that data, this is a way to figure out why there's a discrepancy.
  
* V1 of the desync detection and correction code, which should probably only take a few days.
+
* Multiplayer sync messages are now numbered by the host, and the clients read the number out when they get the message.  This way, if a host sends out a sync message prior to a client joining, or a client misses a message or whatever else happens, the logs will still match  up on both ends and are something we can compare.
 +
** We were running into the baffling situation where the logs did not match in ways that should be impossible, but this was because the clients and host were being allowed to number their own messages independently.
  
==== Before Beta ====
+
* ArcenExternalData-RowIndexNonSim is no longer logged in general, because it is specifically something that is non-sim and thus will be different on the clients and the host.  The matching isn't done based on it, so it's not a part of sync that matters.
  
* 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.
+
* We slightly reduced the maximum fragment size that we're willing to send, from 512kb to 500kb, still minus 100 bytes in both cases.
 +
** We had one report of a user on Steam getting an exception when trying to connect with the prior limit and the new limit does not make much practical difference to anyone else.
 +
** Specifically it complained about 524,199 bytes, when 512kb is actually 524,288 bytes; with the new limit of 500kb, that is coincidentally 512,000 bytes, which is potentially the actual accidental number of casual-math bytes that Valve actually is limiting to.  We thought we remembered seeing in their code that it was 512 * 1024 that they defined their limiter as, but nonetheless that was only in a header file and so the internals might be defined differently.
 +
** Thanks to NRSirLimbo and CRZgatecrusher for reporting.
  
* Make the desync detection and correction able to correct factions, not just ships.
+
* Fragmented error messages now give more informative error messages when something is off.
 +
** It's now vastly more common for savegames to be over the limit, since we now have all the pre-caching of PKIDs.  One small 275kb savegame changes to 527kb in the new version.
 +
** Good thing we spent so much time on data efficiency earlier this year, because we really require an abundance of extra data to make sure PKIDs come out nicely between the client and the host.
  
* The really big one that remains is making sure that the cross-machine identifiers (PrimaryKeyIDs) are consistent between machines. I don't fully have this figured out yet, but I think that the interim state of it will essentially be that there are occasionally too many messages being passed around because of rolling sync errors. I will probably punt this issue into something I look at during the alpha, so that I can gauge what sort of impact it really has on performance, and where the problems are coming from.
+
* Completely re-wrote our custom packet fragmentation-and-reassembly code.  It's more efficient on the client now in general, and works properly.
 +
** We've tested this with a maximum allowance of 50kb  so that it fragments a variety of messages rather than just the initial savegame. It was all working well, now, so we've gone back to 500kb.
 +
** It turns out that, previously, we had an accidental game of Russian Roulette going.  Depending on what bit the last of the fragment header ended on in its final byte, it might automatically advance to the next byte on its own.  That gave it a 1 in 8 chance of dying on a fragment by skipping one random byte of data.  That's no longer possible, but took us forever to track down.
  
* Make sure that the lobby fully works as we expect, and various other small UI systems to get multiplayer basically playable. A lot of work went into the lobby in particular in the last few months to make that as close to as ready to go as possible.
+
* ArcenSerializationTester, which was used as a single static-style class, has been removed.
 +
** Because of its static-class nature, it was not threadsafe, and we could not guarantee that we were not having mixed serializations or deserializations in one batch.
 +
** As part of this, we have replaced it with a new ArcenSerializationLogger class, which lives on actual serialization and deserialization buffers and thus can't be confused across threads.
 +
*** As part of THAT, we are also now making it always write directly to disk, rather than buffering in memory sometimes.  So the settings option "Write Savegame Serialization Logs In Realtime" has been removed, as it is now always true.
 +
** It is worth noting that this method of logging is somewhat less performant, and definitely wastes some RAM, but that's not of relevance to our purposes.  If you have this logging turned on, you're already in a debug mode that is going to have performance that suffers by its very nature.  What we prize most in that situation is accuracy.
 +
** This removes any doubt of any logs getting scrambled by simultaneous writes, or by overlapping requests to log, or things of that nature.
 +
*** As a side effect, if you enable several kinds of overlapping debugging at once, it is possible to get an exception now, but that's better than before where it would just scramble your log happily.
  
==== Before Full Launch ====
+
* Added a new setting to the network section: Log All Decoded Network Data To Disk
 +
** Will massively slow the game down, but dumps ALL messages as they are encored or decoded to the disk in files inside the PlayerData/NetworkSentDecodedData and PlayerData/NetworkReceivedDecodedData folders.  This covers absolutely all data, and includes message headers that other forms of decoded-data logging do not.  With this logging enabled on both the client and host, you can compare the output and see what serialization problems are happening, if there are any.
 +
** This is a last resort sort of debug option!  Since ALL data is being actively decoded as it is written, it is far larger (and in plain text) than the actual data being sent across the network.  A typical ratio might be 40MB of decoded data for 500kb of actual network traffic.  You can have a few GB of data on your disk after just part of a minute of letting the game run in this fashion.
 +
** Warning: do not use with 'Log All Decoded Network Sync Data To Disk' or any of its sub-options also turned on, or you'll get errors.
  
* 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.
+
* The game now sends a unique 64bit messageID with every message from the sender, in sequential order of send, so that the sender and receiver are able to compare notes.
 +
** Full support for understanding the serialization of message headers is also now in place.
  
* 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.
+
* The game is now able to do some temporary buffering of serialization data to write to disk, prior to knowing what the name of the file should be, and then come in later after it has done a bit of deserialization and knows what to name its new message.
  
== What's this phase all about? ==
+
* These new abilities combine to give some really rock-solid and overkill-style logging abilities that let us find bugs that otherwise escape us in the networking code.
 +
 
 +
* After about two days of wanting to tear his eyeballs out trying to find an incomprehensible error, Chris found the single-line typo that he was missing.
 +
** The PKID syncs work fine on clients now when it comes to things like building structures directly, but for most other purposes there are just as many catastrophic mismatches as ever.  Sigh.  This is going to take some doing.
 +
 
 +
== Version 2.637 Threatfleet Conversion, Chat, And Clickable Planets ==
 +
(Released November 21st, 2020)
 +
 
 +
* The game now tracks a new BecameThreatfleetAtGameSecond on each entity.  When it is detected than an AI Sentinels ship is in Threat status (meaning it would show up as Threatfleet), it now logs the current game second so that it remembers how long it has been threat.
 +
 
 +
* Added a new seconds_threat_exists_as_threat_before_joining_hunter_fleet on AI difficulty, which is currently set to 2x seconds_threat_waits_before_joining_hunter_fleet for all AI difficulties.
 +
** This sets a new and absolute timer on how long threat can be threatfleet for the AI Sentinels before getting transfer orders to the Hunter Fleet.
 +
** Previously, based on the other timer, if the AI Sentinels threatfleet is engaged in whatever activities, even if that activity is indecision, then it would never switch to the hunter side.
 +
** This makes it impossible for ultra-long-term threatfleet to remain in the galaxy, unless it is pointed at a non-human faction, or it is of a specific type that can't convert (usurper, overlord phase 2, drones, etc).
 +
** Overall in some edge case savegames, this makes it so that suddenly a bunch of idle threatfleet that was too stupid to figure out your particular empire now gets converted to the far-smarter hunter faction and joins teams dismantling you.
 +
** Thanks to TechSY730, Metrekec, ArnaudB, and Crabby for reporting.
 +
 
 +
* Previously, it was up to the host and the clients individually to tell when the game was won or lost.
 +
** Sometimes there is a tiny bit of a disconnect between an event happening on the client and the host, however, and the client has a part of a second where it might think that you've won.  We're being vague here to avoid spoilers, but it's a pretty common result that would happen at the end of each game.
 +
** At any rate, now the multiplayer host is exclusively in charge of saying when the game has been won or lost, since it never has any missing data even for a part of a second.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* Made a number of changes to the in-game chat textbox to prevent it from capturing your input even after it was closed, thus leading to mysterious sends of extra keys as well as your keybindings in general not working while the capture was in place.
 +
** Thanks to StarKelp, Puffin, Democracy, and Badger for reporting.
 +
 
 +
* Also wound up re-plumbing the entire textbox input pipeline, because there were a number of cases of strange and annoying lag that could happen with them.  So far all the ones we've tested are working great now and are more responsive.  But please do let us know if there's any that are funky for you.
 +
** This could in some cases lead to race-condition-like behaviors, and repeat sends of messages.
 +
** Thanks to Sigma7 for reporting.
 +
 
 +
* Fixed issues where pressing the escape key while in a chat textbox would send the chat rather than erasing it.  This is because of our use of OnEnterOrReturnPressed(), which apparently also fires on escape being pressed.  So now we have left notes in the code to that effect, and use a different method of detecting that enter is pressed to send chats.
 +
** Thanks to Sigma7 for reporting.
 +
 
 +
* Should finally have fixed the super annoying bug where sometimes a planet on the galaxy map is un-clickable.  We did this by making sure that the collider box for the planets is now way taller than anything else, and so things like the links between planets can't accidentally override them.
 +
** On the off chance that somehow the collider was actually being turned off for the planet icon, we actually are now always making sure that is on every frame, too.
 +
** If you were seeing some sort of other tooltip for something but unable to click the planet, and you see the problem again, please let us know what the tooltip is for.  If you were seeing no tooltip at all, then that was probably the collider being disabled in some fashion.  We do turn off the colliders for icons that are supposed to be off, but that should never affect planets.  If it was affecting a planet icon previously, that should no longer affect a planet icon.
 +
** Thanks to Badger, TechSY730, GreatYng, CRCGamer, RedPine, denko, crawlers, Isiel, Cyborg, Asteroid, Kizor, Strategic Sage, and probably others for reporting.
 +
 
 +
== Version 2.636 Text Hotfixes ==
 +
(Released November 21st, 2020)
 +
 
 +
* Shots now visually scale up at 6x the rate they previously did when you are zooming way out from a battle.  This should keep them visible in farther-off battles, while not being so large when closer in.
 +
** They also now only start scaling up after a distance from the camera of 150, rather than 50, and their scale factor subtracts off the original 150 so that there is not a sudden jump in size when you cross that distance threshold.
 +
** Thanks to Badger for suggesting that these be scaled up better.
 +
 
 +
* Fixed a bug in the prior build with how integers and chars were being written using the revised ArcenDoubleCharacterBuffer.  It essentially either made numbers stay stale, or be outright invisible, in a wide variety of situations.  Other times they looked just fine, but it was dependent on exactly how the calling code worked.  From what we can tell, all instances of this are now fixed.
 +
** Thanks to Wuffell, ArnaudB, Daniexpert, TechSY730, Smaug, and Crabby for reporting.
 +
 
 +
* Fixed one other issue with the revised ArcenDoubleCharacterBuffer, where if the next string from the buffer was SUPPOSED to be blank, it would just return its most recent string instead.  So messages that were popping up various places but then should disappear when no longer relevant could not do so.  They could be replaced by a different message, but could not actually just fade to nothing.
 +
** Thanks to Wuffell, ArnaudB, Daniexpert, TechSY730, Smaug, and Crabby for reporting.
 +
 
 +
* If an exception happens in FromServerToClient_PeriodicPlanetFactionSyncDataThatJustOverrides, we should now get far more useful error messages now.
 +
** In this method and in a variety of other network sync methods, it now also checks to see if the galaxy is null, and returns early if that is true.  This basically prevents errors from stray network syncs that are trying to be processed after the game is being disconnected.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
== Version 2.635 AOE Visibility ==
 +
(Released November 20th, 2020)
 +
 
 +
* Some improvements for frigate roll colouring in games created on this patch
 +
** Thanks to Daniexpert for suggesting
 +
 
 +
* Fix a bug where Discoverable factions weren't appearing in the Edit Factions screen
 +
 
 +
* Some minor UI improvements to the Active Metal Flows screen and the Brownout Notification
 +
 
 +
* The descriptions for the AI Reserves unique units now mention they are used to combat player Deepstrikes
 +
 
 +
* Fixed a couple of exceptions that could happen if you were viewing the tooltip for an ship or structure right as you exited the game.  There were probably a few other cases that could also cause this.
 +
** Thanks to Corpserule for reporting.
 +
 
 +
* Majorly reworked how the "time do die now" code paths work for ships and units in general, so that we can more accurately tell them when they should explode or when they should not explode.
 +
** This solves the problems of ships exploding when they are removing one to add itself to a stack, as well as the problem of ships on MP clients exploding as they move to their proper position after a sync error (if the PKID itself was off).
 +
** It is likely that there may be some bugs resulting from this, but fingers crossed nothing too severe after we fix the initial raft of those issues.
 +
 
 +
* The settings for screen edge panning have been moved higher in their respective camera controls sections, and have been renamed slightly to make it clear that it's only for the single camera type, not both cameras.
 +
 
 +
* Fixed an issue (that was probably not new) where when you had the camera low enough that gimbal icons for ships were not showing, those gimbal icons would still show their explosion animation when the ships under them died.  Now you just properly see the explosion animation of the ship itself.
 +
 
 +
* Fixed some minor bugs that may or may not have been present previously with srapping units not always showing them exploding as they do.
 +
 
 +
* The game will now complain if it can't find various materials and such that are used for things like under construction status, etc.  At the moment, nothing complains.
 +
 
 +
* Fixed a very small parser error that was causing AOE effects to not show up at all, ever.  This was introduced a bit ago when we improved the xml parser for modders.
 +
 
 +
* When Autobombs blow up, they now have a flak-style effect that appears around them.
 +
** Same for all of the minefields.
 +
 
 +
* Added a new xml flag, is_okay_with_null_aoe_effect_for_aoe_attack, which is used for the ExplosiveInvisible shot type, aka for Crusher turrets and weapons.
 +
** These are meant to be invisible AOE damage that crushes stuff near them, and so we don't want the (new) "usual" error of "hey there's a missing AOE visual effect when you are doing an AOE attack" to happen.
 +
** Actually, we wound up suppressing the error, because more things were hitting it than expected and it's not worth it.
 +
 
 +
* The flak effects now appear again properly, we can now verify.  This being with grenade launchers most notably.  They're on the small side, but that's somewhat by design so they are not overwhelming the battlefield.
 +
** The tesla effects are also back, but again more thin and more reasonably sized.  We may need to look into scale on these some in the future at some point.
 +
** For the flak effects, they do seem to be strangely crunched down on themselves compared to what we were seeing in our videos, but we'll have to investigate that at some point in the future.
 +
** Thanks to TechSY730, Badger, Isiel, Puffin, and Corpserule for reporting.
 +
 
 +
* Fixed a variety of sync exceptions for multiplayer that would cause duplication of various things on ships:
 +
** The ships granted if they are hackable, etc.
 +
** The amount of damage dealt to ships of various death-types.
 +
** Various data relating to AI reinforcement points (guard posts, etc).  This was not endlessly duplicating, but was causing some funkiness.
 +
** The incoming shots.
 +
** Various things with forcefields protecting a ship.
 +
** Various bits with where an AI ship thinks it is guarding something.
 +
** Any techs that were granted by hacking a ship.
 +
** This should handle all of the cases that people have reported, plus some things that were not visible to people directly.  Please do let us know if you see more of this!
 +
** Thanks to Puffin, Arides, Daniexpert, jrad, SilverLight, and others for reporting.
 +
 
 +
=== More Performance Improvements ===
 +
 
 +
* A new version of our internal ArcenCharacterBuffer has been added, which now wrappers a StringBuilder and uses many of the benefits that has been added to that class over the years.  The performance of adds and updates should be a couple of orders of magnitude better than what we've had up until now, making large interface elements more responsive.
 +
** Though in fairness, we don't use too many ArcenCharacterBuffers, it's mostly another class which will also be updated.
 +
** Thanks to NR SirLimbo for benchmarking all this and figuring out where there were some major slowdowns with this.
 +
 
 +
* A much more substantial performance boost has been achieved by replacing ArcenDoubleCharacterBuffer's internals with a new approach that uses a mix of StringBuilder and our own form of logging of "WrittenValues."
 +
** This makes really long text displays that are continually updated much faster (before they would take you down by 10-20 fps on a fast machine just for viewing them), and that includes really large tooltips.
 +
** This also seems to make the game load a bit faster, and also in general makes the UI generate faster all over the place.  It seems to be around an 8-10 fps bump on a very fast dev machine.  Slower CPUs should get more benefit.
 +
** On the escape menu, under the memory pooling section, there is now a "Texts saved" versus "texts new."  In under 1 minute of just sitting there and moving around a bit, we wind up with values of around 500 new, and 500,000 saved.  That's.. substantial.
 +
** Based on testing by NR SirLimbo, all use cases of this are faster, but in general the average improvement in speed is using 98% less processing power to draw text than we used to (and the processing power was nontrivial).  The load time of the game itself has also improved by at least 2 seconds for most of the faster machines, and maybe more for slower ones.
 +
** Thanks to NR SirLimbo for sparking this line of inquiry.
 +
 
 +
=== Visual Improvements ===
 +
 
 +
* On February 4th, 2020, we had an accidental regression that caused the "ship placement" material, and the under-construction and under-construction-stalled materials to all lose their shaders and some of their textures.  So when we tried to draw units with these visual effects on them in the game, they would just be invisible (icon aside).
 +
** This was during a larger purge of some unused shaders and textures, and had this as an unfortunate casualty.  We've now restored those items, and things from those areas should "just work" again in the next version.
 +
** Thanks to a lot of folks for pointing out that this had gone missing, including RabidSanity and Mckloshiv.
 +
 
 +
* Arcen "Death Chain Effects" have long been used for things like flak hits and tesla attacks.  However, they were entirely scripted and robotic, before.  The only difference between one playback and the next was the rotation of the entire effect.
 +
** We've now added a tremendous amount of randomization in how these play out, including to the position and scale of their sub-components, how fast they move through their animation per explosive, and things of that nature.
 +
** The end result is that we're now able to make a single death chain effect look a bit different every time it plays, for almost no extra processing power, and so the entire battlefield will look way more alive and unique when these things are happening in large numbers.
 +
 
 +
* The shader that we use for our "death effects" for AOE damage, most notably flak explosions and lightning explosions, has been rewritten to use a custom lighting path rather than using surface lighting.
 +
** When we redid our lighting pipeline earlier this year, it unintentionally made all of our death effects of this sort look TERRIBLE. 
 +
*** Essentially, they were showing up for a bit before visually appearing, in kind of a ghostly form, and they were also then showing up a lot more white than they should have been.  This was them interacting with the HDRI reflection cubemaps that are now in the scene.
 +
** The new version of the shader looks better than the old one ever did even pre-lighting-update, and no longer has any of the above issues.
 +
 
 +
* The flak explosions have been completely reworked to the point that they are almost unrecognizable. 
 +
** All we've done is adjust the shaders and the randomization of the chain effect, but this went from an effect that made us cringe to one that we'd love to see in massive quantiles taking out our foes.
 +
 
 +
* Plasma AOE explosions are far simpler than the flak explosions, since they only have one main body of the explosion, but that's no reason for them not to look cool.
 +
** We've introduced some new variance into this effect, and in general made it look better, so that now it has a distinct "rush and pop and slowly fade into wisps" feel to it.  With the speed and details being randomized, this definitely brings it to the next level.
 +
 
 +
* The tesla AOE effects, both the "guardian" level and the "regular" ones, both look vastly better now and way more like lightning.
 +
** We made a video showing off all the new effects in the editor!  https://www.youtube.com/watch?v=mhJjPabV3gM
 +
 
 +
* A new "Victory" fire text has been created, for purposes of being used like the "you have lost" text that can happen when you lose.
 +
 
 +
* When you lose the game, it once again shows the "You have lost, humanity has perished" message in big burning letters.
 +
** That lasts for 7 seconds, and then immediately after that you go to the loss screen.  This makes it so that the transition to the loss screen is not so abrupt.  Plus people liked the text.
 +
 
 +
* When you win the game, it now says "VICTORY" in giant fiery letters, rather like the "You have lost" for when you lose.
 +
** This one waits only 4 seconds, and then transitions to the normal victory screen.  This again makes the transition a bit less abrupt.
 +
 
 +
== Version 2.634 Multiplayer Solidification ==
 +
(Released November 18th, 2020)
 +
 
 +
* A new planet naming scheme, Oddball, has been added to the game:
 +
** Aims to give a sense of history. One heavy with warfare and bored scout captains. Created by Kizor. Thanks to Loweko, R. Jean Mathieu, Vornicus, McMartin, Reiver, Quasispace, Derakon, Kyoshyu, and the anonymous.
 +
 
 +
* Several updates to journal entries for extra lore details.
 +
** Thanks to Puffin for writing these!
 +
 
 +
* The sabotage hack, when there are multiple viable targets on one planet, now includes the text:
 +
** Whichever of these is closest to the hacking unit will be the one hacked, so park your hacker right near the target you intend.
 +
** Thanks to Daniexpert for suggesting.
 +
 
 +
=== MP Performance Boost ===
 +
 
 +
* Previously we had a rate limiter in place for only checking if background work threads were done if it had been at least 50ms of time since the last check.  This is not a super expensive check in the grand scheme, and we'd rather react to these being done as fast as possible in order to avoid small timing discrepancies causing larger delays in sim cycles kicking off or moving to the next frame.  So for now we've just entirely taken the limiter off, which should have only positive effects from what we can tell.  The limiter was originally put in place out of an abundance of caution, when we were not sure how slow it was to call ThreadState on threads.
 +
** Update: apparently this actually majorly cuts down on multiplayer lag and small jitters.  This tiny bits of timing really add up when you have to wait on the other computers in particular.  What a lucky find!  This would have taken us ages to figure out if we'd actually been looking for it, but instead we found it while fixing the flickery dropdowns.
 +
 
 +
=== Bugfixes ===
 +
 
 +
* When a client is getting sync correction data from a host about entities, there were several cases where it could detect some invalid data, and it would then throw a visible error... but it would also just keep trying to process this now-known-bad data, and thus run into further problems.
 +
** Now it actually stops processing all of the sync fix data from that batch, and logs warnings into the log silently.  This way we can go back and find them if need be, and certainly if your log is filling up with these that would be bad.  But these will not affect the running of the game (just how rapidly sync correction happens for this specific batch of units), so they are starting their lines with "Not fatal - just a warning" to be extra clear on that.
 +
** There were various errors that would show up after these, previously, that were simply a matter of "hey, bad data was sent, but we tried to parse it anyway, and of course that went about as well as you could expect."
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* On the host in multiplayer, it now does a last-minute check to see if it's about to send the sort of mangled data for a ship that would cause the client to have to do the sort of toss-out of the entire batch that the clients were doing in the most recent fix.  If it finds that it is, then it should now just skip that unit and leave it for a future sync pass.
 +
** At this stage, we can assume that maybe the unit JUST died on the host, and so within 2-4 seconds the client and the host should get synced up properly regarding it.  But in an abundance of caution, there's always the chance that actually this unit is still alive, but just was changing planets or something, so let's not tell the client to delete it just yet.
 +
** This sort of scenario should be an edge case, but the idea here is that we make it less likely than the client would have to throw out an entire batch of divergence data, and instead just the one problematic ship will get re-evaluated next cycle and we don't even need any bad log messages about it, etc.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* Fixed a minor bug in the macrophage, which nobody has ever even hit, where if the king was not found it could wind up having some pathing errors unless you had debug flags on.
 +
 
 +
* Fixed a really rare bug with the Zenith Trader where, two seconds into the game, it was theoretically possible for multiplayer clients to get a nullref exception when the trader was trying to spawn.  No one actually hit this yet.
 +
 
 +
* In multiplayer, on the client, if findHumanKing() cannot find a result, it no longer throws any form of error (they were silent errors in the log, before).
 +
** Essentially, sync data must be slightly off, and that is fine and something that we should just ignore.  The host will take care of giving proper orders to ships, and the client will find out about that soon enough and have all its data corrected anyhow.
 +
** Same logic on findAIKing().
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* Some of the data for how things that use internal build points (for things like viral shredders in particular) was being set up on the fleet memberships, and cached there as well.
 +
** Now it sets it up once only, at game start, in ComputeBalanceStats_OneTimeOnly().  This is more efficient, and also gives us errors on load if our xml is wrong, and also fixes a compatibility problem.
 +
*** There was previously a bug in multiplayer where viral shredders would lead to endless exceptions on the client because it was missing the extra cached data on the fleetmem, ouch.
 +
** As an additional bonus, we are no longer storing this data on fleet memberships in general, which means we no longer have to serialize and deserialize that.
 +
*** The fact that we WERE serializing it was making the question of the exceptions in multiplayer even more confusing, but at any rate now some sync data and all savegames will be a tiny bit smaller.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* MP clients in general will no longer throw any exceptions related to things with internal build points on their fleetmems.  If something is off, it will just let the host take care of that and inform them within a few seconds.
 +
** However, the error will still happen on the host if something is messed up, but it will be more informative and not block the rest of the execution of this fleetmem per-second cycle.
 +
** And based on the fix above, this should now just work properly in general on clients, but we prefer an abundance of caution.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* Previously, in multiplayer if there was a reroll hack that was done, it would give a different result on the client and the host.
 +
** That has been corrected by making it so that on the host it now calls FlagAsNeedingForcedFullSyncToClientsJustInCaseIfInMultiplayerAndWeAreHost() on completion of the hack, which is the general standard that we should be aiming for with this sort of information in the future.
 +
** This applies to the ARS, FRS, TV, and GCA.
 +
** There is a slightly-more-automated fix for this that doesn't require individual mod-author (or faction-designer or unit-designer) input, but this is still a good idea to do.
 +
** Thanks to a variety of folks for reporting this, including Arides, Daniexpert, and others.
 +
 
 +
* Apparently it is possible to get an exception when hovering over a tech tooltip in multiplayer.  This has not yet been fixed, but now when it happens it will be sure not to be destructive to the rest of the game, and it will give a far more detailed error message.  Right now we really have no idea what the actual error is, but this will at least contain it and let us fix it after we have a new report in the next release.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* TextEmbededSprites now have a few new capabilities:
 +
** The scale float xml parameter allows you to set the scale of a sprite relative to what it would normally be (default is 1.0).
 +
** use_geometry_queue as an xml parameter allows for you to make a for-the-galaxy-map-by-planets-text version of sprites.
 +
*** If this is set to true, then those versions of the galaxy map sprites will be vastly more efficient and will dynamically batch as we set up last build.
 +
*** If this is set to false, then this is for use anywhere else in the GUI, including the header and tooltips and whatnot.  If this is set to true and you try to use it in the interface elsewhere, it will be invisible, as we discovered yesterday.
 +
 
 +
* Using the above, strength icon is now properly batched on the galaxy map (as with last build) but all of the other sprites being drawn in the GUI now actually draw visibly again (unlike last build).
 +
** Also, while we were at it, we adjusted the scale of the strength icon to be 0.9, since it was a little bit on the large size in most text.
 +
** Thanks to Badger, Daniexpert, TechSY730, and Crabby for reporting the invisible icons in the GUI.
 +
 
 +
=== MP Sync Improvements ===
 +
 
 +
* During multiplayer, if there is a hack happening, then every second where something is changing, the host does an extra forced sync of the hacker and the hack target (if there is a hack target) to all clients, thus keeping them all in the loop.
 +
** This is central and automated, and should probably actually catch cases like "something was different after a hack between the client and the host" even if the end programmer/modder/etc doesn't account for it fully.  This is just a handy new feature in general!
 +
 
 +
* When units are claimed, or when they complete construction for the first time, there is now an automatic forced full sync of that unit from the host to the clients.
 +
** This gets rid of a lot of potential desyncs that otherwise could linger for a bit.
 +
 
 +
* The ability to set the importance of intel tab entries is now shared among players in multiplayer.
 +
** This was previously set up to only be local, kind of by accident.
 +
** This has some code to keep it nice and responsive as if it was still just a local change, but if you click really rapidly on the same intel entry and cycle it through, you may see some slight funkiness to that.  Should not be a big deal, but we'll see.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* FlagAsNeedingForcedFullSyncToClientsJustInCaseIfInMultiplayerAndWeAreHost() has been renamed to FlagForForcedFullSyncToClients_FromHost().
 +
** Added a new FlagForRequestedForcedFullSyncToAllClients_FromAnyClient(), which lets clients request updates on an entity rather than the host having to tell them.
 +
** Both of these calls remain utterly impact-free when we're talking about calling them repeatedly, or calling them during single-player.  They intelligently weed out extra requests, and don't do any substantial processing directly.
 +
** The FlagForRequestedForcedFullSyncToAllClients_FromAnyClient() method in particular throttles itself so that a fresh flag can only be set on a given entity on 1 second intervals.  So if the client is repeatedly asking the host for updates on an entity, that's just fine, but it will only get results on that given entity once per second.  Other entities may be requested inside that timespan.
 +
** The upshot of this is that, whenever you look at a ship or structure as a client, by hovering over them to see the tooltip, you immediately get a refreshed copy from the host (within 100ms or so at the most, probably less, so too fast for you to notice), and then every 1 second after that you get further updated info.
 +
*** There's a lot of extra data that is stored normally only on the host.  That gets sent to you as a client when you first connect, but it's mostly stuff happening on background threads and affects faction decision-making.  Some of the DLC2 factions gather various resources that you can see in the tooltips, for instance.
 +
*** Previously, before this addition, clients would just have incomplete tooltips.  Now their tooltips are updated with host data as-needed, and already the behavior of those sorts of ships would be updated by the host (so if you're not hovering over something for a tooltip, it will still act correctly; and you don't need the extra data in the tooltip unless you were to hover over it).
 +
** The other side effect of this is that if you feel like maybe there's a sync error with some ship or structure, and you go to hover over it to check that out and see for sure... it's going to instantly fix itself.  So do be aware of that, though it's more or less a good thing.
 +
 
 +
=== UI Improvements And Fixes ===
 +
 
 +
* The concept of "Update Cycles" in the ArcenUI framework has been removed.
 +
** Instead we are basing things on ArcenTime, which was developed after the initial design of the ArcenUI.
 +
** This in turn lets us have reactions which are framerate-independent, which is thus more consistent across machines.
 +
 
 +
* Using the above shift, plus also an extension to allow dropdowns to properly handle tooltips even on their "off frames," we have fixed the flickering dropdown tooltips that were introduced in the last update of the game.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* Various lobby dropdowns have been improved as follows:
 +
** The tooltips for map type planet count entries still retain the header text of what you are doing.  Also, colors for the selected vs potential items has been added.
 +
** The tooltips for the planet naming types are a bit more clear in general, and it now shows the name in a line above the description for extra clarity.  Also, colors for the selected vs potential items has been added.
 +
** The tooltips for the map types explain themselves a bit better, include the name of the map type, and have the new colorization.
 +
** Tooltips for the map linking flavor and planet layout and such now match the others in function and colorization, including showing the details of currently-selected item when you hover over the closed dropdown for the first time.
 +
*** Also discovered a special discrepancy in how these were being handled that was causing these to still flicker like crazy even after we fixed dropdowns in general.
 +
**** Also found and fixed this on all settings on the personal settings window, although all other windows seemed to be okay.
 +
 
 +
* Put in a fix that will prevent dropdowns in general from using the code combination that leads to flicker:
 +
** Essentially, HandleOverallMouseover() has been removed, and you should now use HandleMouseover() for that, and continue to use HandleItemMouseover() for items.
 +
** We are able to control how this flows properly and remove the flicker, whereas before if someone used HandleMouseover() by mistake -- when they were supposed to use HandleOverallMouseover() -- then they would get a flicker.
 +
 
 +
== Version 2.633 Roaring Performance ==
 +
(Released November 17th, 2020)
 +
 
 +
* Civilian Industries Update
 +
** Put in some defensive code to prevent potential pathfinding lock ups when multiple civilian factions are in play.
 +
 
 +
*  When hovering a Flagship, the 'max possible strength' value in the tooltip is now colour-coded to let you know what percentage of that strength currently exists. So if your fleet has taken heavy losses, the Strength colour will be darker. If you are at full strength it is brighter. This matches the behaviour of the tooltips for Factories.
 +
 
 +
=== Performance Improvements ===
 +
 
 +
* On the main menu scene, improved the culling mask on the scene-view camera to greatly improve efficiency of that scene.
 +
** It looks like the main menu may have been accidentally drawing 1.8 million tris rather than 800k tris because of this being set wrong.
 +
 
 +
* The reflection probe on the main menu scene has also been updated to have an appropriate culling mask, for the same reason.
 +
** The reflection probe updates, which are quite heavy and frequent, should also thus be correspondingly faster and draw so many fewer triangles as well.
 +
 
 +
* Poly few has been employed on the main menu scene to combine all of those meshes of the hangar into just a single mesh with 16 submeshes for the various materials.
 +
** This cuts the number of draw calls on the main menu down from about 3000 to about 250.  The visual end result is identical.  The performance gain is potentially massive, but varies heavily by hardware.
 +
 
 +
* We have historically had static and dynamic batching disabled for this game, because we use GPU instancing instead (which is far more efficient and direct).
 +
** However, when we made the new main menu, we had implemented things such that this type of batching would be useful there, so we turned it on.
 +
** We have now changed things around again to remove that, and so once again removed those from being on in the application as a whole.
 +
** It's quite possible that these were dragging down performance on some machines in general, as the game may have been spending some CPU cycles fruitlessly looking for things to dynamically batch during the main game itself.
 +
** It's irrelevant to the end result of how things look, but there's no chance of that popping in and impacting performance negatively anymore, which is good.  If it wasn't a performance impact, then no worries there, either.
 +
 
 +
* Using Blender, we've manually removed some off-screen sections of the main menu meshes.  This has overall reduced our polygon count in the game on the main menu by another 300k or so triangles.
 +
** This sort of hand-optimization is something that we had been saving until it was clear this is where the bottleneck was, and after it was clear that the new main menu was a winner (and that we had time aside for it).
 +
 
 +
* With these changes, on Chris's main two computers he sees:
 +
** On the main menu on his main dev machine (GTX 1070 and a few year old i7 laptop) a jump from about 55-60 fps to instead being about 100fps.
 +
** On the main menu on his MacBook Pro from late 2013 which has an i7 but does not meet the minimum system requirements in general, it jumps from 26fps to... 26 fps.  So there's a different limiting factor other than polygon count or draw calls on this ancient of hardware.
 +
** Most likely, any machines that are actually meeting the minimum system requirements, or vaguely approaching the recommended, environment, should see a substantial performance bump on the main menu.  And for everyone, the disabling of the static and dynamic batching may improve performance beyond the main menu.
 +
 
 +
* In our main menu scene, the way that the reflection probe is update has been changed fairly substantially.
 +
** Previously it was every-frame every-face if you had at least 30fps, and every-frame individual-face if you had at least 15fps, and below that would not update over time.
 +
** The individual-face updates were really jarring, however, and not something that is a good idea for any sort of smooth feeling.
 +
** Now only if you have at least 50 fps will it do every-frame every-face updates, and below that it will just not update over time, instead only having the reflection from the initial onawake event.
 +
** On Chris's main machine this makes no difference since it runs at 100fps now, but on the under-min-specs OSX machine this brings performance up to 31fps from the previous 26fps.
 +
 
 +
* On the main menu, a number of lights were set to affect more than just the Scenes layer.  This probably did not affect performance, but we are correcting that anyhow.
 +
 
 +
* On the main menu, we had one extra spot light that was drawn in a not-important weighting, and that was very dramatic and looked good in general BEFORE we started having ships with lights on them moving around.
 +
** Since having ships moving around, that spot light would disable itself as the spotlights overtook it, then re-enable itself, and the transitions were jarring.  It did not seem to affect performance much on the high-end or ultra-low-end machines, but in the middle-tier it might, also
 +
** This spot light is simply removed, as it was not needed for the new scene composition.
 +
** We experimented with turning off the point lights used on the ships, or even with turning off the reflection probe from being on at all, but the former gave 2fps on the super-old mac (from 31 to 33 fps), and the latter gave no boost at all.
 +
** Whatever is holding back the ancient below-specs mac is really not the sort of thing that is holding back the rest of the potential computing audience.  And this is one excellent reason why we have system requirements in the first place.  Not that 30fps is a cardinal sin; the original AI War was hard-locked to 20fps most of the time.
 +
 
 +
* Added a new Performance tab option: Unrestricte UI Update Speeds
 +
** Normally, most UI windows only update their contents every 50-100 milliseconds.  If your framerate is much higher than this, however, you may prefer that the UI update at whatever your actual framerate is.
 +
** This will likely reduce your framerate, potentially substantially, but it leads to the ultimate in responsiveness.  Prior to version 2.633, and since sometime in the game's alpha, the UIs were all running on unrestribted update speeds.
 +
** We are not noticing any substantial benefit from this on our powerful machines, but on lower-end and middle-tier machines this may make more of a difference.
 +
** At the moment, things seem to perform equally well either way, but it's nice to put a lesser load on things where we can.  Since this does not seem to make a visual/feel difference that we can detect at the moment, this seems fine to have with a differing default from the past.
 +
** Thanks to Daniexpert for inspiring this change.
 +
 
 +
* In the ArcenUI_Element class, we have a SetActiveIfNeeded() method that long ago had some gating that was based on a cached wasLastActive in the class. 
 +
** This was working poorly, back in alpha or beta of the game, because of how unity handles commands to enable objects that are disabled in the heirarchy, and things like that.
 +
** The game has now been updated to do a check against the activeInHierarchy property of the gameobject, which will always give the real result.  This should not result in bugs, and should in theory result in some slightly better performance in certain cases where large numbers of ui elements are turning on or off frequently.
 +
** We don't really see much of a difference based on this, but in general this was something we noticed that was an optimization we had wanted a long time ago, and being able to have a tamer version of that back in here now is nice.
 +
** Thanks to Daniexpert for inspiring this change.
 +
 
 +
* Over the last few months, as we've added functionality, the performance of the galaxy map has dropped notably.
 +
** In combination with a much-more-recent performance drop related to how we draw sprites-in-text and how that affects the galaxy map only, full galaxy maps were down in the 25fps range and really choppy to move around, today.
 +
** We've now restructured a lot of things to update in a time-sliced fashion, and the performance is now in the range of 90fps when zoomed all the way in, and 60fps when zoomed all the way out on a full map.
 +
** There are still some performance improvements we need to pursue related to sprites-in-text in this specific instance, but those will be in the next build.
 +
*** We did experiment around with trying some things like adjusting the sprite-in-text shader to allow for GPU instancing, but that went absolutely bonkers in a way that we don't care to untangle.  There's a better approach that we'll implement soon.
 +
** Thanks to Daniexpert for reporting.
 +
 
 +
* A whole messload of the new background images and other accents that are used in the new UI have been made vastly more efficient.
 +
** This may actually vary by OS just how much more efficient they are, but in essence these are all now able to be stored in DXT1 format, and all of the ones where relevant now have mipmaps for more efficient drawing at smaller resolutions.
 +
** The amount of VRAM that this should save, and the extra load removed from the GPU pipeline, should be substantial.
 +
** Thanks to Daniexpert for getting us to look into this.
 +
 
 +
* Discarded these changes: Rather than using raw "TextMeshPro" text renderers for the text that is shown all around the galaxy map, we are now using individual Unity GUI Canvases with embedded TextMeshProUGUI objects.
 +
** Visually this looks identical, but now we are able to take advantage of the compositing stages that unity canvases go through, and thus we can have things like strength icons be embedded directly in these canvases without them causing extra draw calls.
 +
** At the moment we have one canvas per planet, with three text sections inside of that.  This is less efficient per update of text, but more efficient for drawing text, which is the more common operation.
 +
** None of these respond to mouse raycasts at all, so on the off chance that the occasional (could not click a planet on the galaxy map) was relating to these, that no longer is possible.
 +
 
 +
* Replacement changes for the above: In the end we went back to raw TextMeshPro text renderers, as their performance was superior to anything we tried with an abundance of canvases.
 +
** We did wind up also making it so that the shaders for TextMesh Pro sprites now use the Geometry queue instead of the Transparent Queue, which improves performance on rendering and also allows for batching.
 +
** And for the various ship icons in both the main view and the galaxy view, those also now use the Geometry queue.  Those should generally get picked up by GPU instancing, but in the event they do not they will now get picked up by dynamic batching instead.
 +
** We actually have re-enabled dynamic batching for the game, but still left static batching off, and this seems to give the optimal performance when that's paired with these shader changes for the sprites.
 +
** Sprites used to always do perfect instancing, but now the sort order sometimes messes that up since there are multiple materials and it feels like it needs to handle them in proper order (really, z buffer ought to be sufficient and overdraw is probably preferred, but anyhow).  The queue change makes these more likely to instance, and in the event they don't instance it makes them batch, thus leaning on the z buffer as noted.
 +
** The end performance boost on the top machine we have is now getting us back into the 90s fps on the galaxy map, up from the high 20s in the prior build, and still in the 90s on the main planet view.  And both feel smooth rather than jittery, now, which is good.
 +
** Thanks to Daniexpert for reporting the performance loss observed lately.
 +
 
 +
* On the galaxy map, we are now properly buffering text such that we don't put back in the same value into a field that just had that value.
 +
** This was causing some needless thrashing and re-parsing of rich text tags.
 +
 
 +
== Version 2.632 Multiplayer Sharing ==
 +
(Released November 16th, 2020)
 +
 
 +
* Fix an XML parsing error related to the Human Marauders
 +
** Thanks to Crabby, zharmad and okonomichiyaki for reporting
  
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, both LiteNetLib and Steam are 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 August.  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.
+
* Add a setting for 'Show Faction Ring Around Ship', which displays a circle around a ship of the colour of the faction.
 +
** This is intended to make it easier to follow how battles are going without icons on, since it looks really cool that way.
  
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).
+
* Add some Red text to the Delete Campaign popup to make it a bit harder to do it by mistake
 +
** Prompted by the woes of Pat on the forums
  
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?
+
* Mod updates: Fixed Tugboat Drones always slowing enemies by 80%. Instead they now start at 20%, increased by 5% per mark beyond 1, ending up at 50%. Note that Tugboat Drones can still archive the maximum slow if their slow fields overlap.
 +
** Thanks to zeusalmighty428 for reporting.
  
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.
+
* Micro Mod Collection fix/balance:
 +
** The Energy Converter no longer produces negative energy and instead consumes the same amount of power. It was causing errors when a bad brownout could turn the energy generation of the player negative.
 +
** Doubled the metal cost of the Research Expedition.
 +
*** From zeusalmighty428's balance feedback
  
== Version 2.114 ==
+
=== Multiple Players Controlling A Single Faction In Multiplayer ===
(Not yet released -- we're still working on it!)
 
  
* You can now have multiple copies of the Devourer and Zenith Trader in a game
+
* In the lobby sidebar, you can now see on the client and the host if other people are in spectator mode, not just if you are personally.
** There's no technical reason for this limitation, and we're encouraging Zenith stuff because of the coming Onslaught
+
** This is quite helpful for knowing if the multiplayer lobby is truly ready to start.
  
* Quickstarts are sorted alphabetically again, instead of when the quickstart was created
+
* Under human player entries in the factions tab in the lobby and the factions screen in the main game, you can now add and remove players from factions.
** Thanks to ArnaudB for the bug report
+
** The tooltips make it pretty clear, but basically you can switch who is controlling what faction, or make someone just a spectator, or have two people share control of one faction, etc.
  
=== Imperial Fleet Summoning Changes ===
+
* Fixed an issue where regenerating maps was causing faction assignment auto-allocation previously.
  
* The AI now generates some weaker bonus exos against miscellaneous player targets (energy producers, MDCs, GCAs, etc), just to keep things exciting.
+
* Two players are now confirmed as being able to share the same faction, and both can order around the ships of it and see everything as if it was just controlled by one of them.
* Fix a bug where Exos were trickling into their targets instead of moving as groups.
+
** What is not shared is the state of your GUI, such as what you are looking at or what you have selected, or what you are hovering-over, etc.
* Start the Exos the moment you finish the hack, instead of some random time < 30 seconds from when the transceiver finishes.
+
** This is essentially the same as even really old RTS games like the original Age of Empires that would let you share a faction if you gave two players the same color.
** Blame MasterGeese for these changes
+
** However, with this you are able to still do text chat with the colors and the names of the individuals who are a part of the game, whether they have their own factions or no faction or share a faction. This feels pretty awesome!
  
== Version 2.113 Dyson Growth ==
+
* Joining a game late as a spectator is confirmed to still be possible, but now that's the only time it warns you that you are a spectator.
(Released August 3rd, 2020)
+
** If you join the game in spectator mode during the lobby, or the world is regenerated while you are in the lobby, it doesn't show the "hey you're a spectator, is this on purpose" message.  That was really annoying when changing galaxy sections to have fewer factions or while someone was just intending to spectate.
  
* Fix a null reference exception if the game wants to spawn a Relic but you own basically every explored planet
+
* New feature, after someone has joined a game late (or frankly, even if they have been there from the start):
** Thanks to Lord of Nothing for reporting
+
** You or they can unassign them from factions, and assign them to other factions or no faction.
 +
** This is great for having a game where you were playing solo, but now have some friends coming in as extra sets of hands.
 +
** But surprisingly, since this is so quick and so seamless of a way to pop over and see the perspective of another player, I can see this potentially being used as a "hey, look at my metal flows and such for a minute" type of view, too.  You can do it while paused or unpaused, the game doesn't get interrupted while people change status or come and go in general, and overall this is just really smooth.
  
* Fix a bug with Dyson Sphere units not marking up
+
== Version 2.631 Multiplayer Swaps And Performance ==
** Thanks to GreatYng for reporting
+
(Released November 13th, 2020)
  
* Fix a typo in a Battlestation description
+
* Fixes to when GetIntValueForCustomFieldOrDefaultValue or GetValueForCustomFieldOrDefaultValue have empty strings in them, to where they will now return the default values properly.
** Thanks to ovalcircle for reporting
+
** Thanks to NR SirLimbo for identifying the problem and likely fix.
  
=== Multiplayer Work ===
+
* Kaizers Marauders fixes:
 +
** Fixed another exception in relation to missing settings. Tracing the issue back lead to finding out that Vanilla GetValueForCustomFieldOrDefaultValue() sometimes still does not return the actual default value but an empty string. OnS0_KaizerUpdating() now detects this and produces an informational popup before correcting it to "Never" which is the actual default value.
 +
** Debugging lead to the discover of a bug in the Budget Updating logic where (due to the same issue) they would every second set the starting budget of [nothing] without ever beginning to accumulate budget. They now start with 0 and begin accumulating.
 +
*** Thanks to Isiel on Discord for reporting and delivering a save to reproduce these issues with.
  
* Fixed one oversight that was causing the factions tab chat to not show its chat text properly, unlike map and options in the lobby.
+
* Fixed an exception that could happen in RemoveInvalidatedOrdersAndReturnFirstValid_IncludingDecollision() somewhat at random on multiplayer clients, mainly as a race condition.
 +
** Thanks to crawlers and Driftwood for reporting.
  
* As text messages come in inside the lobby, it now scrolls to the bottom of the chat window, as you would expect.
+
* For whatever exact reason, the Macrophage faction really doesn't work well if the client is also trying to calculate all the decisions for things in multiplayer.  This is referring to the DoPerSecondLogic_Stage3Main_OnMainThreadAndPartOfSim() method in general, but the telium spawning logic in particular.
 +
** Since this was a constant source of errors, and since the desync repair code should catch things like this quickly in general, for now we're just not running this on the client at all anymore.  This stops the errors, and any divergences should be quickly and easily picked up by the desync repair logic.
 +
** Thanks to crawlers and Driftwood for reporting.
  
* The maximum length of chat messages in the lobby is now 1000 characters.
+
* Fixed potential exceptions that could happen in OnlyInMapgenOrInActuallyGettingRidOfEntities_ImmediatelyRemoveFromSim() in general during cross-threading, but most often on multiplayer clients.
 +
** Thanks to crawlers and Deadwood for reporting.
  
* GetLocalPlayerFaction() is now GetLocalPlayerFactionOrNull(), to support spectator players.
+
* A variety of data that is only relevant in single-player or on MP hosts no longer shows up on MP clients in the escape menu sidebar.
** 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.
+
* Previously in MP, it was possible to get some errors like "Hey, we have generated drones from a ship of type CarrierGuardian that can never be properly deployed by the fleet it is not the centerpiece of, of type NonPlayerDrone" on the client in a spurious fashion.
 +
** These are simply not written right now, and the natural sync process fixes those already within a couple of seconds.
  
* 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).
+
=== Swapping Fleet Lines Between Multiplayer Players ===
** 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.
+
* Created the ability for players to swap out ship lines between each others fleets in multiplayer.
 +
** For the sake of convenience, every player can slot in every other player's ships into their fleet, or grant their own ships to any other player's fleet.
 +
*** In AIWC, we required players to actually gift ships or similar from themselves to someone else, but in this game you can outright take from others.  You're all on the same side, so divide up tasks how you will.
 +
** The owner of the fleet is included in the row of the swapping target so it's easy to see who owns it.
 +
** For balance reasons and to prevent technical hiccups, any ships that are swapped between players in this fashion get destroyed and have to be rebuilt by the player on the other side.
 +
*** This is fairly similar to how, when ship lines are swapped between fleets on different planets, the ships are scrapped and have to be rebuilt then, too.
 +
** It's worth noting that this sort of thing does allow for a lot of extreme focusing of tech lines in multiplayer, making MP even easier than it would have been before (you take all of the ships that benefit from tech X, give me all the ones that benefit from tech Y), but this was always a feature we were planning, regardless.  Player flexibility and the ability to coordinate is more important.
 +
*** We could implement punitive-style tech costs in MP, to make it so that it was more costly to use techs, but that would probably just encourage even more specialization.
 +
*** In general, it's simply worth noting that a MP game is substantially easier than the equivalent game played solo.  So either up the difficulty, or add more secondary foes to deal with, or enjoy the extra ease.
 +
*** The original AI War had a much more limited set of factions at the start, and only could ever have two AIs, etc.  So it was important for that game to scale the difficulty up as more players were added.  But in this sequel, the amount of other factions, and their power, make it so that you can really tailor it to your own needs, instead.
 +
** Huge thanks to NR SirLimbo for implementing this!  This was on our list to do, but to have a modder implement it for us in advance is a great time saver.
  
* 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.
+
=== Multiplayer Performance Improvements ===
** 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 multiplayer sync-repair of planets, with planet-factions included inside of them, was by far the largest amount of bandwidth being sent by the game during gameplay, and it has now been set up in a time-sliced fashion so as not to cause a bunch of lag on the client.
 +
** It's quite likely that, on some certain very heavy games on Steam, this was actually able to cause an exception where the amount of data being sent in one message was larger than what Steam allows.
 +
** At any rate, this was causing periodic lag on the client that was so severe in some games with larger counts of planets that it was making the entire game laggy.
 +
** We have not only started time-slicing the planets, but we actually split out the data for the planet factions themselves and also time slice THOSE now, too.
 +
** As a direct result, the performance of multiplayer games has skyrocketed when it's involving large number of planets and/or factions, but we're going to take this a bit further.
  
* The correct name for each player faction now shows up for even for players who are in spectator mode.
+
* Previously, we had a system where ALL of the various types of network sync repair work shared one large time-slice.
 +
** This really only worked when we had fewer types of sync repair, and when they didn't also internally have lots of time-slicing happening.
 +
** As we have added more types of sync repair, and have started wanting to time-slice those, this would otherwise mean that the really core stuff -- namely ships/units -- could fall further and further behind, which is not good.
 +
** Therefore, we've moved both the "ship sync checks" and the "divergent ship fixes" out of the central time slice group, and they are handled every sim frame instead.
 +
*** For ships, these were already time-sliced, and so those happen over the course of a couple of seconds.  Probably closer to 2 seconds now, rather than 4, but it depends on the number of ships in the game.
 +
*** For divergent ship fixes, those now don't wait on anything, and just get sent to clients asap after we realize that it is needed.  This makes that far more reactive in a good way, and ultimately the data is small enough not to be concerning.
 +
**** As we get to fewer PKID conflicts in the future, this will dwindle even further, but having it be nice and reactive is good.
  
* Player factions in spectator mode now see in the lobby chat area that they are in spectator mode.
+
* Now that we don't have to share the time-slicing with the time-sensitive ship fixes, we can make some of the rest of the sync repair data happen on a more relaxed schedule.
 +
** This actually is a dramatic reduction in the amount of data transferred, and even more importantly is a dramatic reduction in the amount of CPU processing on clients required to handle this.
 +
** Planet Faction sync is by far the slowest stuff to sync, and has the most data, so we're time-slicing it over 20 frames now, which is about 2 seconds, rather than 4 frames like earlier in this build (before this build, it all happened in a single frame every two seconds or so).
 +
** Planet other-data sync is not exactly small, either, so it's being time-sliced over 8 frames now instead of 4 frames like earlier in this same build.  Again, prior to this build this AND the planet-faction data was all in a single giant laggy frame every 2 seconds in large games.
 +
** The data on these things is just not all that visible or important in this sort of time schedule, so cutting it down in this fashion keeps things from drifting over long periods of time without impacting game performance like it previously was.
 +
** We may add in extra time-slicing in the future if it really becomes needed, but at this stage it is seeming to be a good balance between keeping things up to date quickly and not draining performance.
 +
** Thanks to crawlers and Deadwood for providing an MP savegame where basically the performance was stop-and-start laggy; in this new version, we can run it at full sim speed with no waiting on the client, which is really awesome!
  
* 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.
+
* Non-new ships on tier 3 planets now get synced FAR more slowly, and are counted as skip-syncs.
 +
** These catch up at a rate of roughly "one full sync cycle multiplied by 1/10th the number of planets, rounded up).  In practice in one large savegame with 12k stacked ships and 93k ships total on 120 planets, this winds up being about a delay of 68 seconds at most for any given ship.  If players moved onto a planet that is slightly stale on the clients, that planet would be immediately updated.
 +
** The main cases where we might have a problem here is with strength calculations being off on planets where there are large numbers of reinforcements suddenly dumped into new ships.  The host would always be correct, but the client would have some slightly stale data in the galaxy map for up to 60 seconds, which would be annoying.
 +
** There are some ways we can adjust for this for specific ships as they are updated, though, and the next step is to add that.  This whole process at the moment does wind up saving a ton more bandwidth and CPU processing, though, which is excellent.
  
== Version 2.112 Steam Networking Complete ==
+
* Added two new methods to GameEntity_Squad for ships:
(Released July 31st, 2020)
+
** FlagAsNeedingForcedFullSyncToClientsJustInCaseIfInMultiplayerAndWeAreHost() causes a ship to immediately be fully synced from the host to any clients.  It is unused on the client side.
 +
*** This is a great way for mods in particular to, after having updated some sort of special mod-only data (like resources they are carrying) to cause a full ship sync.
 +
*** This should not be done too frequently!  But if you have a mod that is gathering resources, and periodically updating information that would not normally be caught by the sim thread, then having this periodically called on the gatherers would keep the tooltips of clients up to date.
 +
*** In the escape menu networking details on the host, you can see how many of these have happened via the "Ship Syncs Forced" item.
 +
*** BUT, this may actually wind up never being needed, stay tuned.  We're going to make some additions so that anything a client is hovering over to get a tooltip gives them up to date info without you having to be predictive about it.
 +
** FlagAsNeedingFullSyncCheckIfInMultiplayerAndWeAreHost() is specifically to say "ignore my tier3 delayed status," to work around the feature we just added today where background ships get ignored a certain amount.
 +
*** This is mainly something to use when something unusual changes (other than a ship existing at all) that would be visible on the galaxy map for client player, without them clicking into the target planet.
 +
*** So for now this is something that happens whenever a ship marks up, and it also happens whenever the AIReinforcementPointContents contents are changed (increasing, decreasing, transferring, deploying).
 +
*** This should keep the galaxy map accurate for clients, while at the same time not having so darn much data transfer for ships on planets where players are not active.
  
* The description of the Ensnarer Battlestation now explicitly mentions that it can use AI Great-Turrets
+
== Version 2.630 Arbitrary Icon Inclusion And Weapon Exclusion ==
** A number of people have reported this as a bug over the years, so hopefully that won't happen anymore
+
(Released November 11th, 2020)
  
* 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.
+
* Add death effect damage a unit has sustained into the tooltip for it at or above Medium detail.
** This should make battles with other mega-units last longer, which feels more appropriate, but keep their "damage over time" the same. 
+
** Each type of damage is listed separately, and displays the current damage, and the amount required.
** 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.
+
** Thanks to Puffin for adding.
** 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.
+
* Fix a Macrophage typo
** 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.
+
** Thanks to crawlers for reporting
** 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.
+
* Fixed a bug in Astro Trains where they were looking for a nonexistent variable in their custom xml.  This was always a harmless bug, but newly showed an error while in the past it was silent.
** Thanks to MaverickPenkenn for reporting.
+
** Thanks to ussdefiant60 for reporting.
  
=== Milestone: Steam Networking Integration Complete ===
+
* GetDefaultValueOfWhateverSort() on the SpecialFactionData object has been updated to match the way that the default values were returned on the faction screens.
 +
** Thanks to NR SirLimbo for reporting that this was not working consistently.
  
* 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.
+
* The CustomFieldValues array on faction objects is now private, so that people don't try to directly add or find data from it.
 +
** Instead, mods and factions and whatnot should set data through SetCustomFieldValue (which works the same as before), and they should get data via either GetCurrentIntForCustomField() or GetCurrentStringForCustomField().
 +
** Both of those latter two methods have a method that lets you pass in the specific field (more efficient), or which just takes the name of the field (less efficient).
 +
** Either way, the idea is that there's never confusion with not getting the default value back when there is a blank present in the main data (which might be an old savegame or quickstart, or various other valid conditions).
 +
** Thanks to NR SirLimbo for finding this accidental modder-landmine for us.
  
* 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.
+
* Fixes for Kaizers Marauders:
** 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.
+
** Instead of failing horribly when added as a Random Faction, or when loading older saves where old Marauders were enable (be it just as a beacon), which includes quickstarts they will now use somewhat defaulting values. It's not perfect, and not really intended for use this way (simply because of the sheer amount of options available) but it works.
 +
** Fixed a potential issue with Debugging global stuff for Marauders (such as logging Kaizer Updating or the Shared Planetary Cooldown List) where the debug could be turned on, but when only a specific Marauder Faction was set to be debugged it could re-overwrite with false later on, leading to no printouts.
  
* A new ArcenSteamClientConnection wrapper has been created to keep track of the Steam connection on servers.
+
* Remove mentions of 'tiers' from the scourge unit hovertext, since it was confusing peoople. It was only ever a cosmetic thing.
** 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 dataStill not quite seeing it register yet, but we're getting close.
+
* Suppressed a pair of harmless-but-annoying exceptions that could show up in your log files if you were shutting down the game from the main menu in just the wrong way.  These were related to the Slate cutscenes trying to stop at the same time they were being eaten alive by your OS taking back its memoryAll is well, no need for a dying scream.
  
* The full suite of network logging has been integrated into our steam networking wrapper, now.
+
=== Fix To Ship Weapons Mismatch ===
  
* 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.
+
* Added a new ArcenNonTableUniqueStringList class, which we can now use for keeping lists of arbitrary string that we want to serialize.
 +
** We're going to be using this for entity systems.
  
* 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.
+
* EntitySystemTypeDataTable has been removed, and EntitySystemTypeData no longer inherits from ArcenDynamicTableRow.
** 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.
+
** This was really old logic, and is the one instance in the codebase of us really not using dynamic table rows properly.
 +
** The result was slow during startup, in the best of times, and more recently it has been actually scrambling up the data for systems between different ships!  That latter part may be new in the last few builds, or it might just be more common.  Either way, this has needed a shift for a while.
 +
** The EntitySystemTypeData no longer has an InternalName, but instead has InternalName_Original (which is just the raw xml name like FusionBomb), and then an InternalName_Longer (which is the entity type appended in front of it, like "Mugger_FusionBomb").
 +
** The new serialization for these by index uses the shorter name, which just makes savegames a bit smaller.  But it doesn't really matter what is used in the longer-term effect, because these are no longer stored in one central lookup.  They are now properly full sub-entities of the GameEntityType.
  
* 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 this change, shockingly, we have still NOT solved the issue of things like Mugger frigates sometimes getting Brawler weapons.  So that's going to need even more investigation.
** With LiteNetLib, that all flashes past so fast we could not tell that was even happeningWith Steam currently stalling out with the host not getting messages, it became apparent.
+
** This overall change is still worthwhile, as it shrinks future savegames a bit (not ones from prior versions saved in the new build, though), and it also makes loading the initial game program a bit faster and less prone to potential issues... despite still having this particular issue.
 +
** Note from later: this actually solved 90% of the problem, but there was still a case of us managing something slightly wrong that let it keep bleeding overSo the last 10% is below.
  
* Previously it was possible for our socket mode to be off, and silently ignoring messages we were sending.
+
* The "copy_from" tag, which was never used on entity systems inside an entity, and which probably would not have worked well there if it had, has been removed.
** 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.
+
* Fixed a bug where our "dump data tables on load" debug option was no longer working (the hotkey was, but not the on-start version).
** 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.
+
* Fixed a very peculiar issue that only affected a couple of unit in the prior version (in the main game and DLC, anyhow -- more may have been affected in mods) where if there was a unit that had its systems altered on a child, and there were then other co-children, the other children would sometimes get those altered stats and sometimes not.  Normally it should just pass to grandchildren and so forth, not to siblings.
** This helps us to find out where errors actually are.
+
** Essentially, the way that we handle partial records is normally very explicit  (is_partial_record="true").  And in fact, when we have a partial record like that, we WANT for it to inject itself into any other descendants later.
** 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.
+
** But in the case of entity systems, we have this kind of implicit "child partial record" system going on, where you just name the same system in the child as you had in the parent, and make some changes, and those changes then keep going in that lineage.
 +
** What we do NOT want to have happen is the siblings to also pick up those changes, which is what was sometimes happening here because of the funky way that we handle systems and systems alone in the game.
 +
** From looking at the raw data, without mods in play this mostly just affected muggers and brawlers, and a few spider turrets.  Most everything else was already consistent properly.  But if you play with mods on, you may have seen a lot of other chaos happening beyond these particular ones.
 +
** Thanks to crawlers, Ovalcircle, Spaz, Puffin, and Darkshade for reporting.
  
* Fixed a simple typo that was having us send a junk message via both frameworks to the client when they first connected.
+
=== Work To Allow Arbitrary Sprites In Game Text, Part 2 (Complete!) ===
** 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 ===
+
* The sprites in TextMeshPro have been updated so that their default index is 0, not -1.  That way if no sub-name or image is specified, we are still able to figure out where they are.
  
* "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 don't use the mspace monospacing markup, so we're keeping things simple and redefining that to mean "no advance"
** We are now bypassing that and using the raw internal transform offsets to calculate the correct camera position.
+
** This essentially lets us put <mspace>around things we want to all be on top of one another</mspace>, which is really useful for our compound icons.
  
* 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.
+
* Since we already use non-atlased sprites in every location in the UI, and have those present and available as needed, we're just going to go with that for the TextMeshPro sprite embeds as well.
** 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.
+
** There aren't any sprites that we only have in atlases but not also in asset bundles directly, although there are ones that are loose and not in bundles.
** 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.
+
** With that in mind, this lets us avoid the glyph metrics that were working so poorly with our sprite atlases, and the efficiency of the whole thing is not much changed given how compositing on the UI works and how infrequently (overall) we include extra sprites.
** 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.
+
** This actually turned out to be a particularly good move, because what we've discovered is that if there are two different sprites used in a single text area, the following happens:
** 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 haveFor 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.
+
*** The draw order is based on the order of the first sprite dictionary used that is shared, not the order of the sprites in the text.
** 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.
+
*** When multiple sprites are in one dictionary, this can lead to funky resultsWhen there are single sprites per dictionary, the only time this can mess up is when there is a single sprite used more than once AND you want them to overlap one another.
 +
*** It's worth noting that we don't care about the order of sprite drawing, normally, except for the new mspace markup.
  
* 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.
+
* The new custom TextMeshPro dll has been updated (by building the WorkingTextMeshPro project, as silly as that is) and the result has been put in ReliableDLLStorage so that we can compile against it and use those capabilities in ArcenUniversal, etc.
  
== Version 2.111 Initial Steam Connection ==
+
* The copies of TextMeshPro code for the other three main projects that use it have all been updated to match the new capabilities.
(Released July 30th, 2020)
+
** This won't work in the main game build until it actually has a build done, though.
  
* Fix a null reference exception in my new spire relic code
+
* Added a new TextEmbededSprite and TextEmbededSpriteTable table, which are in ArcenUniversal and PARTLY filled by xml entries from the new TextEmbededSprites folder.
** Thanks to Chuito12 for reporting
+
** The rest of these are able to be filled programmatically as we load sprites from other locations, specifically when it comes to ships by name.
 +
** The purpose of these are to define sprites that can be used inline in text for improved display purposes.  You can expect to see us doing more of this over time now that we finally have the capability.
 +
** It is possible for an auto-added sprite in here (such as for a specific unit type) to manually get some tweaks by adding xml for it.  The order of that happening does not matter, which makes the system extra flexible.
 +
*** This does mean that, because of the lack of order mattering, this table intentionally allows for malformed entries (those defining some metadata but having no actual sprite assigned).  That's a necessary byproduct, since other parts of the code are assumed to add those sprites later, but might not do so if they were themselves removed.
 +
** bundle_name and filename are optional, and specify the location of where to directly load the Unity Sprite or Texture2D from during game load.
 +
*** These are NOT used in cases where another class (like GameEntityTypeData) is creating new TextEmbededSprites on its own.  In those cases, the sprite or texture2D is sent from the other class.
 +
*** In the case where these ARE used, we need to know whether we can load it as a Sprite (ideal) or a Texture2D (slightly slower).  The xml tag bundle_target_is_texture2d defaults to false, and so tries to load the target as a sprite.  Anything used elsewhere in the UI would work this way.  But if you need to load a Texture2D and make a Unity Sprite out of it at runtime, you can set this to true.
  
* Nanocaust: Make the AI wait a bit longer before unleashing Exogalactic units on it. Remove some deprecated code
+
* Added a static CreateRuntimeSpriteFromTexture2D() method on the TextEmbededSpriteTable, which takes in a Texture2D and returns a Sprite.
** Also the exogalactic units won't hang around to kill the entire nanocaust, so there's a chance it can recover.
+
** This is something that is particularly useful, because it keeps track of ones that were previously created, and reuses them rather than creating extras.  This can only happen on the main thread.
  
=== Milestone: Initial Steam Networking Connection Between Client and Host ===
+
* About 50 initial sprites have been set up as text embedded sprites for use coming up.
 +
** There is more metadata that we want to get in there, plus some other things to make these as simple as possible to call on, and we need to actually cross-wire this to the new TextMeshPro stuff that we worked so hard on.  But that will come tomorrow.
  
* 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.
+
* Fixed the AIW2ModdingAndGUI project so that it now has the proper TextMeshPro code embedded within it and so that it won't erase our customizations every time it is reopened in the unity editor.
** 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 withThe claim is that their backbone is faster in most cases than the general internet one.
+
* Fixed the WorkingTextMeshPro project so that it now has the proper TextMeshPro code embedded within it and so that it won't erase our customizations every time it is reopened in the unity editorThis is how we build our custom variations on that code, and now we're not at risk of random regressions from unity package manager automatically wiping our changes.
** 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 ==
+
* The following float options are now available on any of the text embedded sprites for manipulating how they fit into the text they are embedded in:
(Released July 29th, 2020)
+
** x_draw_offset, y_draw_offset, width_draw_offset, height_draw_offset, advance_draw_offset.
 +
*** All of those do the basics of what you might thing in tems of adjusting how the sprite draws, while advance says how much space to go over before the next character draws (or how it plays into word-wrapping or whatever else).
 +
*** All of these are in fairly abstract units, where roughly something like 100 is about the height of a line, regardless of how many pixels that line actually is. 
 +
*** Most of the time you won't want to mess with these at all, but in some cases you may want to adjust the vertical centering by using y_draw_offset in particular.  Beyond that, most people would not use any of these.
 +
*** Frankly, to get the kerning of the strength icon working perfectly, we will probably add a few more dials to this soon.
  
* 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
+
* Our TextEmbededSprite sprites are actually loaded up into TextMeshPro sprites now, completing the main integration of arbitrary sprites.
** Thanks to Lord of Nothing for suggesting
 
  
* All of the units that were previously named "Galactic War [name]" are now just named "[name]"
+
* default_color_hex is a new string option available on the text embedded sprites, for allowing a default color to be applied to sprites.
** 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.
+
** Please note that, unlike sprites we had in the past that were based on vectorized glyphs inserted into a wingdings-like font, these sprites can be full-color to begin with.
** This lets us keep the shorter name, while making their sub-group and source a lot more clear.
+
** The one "downside" is that these sprites can't be infinitely zoomed-in-on like a font, but that's hardly a downside given that we could render these crisply on an 8K monitor or more.
** 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.
+
** The default text colors are nice for purposes of things like resource icons that are embedded in text.
** 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.
+
* For now, ArcenFormatting has been updated to stop using the old font-based resource sprites, and now use the new TextEmbededSprite sprites.
 +
** This is a major jump up in quality in general.  Also, now all of the resource icons properly match all throughout the GUI.
 +
** One thing to note, however, is that these sprites no longer inherit the color from their parent font.
 +
*** So, in order to match the text color properly, we needed to add ArcenExternalUIUtilities.GetStrengthIconWithColor_Wasteful(), which hits the garbage colletor, and ArcenExternalUIUtilities.WriteStrengthIconWithColor(), which does not (use the latter if at all possible).
  
* Remove some inaccurate description text for the Rorqual Hejira
+
=== Main Menu Further Refinement And Expansion Logos ===
** Thanks to GreatYng for reporting
 
  
=== UI for Steam Networking ===
+
* The planet that scrolls by in the background of the main menu sometimes has been removed, as it was having some glitchy effects on it that we definitely did not want.  In the end, we don't really need the planet in order for this to be a very interesting scene as it is.
 +
** Thanks to Badger and others for reporting the problem.
  
* 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.
+
* The material properties of the main game logo have been updated substantially so that they look more natural in the light and shadow of the main game.
** 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.
+
** Thanks to Badger for suggesting.
  
* Started building out the Steam networking framework layer, currently based on the ISteamNetworking implementation that most games use.
+
* The main menu now has logos for all three of the current and upcoming expansions, and they are more lit-up if they are on (installed and enabled).
** 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.
+
** If they are not installed or not enabled at the moment, then they show much darker, but still with reflectivity of lights passing by.
** 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.
+
** Videos made during the making of this: https://youtu.be/p73bPBFsgoI and followup: https://youtu.be/K-uvfTH9tgk
  
* 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.
+
* The AIWarExternalCode library now links against ArcenThirdPartyCode so that it's able to make changes to certain things in the front-end game.
** 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.
+
* The main menu now uses a hook to go in and find our custom BetterRotationScript on the background that spins the space skybox, and slows it down substantially compared to prior releases.  This saves us the wait of a 40-minute rebuild process, and in theory actually would let us have a variety of random rotations if we felt like it.
 +
** Thanks to Badger and Asteroid for suggesting.
  
* There is now a screen that will be used for Steam and GOG connections, from the client side, and in Steam it now:
+
* In fact, since we can, the rotation of the stars in the main menu is now entirely random, but at a much lower overall speed than it was before.  It can rotate at a combined maximum velocity that is still only 3/4 of what the prior maximum speed was, and almost all of the time it will be vastly smaller than that.
** 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 ==
+
== Version 2.629 Ship Cap Hotfix ==
(Released July 28th, 2020)
+
(Released November 10th, 2020)
  
* Completely rework the way Exogalatic strikeforce leaders work, to allow per-AI-Type customization. No functional change right now, but intended to support some new AI types for DLC2
+
* Corrected the OpenGL launcher script on GOG, thanks to GOG support (it was our error -- thanks to them for figuring it out!).
 +
** It appears that the issue didn't affect all flavors of linux, but it certainly did affect some.
 +
** Thanks to rudhek for reporting.
  
* 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.
+
* A simple typo was breaking all of the xml parsing for sub-lists of data of the following types (unless they had the requirement of IsUnique on): fint, arcenpoint, vector2, vector3,  
 +
** Most of these were new or unused in general, but fint was not new and is used for the scaling of ship caps in the game, as well as for the engine stun seconds progression.
 +
** All of our other list parsing, which are more commonly used, were all working fine.
 +
** Thanks to Wuffell, ArnaudB, ThyReaper, and other for reporting.
  
* 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.
+
== Version 2.628 Mod Proliferation ==
** Thanks to Badger for reporting.
+
(Released November 9th, 2020)
  
* Added a new UI feature that is a throwback to some of the functionality we had in various past games: the "center screen message"
+
* Fixed a bug where the Tame Macrophage Hack was not correctly responding on certain Quickstarts.
** 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.
+
** In actuality, the Enraged subfaction was entirely missing from those quickstarts! Very bizarre.
** It won't block the mouse, and it is over everything except modal popups and tooltips.
+
*** Thanks to Smidlee and Metrekec for the bug report and saves for testing, and StarKelp for fixing.
** 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.
+
* Fixed Cloaked Transport Flagships from starting fleets having the default transport direct tech upgrade costs instead of the higher ones that captured cloaked transports do.
** 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 NR SirLimbo for fixing.
** 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
+
* Adjusted the amount of Combat Engineers Support Factories get for both starter fleets and captured fleets, balancing them a bit and bringing both spawned and captured fleets more in line:
** Thanks to GreatYng for reporting and StarKelp for the fix.
+
** Rejuvinator: 8-13 (starter fleet remains at 10)
 +
** Overloader: 4-7 (starter fleet changed from 3 to 6)
 +
** Everything else stays the same, but the Combat Factory starter fleet goes up from 6 to 8 engineers
 +
** This hopefully kills the bug where Combat Fleets spawn in with 2 Sentry Frigates too.
 +
** Thanks to NR SirLimbo for making these changes.
  
* The in-game credits have been updated to include two more individuals who are key DLC2 testers.
+
* Added 2 more tiers to Metabolization and Greater Metabolization in preparation to additions to ESV.
 +
** To clarify: This is NO new types of Metabolization but simply new conversion ratios damage/shot -> Metabolization points. By default Gangsaws for example deal 10x as many Metabolization points as they dealt damage.
 +
** The new tiers are "BigMajor" for a conversion ratio of 5x, and "SupportWithoutDPS" for a conversion ratio of 50x.
 +
** Thanks to NR SirLimbo for adding.
  
* 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.
+
* Some minor buffs to Shark B
** 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
+
* Fix a typo in the Mesopotamia planet list description
 
** Thanks to Lord of Nothing for reporting
 
** Thanks to Lord of Nothing for reporting
  
* Fix a typo, "reciever" to "receiver"
+
=== Included Mod Updates And Additions ===
** Thanks to Apthorpe for reporting
+
 
 +
* For modders reference: rename BadgerFactionUtilityMethods to FactionUtilityMethods.
 +
 
 +
* Disabled mods and/or expansions that are installed on your machine no longer temporarily show up as enabled for just a few moments during the initial load of the game.  That was confusing.
 +
** The Settings from any installed-but-disabled mods and expansions ARE loaded, so that those can be kept properly if you are enabling and disabling mods over time, but those are the only parts loaded when they are disabled.
 +
 
 +
* KM / AMU mod fixes:
 +
** Fixed a very strange bug about fireteam debugging where for some reason it couldn't find the Fireteam.GetDangerOfPath() function.
 +
** Hopefully fixed another very strange null ref exception in the Marauder LRP
 +
 
 +
* Civilian Industries mod:
 +
** Fixed a bug where Fireteams were being rude and not letting civilians use their danger pathing code.
 +
** Optimized a few pieces of code to hopefully help with the performance issues some people have been recently having.
 +
 
 +
* Fixed a literal 1-symbol-bug in Kaizers Marauders where they would not accumulate AIP but instead reset their AIP to the most recent increase.
 +
** This also lead to the discovery of a bug for the Debug Mode where Marauders produce and use real AIP that multiply AIP by the number of AIs present.
 +
** Thanks to ussdefiant60 for noticing.
 +
 
 +
* New content for the Extended Ship Variants mod and its counterpart for Fallen Spire. Do note that the latter now requires the base ESV installed!
 +
** Extended Ship Variants:
 +
*** Added 4 new types of Transport Flagships: Engineering (hybrid between a stronger engineer and a transport), Vanguard (hybrid between a Vanguard and a transport), Tugboat (has small drones accelerating everything to at least 700 speed and can slow down enemies) and Target Painter (long-range beam that amplifies damage dealt to a single enemies)
 +
*** Added 3 more types of Mobile Factories: Metabolizing (launches Metabolizing drones), Rescue (creates rescue-beacons that can revive ships), Translocator (good AoE explosion that pushes small ships back and paralyzes them)
 +
*** Added 6 new mobile starter fleets with ESV ships and transports included into them.
 +
*** Added 5 new support starter fleets, 3 with ESV mobile factories and 2 with vanilla mobile factories that did not have a starter fleet before
 +
*** Buffed the Agile Transport: +25% speed on entering a new planet for 5 seconds, -50% damage if attacked from >= 5000 distance, 21 gx engine to resist Black Hole machines
 +
** Extended Ship Variants for Fallen Spire:
 +
*** New Transport Flagship: Cyber Command (reduced hacking response, much more expensive, much more fragile hull but decent shields)
 +
*** New Mobile Factory: Acidic (launches drones spreading acid onto enemies)
 +
*** New Mobile Starter Fleet: Hacker Fleet (designed to deal with AI hacking responses)
 +
*** New Support Starter Fleet: Combat Engineers and Acidic Factory
  
=== UI Changes ===
+
* Increased the timer on Kaizer's derelict to allow for a longer time period to save him. Instead of 1% health per second he now loses only 0.3%, which grants 334 instead of 100 seconds time to save him if the player so desires.
 +
** From a discussion with SilverLight on Discord.
  
* In the Load Menu, campaigns are now sorted by 'most recent save game in that campaign' rather than alphabetically
+
* Updated Kaizers Marauders to be compatible with this new AIW2 version (no functional change) so players should be able to hop back in as soon as the update drops, without having to wait for an update of the mod in response to an update of the game itself.
** Thanks to Puppet Master for the suggestion.
+
** Updated the source files on AMU.
 +
** Worth noting that the Civilian Industries mod did not actually need an update for this new version because it didn't happen to be using the features that changed.  
  
* The default sort for the load menu is now by date.
+
* Fixed a type mismatch now exposed through the new External Constant Loading in Kaizers Marauders: AIAlliedInvertedTechBonusFactor was declared as FInt, but loaded as int. Is now also declared an int so it works.
 +
** Curiously this didn't seem to have any impact on the mod in any way... Strange, but ok.
  
* 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
+
* ExampleMod and ExampleMod2 have both been removed from the game, as they were utterly pointless at this point.
** Note that internally the code uses the old names for the moment
+
** There are more and better ACTUAL mods of all sorts for you to look at if you're thinking of getting into modding.
** Thanks to a discord conversation involving relmz32, Oryutzen and NRSirLimbo
 
  
=== Dyson Sphere Buffs ===
+
==== New Micro Mod Collection By NR SirLimbo! ====
  
* The Dyson Sphere's ships should now really level up after the hack
+
* Added the Micro Mod Collection mod to the off-by-default mods.
** Thanks to GreatYng and zeusalmighty for the bug reports
+
* Currently adds:
 +
** 4 types of Distribution Nodes: 6m metal for 1 AIP, 45 hacking points for 2 AIP, 3k science points for 3 AIP, 4m metal/30 hacking points/2k science points for 4 AIP.
 +
** Energy Converters (10 for Home Command, 5 for every Economic Command Station) that convert 50k energy to 150 metal/second
 +
** Research Expedition: Mobile science/hacking gatherer that can speed up gain on owned planets but also extract from allied/neutral worlds, scout adjacent planets and at higher levels decloak/cloak itself. Fragile, high-priority target for the AI, producing 20 AIP on death.
 +
** Reinforcement Seeder: AI ship dropping Minor Reinforcement Warp Gates that increase planetary reinforcements by 5% per gate.
 +
** 3 types of AI Command Stations with escalating levels of strength: Gravitic (slow aura), Tachyon (decloaking aura) and Pulsar (periodic paralysis aura).
 +
* Balance and general feedback required and sought after!
  
* Dyson Sphere hack descriptions now say "This hack will make the Dyson Sphere very unhappy with you for a while" to clarify the behaviour.
+
=== Work To Allow Arbitrary Sprites In Game Text, Part 1 ===
** 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
+
* Added a working testing project for altering TextMeshPro, while retaining compatibility with all the various unity scenarios in which we use it.
 +
** Attempted three different ways of updating it to have new sprite embeds, but so far those methods were all a bust.  Going to try another method of injecting our own sprites, instead, and for that we need to start basing our things on having some sprites and then shoving them in.  Thankfully we have a nice little isolated test project for this, which now has some added info in it.
  
=== Multiplayer Work ===
+
* Added some code in ArcenXml that lets us parse xml directly from TextAssets, mainly for testing.
 +
** This is also used now in parsing the sprite dictionaries that we are creating via TexturePacker.
 +
** Also set things up so that we can now have sprite dictionaries that are a single sprite loaded directly from a unity-style sprite with borders, etc, intact.
 +
*** This is useful for some of the other new icons-in-text that we want to do.
 +
** The general purpose of this is partly for test loading sprites of two different categories in a way that we can start trying to get them into TextMeshPro programmatically, but this also would be used long-term once the testing phase is past.
  
* SendMessageToAllClients() has been split into two methods: SendMessageToAllClientsWhoAreFullyConnected() and SendMessageToAllClientsRegardlessOfConnectionStatus().
+
* Made a change that makes it so that if a sprite material is destroyed (such as one that was created at runtime in the unity editor) it will now just display as a blank image rather than throwing errors inside TextMeshProUGUI.  This is mostly helpful for our own internal testing of our injection of our custom sprites into TextMeshPro's rendering pipeline.
** 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)/
+
* References to ArcenSprites are now stored on their parent ExternalIconDictionary.
** 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.
+
** We never needed this before, but now that we are translating entire dictionaries into use for TextMeshPro, it's a thing.
  
* 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.
+
* TextMeshPro has been expanded to allow for us to inject our own images at runtime, from any source (not just Resources, but rather asset bundles and whatever else).
** 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.
+
** We can inject unity Sprite objects, unity Texture2Ds, and our own custom ArcenSprites in their entire ExternalIconDictionary.
 +
** This new capability is set up so that we can also control things like how they are scaled and offset, and essentially how the kerning works.
 +
** Whether we use all those features or not is not really relevant, but it's good to have options.
 +
** This is far more powerful than our old method of drawing images in text in TextMeshPro, which was limited to a special "Arcen Icons" font where we had vectorized some of our icons into a font format and were using that to draw icons.
 +
*** In some respects that was nice because that gave us infinite zoom on those icons, and now we're using raster images with a fixed maximum resolution, but those other icons really did not behave well when it came to trying to line up with varied fonts.  Often the offsets and kerning were terrible, and updating them at all required a rebuild of the central game executable, which is time-consuming to say the least (that's about a 40 minute wait).
 +
** This new approach allows for images to be inserted into text by mods, let alone just our own code.
  
* 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.
+
* We don't yet have the new TextMeshPro stuff integrated into the main game, but it should be tomorrow.
** 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.
+
** For now, we've got our new data formats and are testing the last of the capabilities we need, and trying to make sure that our sprite dictionaries translate properly to theirs, which is so far not quite working right but getting close.  Single images are working great.
** 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 ===
+
=== Giant Overhaul Of Xml Parsing For Accuracy And Speed ===
  
* 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.
+
* exclude_children_from_copy was not an xml feature we were using, and it was slowing down xml parsing in general, so we've removed it.
** 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.
+
* The way that child nodes and attributes are determined to NOT be copied in xml is now vastly more efficient, and doesn't involve any GC churn.
** 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.
+
** This should lead to more accuracy when we pair it with some other changes, as well as faster loading times in general once we finish with our changes.
** 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().
+
* Really substantial xml processing speed improvements during game load.  These have to do with our checks to make sure that the xml is correctly formatting and we are importing all the proper nodes.
  
* Added a new SendToSpecificPeer() method onto LiteNet's NetManager.  Not sure why that variant didn't seem to exist.
+
* The way that attribute-checking is logged and verified is now vastly more efficient than it was, so again loading is faster in the initial part of the game.
  
* Wiring back up our LitNetSocket wrapper class:
+
* The xml parsers that were able to give back a list of children no longer do; there are instead DoForChildren methods that don't require a hit to the garbage collector, and which also make it so that they don't have to be wrappered more than once.
** SendMessageToHost_Inner() done.
+
** This is substantially more efficient in several ways.
** 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.
+
* Instead of copying xml attributes and nodes from parents to children in partial records and copy-from records, these are now linked, and calls like GetBool() and similar are able to process through them much faster and with accuracy.
** 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.
+
* Added a new EqualsCaseInvariant() overload to strings based on ArcenUniversal.
 +
** It turns out that this is very slightly more efficient than doing a ToLower() and comparison to the lower-case version.
  
=== Continued Multiplayer Work ===
+
* Our xml parsing now gives visible errors when trying to parse integers that are not valid integers.  Before, it was just failing silently and returning the default value.
 +
** GetInt32List was removed from our xml parsing, as it was inefficient and not something we've been using in AI War 2 in general.  This was generally used in some of our older titles.
 +
*** Same with GetInt16List, GetByteList, and GetFloatList.
 +
** Also, a variety of duplicative methods that were concerned with complaining if a value was missing-or-default have been folded into the main methods for getting from xml.  We also now only complain if the value is outright missing, as in basically any case where the default value is specified that is an intentional thing.
 +
*** We have now removed the ComplainIfAttributeNotFound() method, since that was only used when we were looking at complaints about "missing or default, but actually default is fine."  This makes for far cleaner code.
  
* A fair bit of work has been done to make intentional disconnections from the client or server tell the other side more quickly.
+
* Our xml parsing of vector3s is now much more efficient, although we do not process those very often anyway.
** This should help to avoid some disconnect-and-reconnect issues that are otherwise inevitable, and it just makes things feel more responsive.
+
** Our xml parsing of FInts is now a bit more efficient, and that is processed extremely often.
 +
** Our xml parsing of enums is now a bit more efficient, and more normalized (same with FInt actually), as these are processed very frequently.
 +
*** One change that may affect mods is that FillEnumIfPresent has been removed, and is now just FillEnum.  Assuming you pass in false to ComplainIfMissing, it will act as you previously experienced.
 +
*** Another is that FillEnumAndComplainIfDefault has been removed, so now you'd just use FillEnum and pass in ComplainIfMissing as true.
 +
**** This is technically a difference in functionality, because this only checks to see if something is missing, not if it has a default value (usually None or whatever).
 +
**** Generally speaking, our experience has been that if someone sets up a default value in xml explicitly, then they probably have a reason to do so.  We've been having to work around this with reading in xml in general, and now it doesn't complain about explicitly-set defaults with other data types, either.
 +
**** This should not negatively affect anything current, as any xml that was "invalid" by the old standard would have been complained-about already and preventing clean game launch.  Any new xml that is created in such a fashion is probably on purpose.
 +
*** We also got rid of GetStringAndComplainIfMissing(), which had basically the same sort of issues.  Just use GetString() or FillString() and complain if it's missing, but if someone sent in an empty string from xml, they probably meant to.
  
* 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.
+
* The way that we were previously handling "custom data sets" on xml rows was incredibly slow as well as kind of brittle, particularly when it came to modding.
** This should hopefully help with any cases of the game still being thought to be running on Steam in particular after it closed.
+
** This is seeing an entire rework, with the pattern for getting custom data becoming far simpler (but also more powerful, as mods and copy-from and partial records will now work correctly in all cases).
 +
** First of all, the CustomDataSet class and all its methods have been removed in general.  ParseCustomDataIntoSet() and GetCustomAttributeNames() have also been removed.  Also the CustomDataLookup class.
 +
** Custom attributes are instead something that code is able to parse as-needed later on from the xml, and the "requested attributes" code just ignores anything that begins with "custom_"
  
* When you exit the game, while it is doing its brief exiting stuff it now throws up a center-screen "exiting.." message.
+
* The ExternalCoreConstants, which was not actually used for anything, has been removed.
  
* Got rid of OnServer_WaitingOnConnectionIndices, as this was basically a duplicate of something we are doing better and more cleanly a new way, now.
+
* Vector2 xml processing is now consistent with Vector3, whereas before it had only a subset of the capabilities.
 +
** Same with ArcenPoint.
 +
** AngleDegrees has instead just been removed, as it's not something we use and we can store that in different formats more easily.
 +
** Loading DynamicTableRows from xml has also been given full parity, and in addition to that they are now able to take empty commands now to set null instead of the prior row reference.  This is a new ability.
  
* UpdateDebugText() and all of its related variables have been removed.
+
* We were previously using various forms of XmlElement (which is a built-in-class) manipulation in order to handle copy-from and partial records cases.
** 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.
+
** This was not appearing to work as expected, and at any rate is generally something that is probably pretty slow.
 +
** We are removing our TotallyReplaceContentsOf, CopyAttributesIntoBlanksOf, and CopyChildrenTo methods entirely.
 +
*** The CopyChildrenTo, which affects child nodes, had some notable strangeness that it was overcoming when nodes were being copied from one document to another (aka two different xml files)We just don't need that sort of hassle.
  
* Got rid of WorldTransmissionMessageType, as it was needlessly complicated.
+
* The ArcenXMLElement RawElement entry on ArcenDynamicTableRows has been renamed to be OriginalXmlData instead.
** This was essentially us breaking the world transmission data into multiple parts and then sending those in partsHistorically there were two reasons for this:
+
** This is far more clear, and is going to be very key for the later forms of parsing that we're doing.
*** 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 paceNetwork cards have grown enormously in the last 11 years, as have the OSes that control them, so that's not really a concern nowAll of the newer network libraries that we would be using to send data should be able to handle 1MB of data without incident.
+
** ArcenXmlElements now have private DirectParentsICopiedFrom and PartialRecordsLaterAppliedToMeInOrder variables that get set as-neededInternal processing handles these properly so that end-user modders or developers don't have to think about these details.
*** 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.
+
*** These help to ensure that data is applied in the correct order, as intended, and that the data can be reconstructed as needed.
 +
** HasAttribute() has been removed from ArcenXMLElement, and instead we have GetMostRecentAttributeValueIncludingParentsAndPartials() and GetMostRecentAttributeValueFromSelfOnly().
 +
*** This will seem inconvenient in a variety of places for modders, but it saves us a ton of extra read calls into a potentially expensive method (especially now that we properly handle xml inheritance)Just read the value once, if it's a string, and if it's blank or null then that's your answer.  Or use any of the fill methods and just say you don't mind blank entries (or only do if it's not a partial record, your choice)It will fill things properly.
 +
** During the read of nodes, it now causes either RegisterMyDirectParentsICopiedFrom() or RegisterAPartialRecordAppliedToMe() to be called, and/or OriginalXmlData to be set.
 +
*** From looking at this, in the past versions, most likely OriginalXmlData (aka RawElement) was probably being overwritten improperly once a partial record was applied, and this was probably where our errors were coming from in parsing certain mods.
 +
** Additionally, if a single xml record is defined as being both a partial record and a copy-from record, it will now throw an exceptionThat should not have actually been the case on any, but now it should check on them properly.
  
* 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 statusUsually 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.
+
* On ArcenAbstractExternalData and its descendant classes, like ExternalConstants for instance, there is now an ArcenXMLElement OriginalXmlData property.
 +
** This one works just like the one on rows, although in this case it's just used for partial records, mainly (there are not child nodes, and there's only one root node in these files).
 +
** This then lets us make direct calls to GetCustomFInt_Slow() on the ExternalConstants singleton and similar in order to get "custom" xml data that is added belatedly, as we see for a lot of the faction data and mod data.
 +
** This particular change will require changes to most mods, as the CustomData by namespace and all that is replaced by far more direct and efficient calls here, nowThough if the results are checked with any frequency, you should still be caching them for sure.
 +
** We are using wrappered methods, rather than giving direct access to OriginalXmlData, in order to control error handling and make sure that if your mod is looking for a field and fails to find it, it will yell.
 +
*** Bear in mind these particular fields are not found at game launch, but rather whenever the faction or mod initializes.  So typos are likely to be cause errors during first unpause with a faction present, rather than during load of the initial game like everything else.
 +
*** The extra error handling that is in this is absolute crazy, incidentally, so if you're not getting the result you expect, then you automatically get an entry in the log with the details of what was present so that you can figure out what your typo was.
  
* The host now properly sends the world data to the client, for the first time in three years or so.
+
* With external constants and similar dictionaries, it now ensures that the base data is now read in before any partial records are read.
** 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).
+
** It seems like someone was referring to this being hard to mod, and this would likely solve that.  At any rate, with our new more-strict reading this also became needed in general.
  
* 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 thingsThese can be echoed to all other clients or not, as the case warrants.
+
* With the new XML parsing, the game does a far better job of reporting problematic data from xml (aka something like a floating point number being imported into an integer field).
 +
** Why this was not working properly before is a bit of a mystery, but it works now, which is the important thing.
 +
** There were several bits of rogue data that we've thus fixed, including the amount of extra intensity the scourge gets from human science amountsThis may have some balance impact on the scourge, as those values were probably previously reading in as zero.
  
* 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.
+
* Full list of data fields now corrected that were previously not reading in properly and thus probably affecting faction performance in some fashion:
** This way we can solve whatever the problem is, and nobody is left sitting wondering why things are slow (when in fact they errored).
+
** Scourge difficulty:
 +
*** AllowedBuildersIncreasePerScienceUnit (was always 0 because of type mismatch)
 +
*** BuilderIncomeIncreasePerScienceUnit (was always 0 because of type mismatch)
 +
*** SpawnerIncomeIncreasePerScienceUnit (was always 0 because of type mismatch)
 +
** Human Resistance Fighters
 +
*** RatioForFriendlyPlanet (was always 0 because of a typo - RxatioForFriendlyPlanet)
  
* 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!
+
* In the event of partially-mangled data from entity systems, the game now does a bit better job of reporting clearly what the problem is with the xml and setting some general defaults rather than just starting in a completely invalid state.
** 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.
+
** This is most notably with a missing range being set on a system.
** 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."
+
** Additionally, we've added a new WriteSystemDataToLogDueToError() onto GameEntityTypeData, to let us see what the state of all systems on an entity are when a problem arises.
*** 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 zoneWe didn't use this anywhere else, and it was puzzling that we used it at all.
+
* There was some funkiness in how some of the passive systems were looking for ranges that they did not need to have, in ComputeBalanceStats_OneTimeOnly(). Those have been corrected/
 +
** This is a case where we wonder how this was not causing errors in the past, but whateverAgain, it works now.
  
* NatPunchEnabled is now true on the server and client for LiteNetLib. We'll see how well that works.
+
* Further cases of fields that had malformed xml and thus did not read in properly:
 +
** Settings:
 +
*** Windowed Mode Window Height maximum (typo of case Max instead of max led to it being infinite rather than 7000).
 +
*** Kaizer's Marauders Marauder_DebugID, same typo of Max.
 +
*** Hidden field of FullscreenHeight, same typo of Max.
 +
*** Kaizer's Marauders Marauder_FireteamDetailLevel, same typo of Max.
 +
** AI Types:
 +
*** SimpleEnsemble was not having its type_Difficulty read in, because it should have been type_difficulty
  
* Added a new debug setting to the network section of the settings menu: Write Network World Serialization Logs
+
* The game now allows any fullscreen resolutions that your OS/hardware reports as being available.
** 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.
+
== Version 2.627 Hotfix ==
** 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.
+
(Released November 5th, 2020)
** 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 ===
+
* Hopefully make Warden fleet ships less likely to turn to the Hunter when in combat
 +
** Noticed by a lot of people
  
* Milestone! Initial transmission of the world data from the client to the host now works properly.
+
* Make reconquista a bit less one-dimensional.
  
* When a local player account is missing the following methods no longer throw errors:
+
* Fix a bug where the galaxy map was showing the wrong faction colour for enemy units.
** 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().
+
* Fixed a bug in the prior version where the scrollbars and scrolling in any dropdowns was not working.
** 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.
+
** Thanks to JonnyH13, Karchedon, and Badger for reporting.
  
* 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.
+
* The selected status of the stance buttons in the bottom left of the screen have been adjusted once again in order to be dimmer and less distracting.
** 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.
+
** Thanks to Metrekec and crawlers for reporting.
  
* 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.
+
* Balance Adjustments to Kaizers Marauders:
** And of course all the more complicated permutations of this. It's the new FromServerToClient_SendNewPlayerProfile.
+
** Changed the budget income modifiers per intensity to be based off the 0.4 + (AI income/1.5):
** 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.
+
** Also increased higher-intensity base defense buildup cap: Medium Intensity from 40 strength to 50 strength, High Intensity from 70 strength to 125 strength to make them more defensive.
 +
** When their budget was increased gradually to compensate for the high growth of strength that high-ranking AIs had it made them too powerful when fighting lower-intensity AIs.
 +
** Now, hopefully, Kaizers Marauder intensity roughly follows the same scaling as AI difficulty, but lower ranks are still supposed to expand further and by comparison are stronger.
 +
** When picking the intensity for Kaizers Marauders I suggest: Think about their most likely adversary (the AI) and their difficulty as a base line, potentially increase to compensate higher-difficulty AI types and other minor factions to fight.
 +
** Kaizers Marauders definitely need balancing feedback!
  
* Clients connecting to a host are now properly told what playeraccount they have been put in charge of.
+
== Version 2.626 Kaizer's Marauders ==
** This makes PlayerAccount.Local not null on their local machine, and lets them give orders and whatnot from their spot there.
+
(Released November 4th, 2020)
  
* Errors that happen during the main sim step will now be more visible in multiplayer contexts.
+
* Underlying mechanics now available for mods, but not used by any units at the moment:
 +
** Added the Classic (AI War 1 style) Hydra regeneration and Hydra Head mechanics.
 +
*** Regeneration is done with: seconds_to_fully_regenerate_hull="" and starts after the normal repair delay.
 +
***  Hydra Heads are done with build_points_per_damage_taken="" and unit_to_make_with_build_points_from_damage_taken=""
 +
*** A head will spawn when build points = total health, / current mark + 1. So a MK1 unit will spawn 1 head at 50% health, a MK2 will spawn every 33%, MK3 every 25%, so on.
 +
*** Current bugs with Hydra Heads: Build points are not serialised and so are lost on load. If a unit with a damage bonus shoots one of these, only the base damage adds to Build Points, not the bonus.
 +
** Thanks to Puffin for adding this.
 +
 
 +
* Drone Fleets (Support Fleets, but most importantly Hive Golems) will now load their drones if ordered so even if enemies are on the planet left.
 +
** Thanks to NR SirLimbo for implementing.
 +
 
 +
* Journals now allow for the insertion of [playername] in them.
 +
** Thanks to Badger for adding.
 +
 
 +
* The FRS now uses a different icon from ARS, to avoid confusion and make it clear what is what.
 +
** Thanks to Badger for suggesting.
 +
 
 +
* Combat Factories of all sorts no longer use normal drones like before (those aggro guard posts in an annoying way).
 +
** Instead, hidden drone launchers trigger if there are enemies within a certain range of the combat factories.  Letting them defend themselves, but not aggro enemy guards just by being on their planet.
 +
** It's worth noting that existing savegames will still have both kinds of drones present -- those in the fleet, and those from the launchers.  So they will be double-powerful but still annoying.  Any new campaigns will just have the launchers properly.
 +
** Thanks to several people for bringing up this issue with combat factories, and Puffin for helping fix it.
 +
 
 +
=== UI Reskinning Part 4 ===
 +
 
 +
* There are still some little things we want to do with the UI, mostly in the "nice to have" category.  The general overhaul is complete, in terms of improving things that were already there.
 +
** There are a VERY few cases where the old resource icons are used in text, but that should still be easy enough to figure out.  We're going to sort that out with new icon-embedding capabilities sooner than later.
 +
 
 +
* Fixed an issue where the border bar on the selected ships window would move up and down as that window got larger or smaller.
 +
** Thanks to Badger for reporting.
  
=== Milestone: Initial Sharing Of Lobby Between Host And Client ===
+
* The glowing states of the following icons in the new UI has been dimmed some:
 +
** Attack move (leftmost item), pursuit mode, stop and shoot mode, hold fire mode, scrap button.  Group move has been left alone.
 +
** Thanks to Metrekec, crawlers, and Isiel for suggesting.
  
* 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.
+
* We missed updating the map tab left panel in the lobby, but it now has a proper background and fonts.
** 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.
+
* Updated some prefab buttons so that things like the font in the Tips window now use the expected new font.
** 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.
+
* The visual style of dropdowns in the game has been updated to match the new style of buttons and other elements, and looks much more sleek.
  
* 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.
+
* The visual style of horizontal sliders in the game has also been updated to match the rest of the new stuff.
** 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.
+
* The tooltip backgrounds have in general been updated to look more like the rest of the new UI.
 +
** We are opting not to do specific graphics for the planets versus the ships, at least not built into the UI panels per se.  We'll handle that stuff via image insertion in text, most likely.
  
* 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.
+
* The icons for metal harvesters, and energy generation sources, have been updated to the new icons.
 +
** Same with science (not used as a ship icon anyhow) and "metal to energy," which is.
  
* In multiplayer games, the save button is now disabled and says: Cannot Save Game As Client
+
* Color improvements to notifications in the top bar.
** If you click it, it gives you this message: Unfortunately, only the host can save games in multiplayerTo save on bandwidth as well as on processing power between your machines, there is a LOT that is calculated only on the host machineIf 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.
+
** Essentially, notification colors being based on the faction that is discussed is something that looks like it means something else.  It looks like red is extra bad, or things like that.  We are using color to mean something with the backgrounds and icons up there, and so the text also having color is just problematic unfortunately.
 +
** We are largely moving the color that was on the text to instead be in the tooltip text.
 +
** Astro train faction color moved from notification text to tooltip text for notification.
 +
*** Ditto Dark Spire VG notification, although the timer colors are still there.
 +
*** Ditto Dark Spire Loci notification.
 +
** Things were fully changed with the color from the tooltip for the Dyson Antagonizer.
 +
*** Ditto exostrikes.
 +
*** Ditto exogalactic wormholes.
 +
*** Ditto AI eyes.
 +
*** Ditto raid engines.
 +
*** Ditto instigator bases.
 +
*** Ditto Zenith Trader.
 +
*** Ditto macrophages.
 +
*** Ditto AI relic trains.
 +
*** This was done previously for the Devourer.
 +
*** Relic search was already fine.
 +
*** Debris was already fine.
 +
*** Imperial Spire was already fine.
 +
*** Brownout was already fine.
 +
*** Nemesis was already fine.
 +
*** DLC2 AT civil war was already fine.
 +
*** DLC2 Nm were already fine.
 +
*** DLC2 Zm were already fine.
 +
*** DLC2 Zb were already fine.
 +
** AI Reserves are keeping their colors for now, in their countdown timer, but if it looks bad or you have feedback on them, please let us know with a savegame.
 +
*** The same is true for counterattacks.  Additionally, the icon on these grays out when the counterattack is stalling.  This may be confusing people, so we may change this up some.
 +
*** The same is true for hacking notifications.  Please let us know if the timer colors look tacky, but the faction bit got moved.
 +
*** Also same for risk analyzers.
 +
** The planet attack notifications actually show the colors of the attacker and the defender, so keeping those makes a fair bit of senseLet us know if it looks awful sometimes.
 +
** DLC2 AT warnings had some mild colorization based on severity, but we were already handling that with the background in recent versions, so the text color is now just always white.
 +
** Overall we need to do more things with the notification icons themselves very soonThis has been on our list since prior to DLC1.
  
* Additionally, autosave is now something that does not happen on multiplayer clients.  Just the host.
+
=== Additional Space Backgrounds By Puffin ===
  
* The header of the load quickstart and load saved game menus now make it clear if you are loading for multiplayer or single-player.
+
* Thirty new space box backgrounds for planets created by Puffin have been added to the game.
** 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.
+
* Six new space box backgrounds for the galaxy map created by Puffin have been added to the game.
  
* 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.
+
=== Revised AIP Mark Level Thresholds By Difficulty ===
** 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).
+
* The AIP amount required for an AI to go to a higher level used to be as follows: https://bugtracker.arcengames.com/file_download.php?file_id=15174&type=bug
** This also lets us put extra information on that screen to help anyone who might be confused.
+
** We are making the following changes:
 +
*** Mark 3:
 +
**** Diff 4: 295 from 305
 +
**** Diff 5: 275 from 295
 +
**** Diff 6: 255 from 285
 +
**** Diff 7: 235 from 275
 +
**** Diff 8: 215 from 265
 +
**** Diff 9: 195 from 255
 +
**** Diff 10: 175 from 245
 +
*** Mark 4:
 +
**** Diff 4: 470 from 480
 +
**** Diff 5: 450 from 470
 +
**** Diff 6: 430 from 460
 +
**** Diff 7: 410 from 450
 +
**** Diff 8: 390 from 440
 +
**** Diff 9: 370 from 410
 +
**** Diff 10: 380 from 420
 +
*** Mark 5:
 +
**** Diff 5: 650 from 670
 +
**** Diff 6: 650 from 660
 +
**** Diff 7: 640 from 650
 +
**** Diff 8: 620 from 640
 +
**** Diff 9: 600 from 630
 +
**** Diff 10: 590 from 620
 +
*** Mark 6:
 +
**** Diff 5: 810 from 820
 +
**** Diff 6: 800 from 810
 +
**** Diff 7: 790 from 800
 +
**** Diff 8: 780 from 790
 +
**** Diff 9: 770 from 780
 +
**** Diff 10: 760 from 870 (the original was an error in general)
 +
*** Mark 7:
 +
**** Diff 6: 1100 from 1110
 +
**** Diff 7: 1080 from 1100
 +
**** Diff 8: 1060 from 1090
 +
**** Diff 9: 1010 from 1080
 +
**** Diff 10: 980 from 1070
 +
** Thanks to Ovalcircle for reporting the discrepancy, and to Badger for suggesting these numbers get a bit of a look in general.
  
* 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.
+
=== New Included Mods By NR SirLimbo ===
  
== Version 2.106 Immortals and Unresponsiveness ==
+
* Uploaded the AMU (AI War 2 Modding Utils) and Kaizers Marauders mods.
(Released July 23rd, 2020)
+
** Kaizers Marauders is a new spin on an old faction gone, for lack of a better word, insane. Expect an entirely new Marauder minor faction with its own unique ships, turrets, superstructures, new and improved raiders and tons more. The forum thread is here: https://forums.arcengames.com/ai-war-ii-modding/mod-kaizers-marauders/
 +
*** It started out as a request to the AIW2 devs to include journals. So I wrote some mods. Months later it's turned out to be a full rework with TONS of special stuff added and everything is in - except for a hand full of journals. Wow.
 +
*** Some highlights: Unique Marauder ships, turrets, forcefields, etc. Most of these can be acquired by the player for themselves.
 +
*** Some featured mechanics: A realistic metal economy, defectors, super-smart fireteams, tech upgrading, and even an alternate victory condition.
 +
*** For more check the forum thread.
 +
** AMU is a requirement for Kaizers Marauders and consists out of modding functions to be used by various other mods, even further reworks I'm planning todo, as well as any other modder. It will get a full documentation and forum thread, but for now simply ping me on discord (-NR-SirLimbo) for debugging it. A partial documentation is already distributed, along with the C# project itself.
  
 
=== Bugfixes ===
 
=== Bugfixes ===
  
* Put in field names for the risk analyzers saving, so if they have trouble serializing we can see which field it was.
+
* Fixed Lone Wolf fleets being excluded from the ability to load ships. If for whatever reason (mostly mods) ship lines end up in Lone Wolf fleets they will now obey loading/unloading orders entirely and not hug the centerpiece perpetually
** 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 NR SirLimbo for fixing.
** Thanks to GreatYng for reporting.
+
 
 +
* Updated StarKelp Civilian Industries for the latest version of the game.
 +
* Fixed a race condition that could occur when setting militia caps.
 +
** Thanks to various people for reporting, most notably SirLimbo.
 +
 
 +
* Fixed multiple places not having reservations for Lone Wolf fleets (both officer and golem):
 +
** CalculateContentsCount(bool IsForNetworkSyncCheck)
 +
** CalculateHasAnyContents()
 +
** GetStrengthOfContentsIfAny()
 +
** GetEnergyCostOfContentsIfAny()
 +
** Noticed and fixed by NR SirLimbo when unloading a fleet of Kaizer's Marauders-boarded ships began to cause brownouts...
 +
 
 +
* For Extended Ship Variants: Fixed the Strike Wing having its damage bonus based on target time on planet, not its own time
 +
** Thanks to zeusalmighty428 for wondering why it was raid tech
 +
 
 +
* Put in a fix for various of the new shaders for UI glows logging "doesn't have _Stencil property" warnings logged into the player.log.
 +
** We aren't actually using this property, but then again we're not allowing for these buttons to interact with stencils and masks and so don't need it.
 +
** Thanks to Puffin for noticing this.
 +
 
 +
== Beta 2.624 Revised Resource Bar ==
 +
(Released October 30th, 2020)
 +
 
 +
* When AI units with Metabolization kill something, the AI now uses its extra metal to boost its reinforcement budget
 +
** Prompted by a discord conversation led by TechSy730
 +
 
 +
* Tsunami CPAs are now the default.
 +
 
 +
=== Roguelike Changes ===
 +
 
 +
* By default, the Esc menu no longer tells you what factions are in the galaxy until you actually encounter them in game. The goal is to give the game a stronger feeling of exploration and finding the unknown.
 +
** You can have the old behaviour by enabling the Always Show Factions option under Scouting in the game lobby
 +
 
 +
* Add a new Quickstart, "The Rogue Badger" taking advantage of this. You won't know what factions are in the galaxy till you find them
 +
** Please don't load this quickstart into a game lobby or it will ruin the surprise.
 +
 
 +
=== Quality of Life ===
 +
 
 +
* In an ARS, GCA or fleet you could capture, the number of ships for a given ship line is now coloured to let you know how good the roll was
 +
** If the number is a bright green you rolled close to the upper-end of ships you could have. If its a dark green, you rolled closer to the lower end.
 +
*** Only applies to newly started games
 +
** Thanks to ParadoxSong for pointing me in this direction
 +
 
 +
* Capturable flagships adjacent to the player homeworld will always get good RNG with how many ships it has.
 +
** The goal is to make sure the player gets something to be excited about early. Also to make it harder to have games that are screwed by bad RNG
 +
 
 +
* The selection window now shows the strength of the selected units
 +
** Thanks to TechSY730 for suggesting
 +
 
 +
* Improve the hovertext for factories for more clarity. The name of the fleet now indicates how many losses it needs to rebuild
 +
 
 +
* Improve the AI Reserves notification
 +
** If there are no wormholes spawned, it gives you the countdown of seconds until a wormhole spawns
 +
 
 +
* Autosaves are now in a more readable format
 +
 
 +
* The objective hovertext for ARSs is now in a better style
 +
 
 +
* If you double-click a fleet's keybinding while in the galaxy map, it now centers the galaxy map at that fleet
 +
* Clicking a Planet Under Attack notification from the galaxy screen, it now centers you on that planet
 +
** Thanks to Vortex for these two bug reports
  
* 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.
+
=== UI Reskinning Part 3 ===
** 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 happeningAt 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.
+
* The bottom left icons on the main screen are no longer quite as glowy when you are not hovering over themThey light up the same amount while hovered, though.
 +
** The idea is to make it less visually distracting when you are just checking the game clock.
 +
** Thanks to Badger for suggesting.
  
* 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.
+
* The ship selection UI has been updated so that the icons are the same as before, but they now have similar glowy appearance to the buttons in the bottom left of the screen.
** This is untested, but should work.
+
** The "hotkey indicators" are now colored to match the button's general highlighted color, but the baseline color is now that same dull blue rather than bright white like it was before.
** Thanks to crawlers for suggesting.
+
** When these are highlighted, they now glow brightly in their specific color, and if they are moused over the same thing happens.
  
* 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.
+
* The sidebar backgounds have been reworked to better function with the different heights that they can all have, rather than looking really wrong and off when stretched.
** 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 savegameThis 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.
+
* In the top bar, the galaxy map icon has been reworked, and now looks like a galaxy rather than a map pinIt also now glows and reacts to mouseover.
 +
** The hover for the planet name now also highlights the background of that button in the top bar in general.
 +
** The metal icon has been replaced (anvil becomes metal pieces).
 +
*** Note that metal harvester icons still need to be updated, and metal icons in text.
 +
** The energy icon, and science icon, and hacking icon, and threat icon have also all been updated.
 +
** The old threat icon is the new AIP icon.
 +
** Thanks to Badger, Puffin, -NR-SirLimbo, Tzarro, and zeusalmighty for all helping figure these out.
  
* 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.
+
* The various fonts in the sidebars have been updated to be more legibile at smaller sizes in particular.
** This was happening because of multiple threads adding to the queues of commands at the same time that the queue was being drawn down.
+
** Some were returned to the way they previously were, others are new.
** 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.
+
** Thank to Strategic Sage for reporting the grainy appearance and eye fatigue with the other new bits we tried.
** 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 the top resource bar, all of the text and numbers are in a new font that is a bit clearer and quicker to read.
 +
** In times where the metal would say "Starving" in the past, it now says "Drain" to save space.
  
* 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.
+
* The hacking and tech sidebars now use the correct image, and also react to hovering with a glow.
  
* 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.
+
* The background from the load menu has been kept the same, but is now vastly darker rather than being bright and in your face.
  
* Added a new ArcenNetworkClientConnection abstract class, which we now store on ArcenNetworkAuthority in a ClientConnections list.
+
* The background for the save menu has been made to match that of the load menu, and is also now darker like the other one is. The other one was particualrly tacky and distracting.
** 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.
+
* Fixed a minor issue with the notifications not being properly rounded up in the top area.
** 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.
+
* The game has been updated to actually set and use the fancy new priority level backgrounds for the notifications in the top bar.
 +
** Bear in mind that this is something that we may tune over time based on feedback, in terms of what gets what notification priority level.
 +
** The notifications are now sorted by priority level from OMG, major, medium, minor, informational, and then hacking, prior to whatever the rest of their sorting would be.
  
* Trimmed out a bunch more old FORGE code that has been commented out for years from the look of things.
+
* Wave notifications (of various sorts) now have the following notification levels:
 +
** All CPAs are major for now.
 +
** Any waves against not-a-player that are shown are considered minor for now.
 +
** Reconquest waves are all major for now, unless they are not aimed at the player.
 +
** If a wave isn't one of the above and also is not targeting a planet, it's considered minor for now.
 +
** If a wave is headed to a planet, but that planet isn't allied to the local faction or has no owner, considered minor for now.
 +
** If the wave is weaker than 2/3 of the combatants friendly to the local faction at the planet, then this is minor.
 +
** If the wave is stronger than 200% of the combatants friendly to the local faction at the planet, AND this is a player home planet then this is OMG.
 +
** If the wave is stronger than 150% of the combatants friendly to the local faction at the planet, then this is major.
 +
** Otherwise this wave is considered a medium priority.
  
* 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.
+
* Regular notifications that are created by whatever other means are now required by code to specify their priority level when they are being created.
** "Hello friend, you've connected: what's your profile name you want to play under?" Etc.
+
** Those shake out as follows for now:
 +
*** AI Reserves notifications are always major for now, given reports on the difficulty of these by players lately.
 +
*** Dark Spire vengeance strikes and loci are medium and major respectively.
 +
*** Dyson antagonizers are major.
 +
*** Nanocaust frenzies got removed from the code, since those aren't a thing since fireteams anyhow!
 +
*** Wormhole Invasions are always OMG level at the moment, we may adjust this.
 +
*** Devourer Golem is informational if it's on a planet that is not owned by anyone or which is not friendly to you.  It's minor if it's on a planet of you or ally.
 +
*** Zenith Trader is always informational.
 +
*** Hacking events are hacking priority.
 +
*** Spire Relic Train is informational, and so are risk analyzers.
 +
*** Spire relics and debris are also informational.  Same with imperial spire.
 +
*** Brownouts are OMG.
 +
*** Macrophage of 4 or more are medium, less than that are minor.
 +
*** Enemy nemesis is OMG, allied is now shown for the first time and is informational.
 +
*** DLC2 NP move is informational.
 +
*** DLC2 AT expansion is medium, civil war of it is major.
 +
*** DLC2 ZM mnrs > 0 is major, just probes is medium.
 +
*** DLC2 ZB are medium, unless all are in flight in which case are informational.
 +
*** When your planet is under attack, the priority is normally medium, unless:
 +
**** If it's a human homeworld, and enemies outnumber you and allies, then it's OMG.
 +
**** If it's a human homeworld, and enemies are more than 50% of your strength, then it's major (just in case).
 +
**** If it's a human homeworld, and enemies are less than 10% of your strength, then it's minor.
 +
**** On non-homeworlds, if you and allies are outnumbered 2:1 in strength, it's major.
 +
**** On non-homeworlds, if enemies are less than 50% of your strength, then it's minor.
 +
*** Exo strikes are major until they are 95% charged, at which point they turn OMG.  MDC exos no longer exist (they do something cooler), so the code for that is just scrubbed.
 +
*** Raid engines are medium, unless they are targeting a non-player faction in which case they are informational.
 +
*** AI Eyes, since they don't spawn anything, are rated minor.
 +
*** Counterattacks are:
 +
**** Minor if they are stalled
 +
**** Still minor if the strength of the counterattack plus all local enemies at that planet is less than all the local allies and own ships at that planet (aka you are outnumbering even if the counterattack launches).
 +
**** Major if the strength of all those enemy forces noted above is at least twice what the allied local forces mentioned are.
 +
**** Medium if it's in the middle range.
 +
*** Astro Trains are generally minor, but if one is headed to a depot that does something once X number of trains have reached it, and there X-1 trains have already reached it, then it jumps up to major.
 +
*** Instigators are generally medium, but if a given instigator has done its thing at least four times, then it upgrades to major status.
 +
** Huge thanks to zeus for suggesting most of these, and Badger for helping figure out details, and Ovalcircle and DEMOCRACY? DEMOCRACY! for helping a ton also. And Puffin!
  
* 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.
+
* GetIsHostileTowards(), GetIsNeutralTowards(), and GetIsFriendlyTowards() on the planet faction now take in variants with a faction directly.
** 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.
+
* On planets, there is a new GetStrengthOfFactions_HostileTo() that gets the strength of all enemies of a faction at a planet.
 +
** There is also a GetStrengthOfFactions_FriendlyTo(), which lets a faction include itself in that total or not, as well.
 +
** There is also a new GetStrengthOfFactions_Self() that gets it just for the faction in question.
  
* 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.
+
* Fixed a pair of typos with astro train journals not firing properly.
  
* The initial challenge-response work, and "what's your name" work, is all functional againThis is stuff that will be identical regardless of the network framework.
+
* The devourer golem no longer shows its warning with the color of its faction directly in the notificationThat blends really poorly now in general.
** The host can now properly see the profile name of the client, and is poised to send the client back all the world information.
+
** In the tooltips it will now show that, but with deep blue in the tooltip it was a blurry smudge.  We will have to make some more changes to notifications over time to make this all more clear.
  
== Version 2.105 Selection Hotfix ==
+
== Beta 2.622 Hangar Ship Diversity ==
(Released July 22nd, 2020)
+
(Released October 28th, 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.
+
* Fix a typo in one of the Tips for returning players
** 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.
+
** Thanks to Breach for reporting
** 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.
+
* One can no longer manually click on a ship with active repair-delay and get your engineers to repair it
** In the prior build, we tried to fix some of those cross-threading issues, but wound up making things not actually deselect properly.
+
** Thanks to Arides for reporting
** 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.
+
* Exos that are being sync'ed with Wormhole Invasions or CPAs now always have a notification
** 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 ==
+
* Slightly improve the nanobot center hovertext
(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). 
+
* The Esc menu now shows the "Display Name" of the map type instead of the "Internal Name"
** 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.
+
* Slight buffs to the AI on intensity 10. The goal is a bit more raw power.
** Thanks to Gunner for reporting.
 
  
=== Multiplayer Connection Work ===
+
* Fixed a bunch of cases of "address" being spelled with three Ds.
 +
** Thanks to Ovalcircle for reporting.
  
* Reworked the NetworkTrafficLog.txt multiplayer output to actually be a lot more informative.
+
* CPAs are now a bit smarter at detecting when they planet they were going to is no longer relevant. CPAs for higher difficulties (AI difficulty >= 8) are now better at focusing their forces.
  
* GetNumberOfConnectsCurrentlyActive has been replaced with GetNumberOfConnections, which lets the network framework tell us a lot more about the general status of things happening.
+
* Add a new Game Lobby setting to prevent Beacons from spawning in the game
** 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.
+
** Intended for people trying for Pure 10 runs, and for anyone who hates beacons
  
* 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.
+
* Add a setting for 'Hide Undiscovered Factions from Esc menu'.
** Previously it just showed one number that included the host and also disconnected clients all wrapped up into one.
+
** This is mostly for people who like surprises and have a poor memory of what was going on in their games
** 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.
+
* If some piece of UI doesn't load properly, the main menu should no longer freak out and throw endless errors.
  
* Removed some old "desync detected" code that was not fitting with the new plans for multiplayer.
+
* If you are adding a new faction in the game lobby and that faction has the same FactionCenterColour as an existing faction, the new faction gets a random colour
  
* 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.
+
=== Astro Train Changes ===
  
* The way that gamecommands are queued and then given out to player simulations for both single-player and multiplayer is now more efficient.
+
* Astro Trains now count as 'Large Ships' for the 'planet in combat' notification hovertext
** 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.
+
* Astro Trains get fewer guards. Guards now attrition (quickly) if their train is dead, and they attrition slowly if their train is on a different planet
  
* 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.
+
* Astro Trains are now better at heading to their Stations, and not getting distracted
** 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.
+
* This section thanks to feedback from GreatYng
  
* 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.
+
=== Refinements To Main Menu ===
** 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.
+
* The reflection probe on the main menu is now located more to the side, so that it is not in the path of ships that go flying through out.
** 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.
+
** This makes it so that the reflection of the ships is shown, but there is not a giant flash on the entire screen as a ship exits the view.
** 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.
+
* The AI War 2 and Arcen Games logos are now subtly on the wall in 3D in the background on the main menu.
** 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.
 
  
== Version 2.103 Hotfix ==
+
* The old ship that was being used for the main menu animation in yesterday's build is no longer used at all.  That was a junky dark ship that was never actually used in the game.
(Released July 21st, 2020)
+
** Now we are using spiders, bombers, raiders, and MLRS corvettes.
 +
** There are two different animations for each one leaving the hangar, and the quality of the animation is now higher, as well.
 +
** The overall idea here is to give a lot more of a sense of life and personality to the scene, and make it clear that these are multiple ships launching instead of just one repetitive animation on loop.
 +
** There are also now point lights on these ships, which helps give even more of a dramatic bit of motion that interacts with the rest of the scene as they exit the hangar.
  
* 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.
+
* Added a new ArcenFramerateTracker that now let's us track the framerate of the game at any time.  We've previously been tracking sim performance, but not the actual framerate.
** Thanks to valinor000 and stanazolol69 for reporting.
 
  
== Version 2.102 Digression For Quality ==
+
* Also added a new ArcenCutscenePerformanceManager class that lets us react to poor framerates during a cutscene by reducing the reflection probe load.
(Released July 20th, 2020)
 
  
* Using the "Increase Max Dyson Strength" hack will now also increase the Dyson's general mark level
+
* On the main menu, next to where it shows the amount of time it has taken to load the game, it now also shows the FPS of the game on the main menu.
* 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
+
=== UI Reskinning Part 2 ===
  
* Improved the speed of some dictionary lookups by precalculating the ArcenAssetBundlePath CombinedPath.
+
* Fixed an unsightly bit of extra partially-transparent white pixels in the corner of the rounded menu backgrounds.
** 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.
+
* The textbox used throughout the game has been updated to look much more attractive than it has in the last few beta versions.
** Since multiple threads do in fact often use orders, at once, this is one of the few collections prone to that.
+
** Actually, then we updated it yet again to make its construction vastly more complicated, but to show the halftone pattern undistorted, the borders cleanly, the interior drop shadow properly, and all that at a variety of sizes as need.  Whoof, that took forever.
  
* 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.
+
* Updated fonts on the tutorial screen, and the background to help differentiate it more from the other similar screens.
 +
** And gave the same treatment to the load quickstart window, but with a different background that is more golden and different shapes to help tell this one apart from others.
 +
** And also the load game menu, where it looks like a bunch of microprocessors and similar.
  
=== Ship Behavior Improvements ===
+
* The following windows have had their fonts updated, but no special backgrounds as they are not used all that frequently and don't need differentiating:
 +
** Controls window.
 +
** Credits window (also updated it so that the names on the right-hand screen are not cut off).
 +
** Kickstarter backer credits window.
 +
** Background story window (this also has been updated to have a more readable and better-sized font for the central story).
 +
** Add/edit profile window.
 +
** Color picker (team and border based).
 +
** MP client connect by IP and List windows.
 +
** MP client connection status window.
 +
** Same for the two general "popup list option" window components.
  
* Fix two problems related to shields recovering from being bumped by Astro Trains
+
* The chat/log window has been updated like the others, but also with a dark blue background in there to set itself apart a bit more.
** Human Home Forcefield Generators can now recover from being bumped.
+
** The factions window has also been updated and has a new different background, but it's a very subtle one.
*** Thanks to Lord Of Nothing for the bug report
+
*** The sectional factions and galaxy options tabs in the main menu has been updated to match a combination of this and the chat window, since it incorporates elements from both.  This really helps to make them stand apart.
** 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
+
**** The standalone chat on the right in the map tab in the lobby in multiplayer then matches the chat colors and such from THAT.
*** Thanks to Puppet Master for the bug report
+
** The personal settings window now has different visuals, slightly, from the galaxy-wide settings menu.  Again to help with people knowing where they are at a glance.
 +
*** The tips window also now has its own variant off the personal settings.
 +
** The settings sidebar popout has also now been updated (this is mainly used for fleets, but can be for other things also).
  
* 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.  
+
* The notifications images have been updated a bit to have a slight bit of extra detail in their background.
** Thanks to ParadoxSong for the bug report
+
** These also now have different background images that we can swap in for minor, medium, major, OMG, informational, and hacking events.
 +
** Right now all the notifications are just set to medium, but we will hook them up to use different backgrounds later.
 +
** Thanks to Badger, zeus, Tzarro, Ovalcircle, and NR SirLimbo for helping figure these out.
  
* 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.  
+
* Updated the visuals for tabs, and the top bar in general in the lobby.
** Not for the faint of heart; intended only for developers who want to get their hands very dirty.
+
** Also updated the tabs on the left of the main screen to match this new style, including slightly different spacing for the tabs themselves.
 +
** Updated the build sidebar's fonts slightly, and in general its backgrounds and so on.
 +
** Same for the fleets tab.
 +
** Same for the hacking tab, except for the header part that has the hacking icon.  That bit will be updated later.  The button color here has also become green.
 +
** Same for the journal tab.
 +
** And outguard tab.
 +
** And intel tab.
 +
** And science tab.  Here again the header icon has not yet been updated.
 +
** And the planet tab.  Later there will be many updates here, but those will have to wait.
  
=== Bugfixes ===
+
* The selected ships window has been updated except for its icons, which are going to be replaced and improved.
 +
** Same for the main header resource bar in the game.
 +
** These will get some more work done on them tomorrow.
 +
 
 +
== Beta 2.621 Gorgeousification ==
 +
(Released October 24th, 2020)
 +
 
 +
* It is now possible to set up material swaps on a list of images related to a given button, which in turn lets us make the glows more intense or even different colors.
 +
** We're now using this for the buttons in the lower left corner of the main view, so that as you hover over them it's super clear what you are hovering over.  This feels far more interactive, and has a lot more in common with what we are doing with other buttons elsewhere in the game.
 +
 
 +
* Added a new "pre-canvas LDR camera" that makes sure to do a no-algorithm tonemapping from the HDR range to the LDR range.
 +
** This essentially does add an extra compositing step, but makes it so that anything that might peek into the HDR range from things like hovering over certain faction icons can't possibly interact with the new bloom effect that is used for buttons.
 +
** Because we have a number of special extra cameras for things like the effects where we have not scouted or don't have current intel, this was the cleanest way to make sure that nothing else goes wrong.
 +
** Thanks to NR SirLimbo and Puffin for reporting.
 +
 
 +
* The asteroid belt ring that goes around the playing area on planets has been updated so that it has full lighting effects on it, with a dark side and a light side that also matches the direction of the sunlight hitting the planet.
 +
** On dark starfield backgrounds, you'll mostly just see the brighter side of these asteroids, but you'll still finally be able to see them.
 +
** On light starfield backgrounds (lots of nebulas), you'll mostly see the shadowed side, which then looks a lot like before.
 +
** On areas of transition and contrast, you still have something to visually pick out in either situation.
 +
** Thanks to a lot of folks for reporting this over the years.  I tried this a while ago and couldn't get it to look acceptable, but this time it worked out.
  
* Fix a bug where the 'delete campaign' button wasn't giving the campaign name
+
* The timer text in the bottom left corner of the main view is now a bit smaller so that it can hopefully always fit its contents in there.
** Thanks to OvalCircle for reporting
+
** Thanks to NR SirLimbo for reporting.
  
* Fixed a rare and harmless (but annoying) cross threading exception that could pop  up with argument out of range exceptions in RenderShip.
+
* The new background image behind the right window in the escape menu was actually too far forward, and was also set as a raycast target.  Consequently, it looked slightly wrong and also caused the scrollbar to not be clickable.
** Thanks to CRCGamer for reporting.
+
** Thanks to Badger for reporting.
  
* Fixed a rare nullref exception that could happen in DoRemovalChecks() on shots, mainly a cross-threading thing.
+
=== Revised Key Scenes ===
** 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.
+
* The victory screen has been completely overhauled in terms of the visual background style, and the fonts used, and the composition of where text is, etc.
** Thanks to Lord Of Nothing for reporting.
+
** The overall color scheme and the visuals are based on what the main menu has been for the last few years, except it's more dramatic than before in the sky and the lighting.
 +
** We were fond of that old main menu screen, and so wanted to keep it around in some fashion, but also to make it more dramatic in a way that is fitting for a victory screen.
 +
** We were NOT fond of the old victory screen visuals, so those are just tossed out.
  
* 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.
+
* Fixed a typo in the victory text.
** Thanks to Oryutzen for a save that demonstrated this.
+
** Thanks to Venger for reporting.
  
* Fix a bug where the imperial spire wasn't Watching previously explored planets for you.
+
* The loss screen has been pretty cool for a while, and it was based on an even older version of the main menu (go figure), but it still needed some work.
** Thanks to Lord of Nothing for reporting
+
** First of all, the armada in the background has been repositioned and also doubled in size, to better fit with the composition of where the AI overlord is located and not distract from certain other elements of the image.
 +
** Secondly, the background visuals are far more vicious and red and angry, and have even more visual interest, in terms of how and where they are positioned.
 +
** Thirdly, the blue planet now has an even stronger glow off its atmosphere, but more pale and more in the background.
 +
** Fourth, the lens flare and glare has been turned off of the bloom effect being used here, to keep things more consistent with the rest of the game.
 +
** Lastly, the text has been moved around a fair bit, and the fonts changed and button repositioned, etc.  It's more similar to the loss screen, but not the same.
 +
** This screen is not the super most legible text, just by nature, but it's at least attractive now and it definitely is readable.  But if any screen is going to cause a bit of eye strain while reading, it's this one.  We figure that's okay, as you don't really need to read the parts that would be at all that way, anyhow.
  
* 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.
+
* The main menu scene is now completely overhauled, and shows a scene from inside the hangar of one of your fleet leaders.
** This was, in very long play, a memory leak as well as a performance drain, and it was generally invisible.
+
** This ship is moving around in such a way that the starfields outside are spinning past, and you can see the reflections of these, and the planet that goes by, affect the dark metals of the large ship you find yourself inside.
** 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 themSo no wonder we couldn't actually find the ellipsis character used in our own text files.
+
** Through the floor, ship after ship is raised up from the bowels of the structure and accelerated out into space.  Those who have been playing the game for a really long time will recognize this ship from being the "mascot ship" on the main menu 2-3 years ago.  It had the game logo and company logo in 3D on the side of itself back then, but no longer does.
** Thanks to Puppet Master for providing the log file demonstrating all this.
+
** As part of this change, now that this scene is so much darker than the old main menu, the buttons fit in better in general.  We are no longer tilting those backwards in order to make them fancier.  It has always introduced aliasing issues around the edges of those buttons.
 +
** To make the ship move and accelerate properly, we have now integrated Slate Cinematic Sequencer by Paradox Notion.  We've had that for years, but never had anything worth integrating it for in this project.  We're aware that Unity Timeline exists, but this was a quick and familiar thing.
 +
** This overall scene is pretty heavy, so if it's causing lag on the main menu, please let us know.
 +
*** On an i7 from 2016, and with a GTX 1070, at the moment we seem to only be getting around 40fps, which is a surprise.  In earlier testing with this scene we were getting 130fps or so.
 +
*** We're not sure if this is related to the Slate cutscene stuff, which was the most-recent-added, or if it's something else that we're not clear onAt any rate, the realtime reflection probe at a really high quality doesn't help matters, but boy is it gorgeous.
 +
** At the moment, the main menu scene (after the loading scene, which is the same as it has been for a really long time) does not include the AI War 2 logo or any other logos.
 +
*** Later it would be nice to include the main logo and expansion logos, but perhaps integrated into the scene in some fashion.
 +
** Overall this, plus the changes to the other two scenes, are requiring about 300MB more disk space, and something along those lines in terms of RAM.  It doesn't have any effect on the speed of loading the game.
  
* 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.
+
== Beta 2.620 Hotfixes ==
** Thanks to Lord Of Nothing for the report and save.
+
(Released October 24th, 2020)
  
* 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.
+
* Fixed an error in the most recent beta where the lobby was broken if you didn't have DLC2.
** 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.
+
** Thanks to cml and UFO for reporting, and Puffin for pointing us to where the issue was.
** 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.
+
* Fixed a known issue from the last beta where the settings and chat visible buttons in the lower left corner of the main screen were not working.
** 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 ====
+
== Beta 2.619 Quality Of Life And Polish ==
 +
(Released October 23rd, 2020)
  
* New setting on the debug menu: Show Pool Counts In Escape Menu
+
'''Since there are many visual changes in progress, to save confusion this is only on the beta branch on steam and gog right now.'''
** 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.
+
* Marauder Outposts now have more health
** 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.
+
* The faction list of the Esc menu is improved. It is now sorted for easier reading, and the 'allegiance' section of the Esc menu is color coded and simplified.
** 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.
+
* Updated the galaxy map camera view to now use a 4-camera stack instead of a 3-camera stack. The new camera on the stack is just for rendering the space background, and it now uses a field of view of 60 rather than 40 so that it has the proper perspective and scale on those background starfields and nebulas versus seeming super zoomed-inThe field of view of the map parts itself remains at 40, to avoid distortion on them.
** Same for TimeBasedPoolBase (and thus TimeBasedPool itself).
+
** Thanks to Puffin Emeritus for suggesting.
** And same for BasicPool.
 
** And holy cow, there's some sort of memory leak with the time-based pools, looks like, based on thisThat 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
+
* Harmonic turrets must be fully constructed in order to apply their "Strengthen other harmonic turrets" buff. Turrets under construction no longer count, and neither do remains
** 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.
+
** Reported by ArnaudB
** 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).
+
* Updated Harmonic mechanic to be able to increase per Mark. Harmonic turrets gain 10% of the original value per Mark.
** 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 ====
+
* Vengeance Generators now prioritize other VGs close to deploying ships when sharing energy. The goal is to get multiple battles going at once. Also improve the hovertext for VGs with some colour
 +
** Thanks for GreatYng for prompting
  
* 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.
+
* Astro Trains guards now spawn pre-stacked if appropriate
** 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 ==
+
* Add a new setting to not show the Dotted Lines between player planets and AI planets without wormholes. I like being able to see the colour gradient better.
(Released July 17th, 2020)
+
** Off by default
  
* 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.
+
=== Journal Tweaks ===
** Thanks to ParadoxSong for reporting.
 
  
* The left and right click functions of the metal display have been switched to be more natural.
+
* The game now does a better job of telling you when journal entries appear through their Chat text
** 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.
+
* When there are new journal entries to read the "Journal" tab on the sidebar now changes colour to make it easier to notice
  
* We've reworked our "Window_PopupScrollingColumnButtonList" a bit to add some new handy features for us.
+
* Add a few journal entries for the astro trains
** 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 ===
+
=== UI Reskinning Part 1 ===
  
* The hovertext for the Scourge "Strength" in the game lobby now tells you what the strength does (more scourge ships/structures, and faster).
+
* Textboxes throughout the game now go to an ellipsis if there is not enough room for their contents, rather than looping to a second line in a strange way.  This rarely came up because of character limits.
  
* Add a "Sandbox: Extra Strong Mode" for the scourge
+
* When you go from hovering over a textbox to then clicking it, it no longer flashes a different color for a moment.
** 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.
+
* Designed some new UI shaders that allow for us to use HDR blooms on icons.
** Thanks to ParadoxSong for the save.
+
** Added a post-processing stack bloom item on the GUI-layer camera that is specifically for anything that is still in the HDR range when it is post-processing there.
 +
** This should not apply to anything except the UI itself, since everything else should have been mapped back down to the LDR range by the tonemapping prior to now.
 +
** At any rate, this then lets us use, very selectively and carefully, some glows on icons and similar in the UI and have that behave properly and give a much better sci-fi effect.
  
* 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
+
* We've been working on this all week, but at this point the various UI elements are about... maybe 1/3rd updated to a new and improved style.
** Thanks to ParadoxSong for the suggestion
+
** The escape menu, and all of the popup yes/no windows, are all done.  The main menu buttons area is done (but not the actual main menu scene in the background or the angled-buttons stuff).
 +
** New font selections for headers and buttons are done, but they're not universally applied everywhere yet.
 +
** The bottom-left corner buttons and timer on the main view is fully updated, but the sidebar and resource bar and selection windows and such are not at all.
  
* 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.
+
== Version 2.618 Astro Reserve Tuning ==
** Thanks to ParadoxSong for the save that exposed this problem.
+
(Released October 21st, 2020)
  
* These changes should make the scourge much harder to deal with in general, and on the X map type in particular.
+
* Add some warning text to the X map saying it has balance issues
  
=== Initial Multiplayer Connection ===
+
* Fix a bug where ai-allied factions like the scourge or marauders weren't correctly allied to things like Astro Trains. This was causing a number of issues, like 'Astro Trains never spawn'
  
* 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.
+
* CPAs will group-move more often
** We've removed this concept, and instead are making it based on the menu choices you make on the main menu.
+
** Suggested by Crabby on steam
** 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.
+
* Change the way Threat numbers for the resource bar are counted.
 +
** AI and AI-aligned factions (Instigators, CPAs. Not AI-Allied Marauders or the like) are the only factions that now count as Threat.
  
* The SpecialNetworkType has been moved into ArcenUniversal, and is now copied onto ArcenSocket along with the InternalName of the row that created the socket.
+
* Add an Experimental setting under "Game" to allow Hunter ships required to go after a specific faction to go through other factions on the way
** There is now a list of AllPossibleSockets on the ArcenNetworkAuthority to allow it to swap between sockets as needed, and particularly by type.
+
** The most usual case was if you owned the center of an Octopus map, and the AI homeworld on one of the legs was building up Threat against a Nanocaust on another leg. The AI really didn't want to send attack you with its Anti-Nanocaust ships, so they would just sit around.
 +
** I'm not sure how well this works, and whether it has potential problems, so I'm making it an opt-in setting to get feedback.
  
* 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.
+
* AI Reserves ships now attrition much more slowly
** If you are logged into Steamworks, it will set steam as the default network.
+
** Attritioning is done as a neat thematic, and also to make sure that the reserves will die if they can't get back to their wormhole, but it was going much too quickly
** If that didn't work or wasn't true, and you are logged into GOG Galaxy, it will use that as the default network.
+
** Thanks to GreatYng for pointing this out.
** 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.
+
* Fixed an issue where command stations and NPC fleet leaders could be seen to be in the new "stationary flagship" mode.
** 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.
+
* The new "stationary flagship" status now defalts to off, and for all savegames prior to this one will have them all set to off.
** 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.
+
** Thanks to Strategic Sage, Metrekec, Smidlee, Asteroid, TechSY730, crawlers, and others for weighing in on this.
  
* 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.
+
* For the included "Extended Ship Variants" Mod:
** 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.
+
** Fixed the Oculus not having a limit on the damage modifier, which meant that it could deal an amazing 1430x damage to them (assuming the 2.5x multiplier based on time also applies). A single Oculus Mark 7 could do 926,640 points of damage - per shot (120 x 5.4 x 1430).
 +
** Found by ArnaudB, when his Spire Great-Shield Emitter got eaten in an instant.
  
* 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.
+
* For the included "Extended Ship Variants" Mod and the Fallen Spire version as well:
** 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.
+
** General Change: The AI ship group weight of all variants was reduced by 50%. So now they should be spending much less budget on them, and more on base variants
 +
** The Void Bomber's full-invulnerability fortification effect has been nerfed
 +
*** It now only applies to shield, and reduces damage to 0.1% (so only 1 in 1000 points of damage applies). Shields were also buffed from 250 to 500 points.
 +
*** Hull was increased from 500 to 2500 to resist at least a bit of fusion damage, which (along with melee) is king against them
 +
*** The defense buff now activates at a range of 350 instead of 1000
 +
** The Vex Guard had its cost increased: AI Budget cost up a quarter from 80 to 100, Metal cost from 4500 to 6500 and Energy cost reduced from 800 to 500
 +
** Also from a discussion with ArnaudB on Discord.
  
* 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.
+
* For the included "Extended Ship Variants Fallen Spire" Mod and the Fallen Spire version as well:
** 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.
+
** Buffed the EMP Missile Frigate up again, increasing its paralysis potential
 +
*** The description now (accurately) states that it has 10 shots (instead of 5, it always had 10), but it now also gains 2 shots per mark level beyond 1 for a full 22 at Mark 7. This is because, as fights expand, more missiles will inevitably get shot down.
 +
*** The maximum amount of targets hit per EMP missile is 7 instead of 5
 +
*** EMP Missiles have an albedo of 0.6 instead of 0.3, making them immune to most tractor beams (if not all).
 +
*** The base cap has been increased from 1-2 to 2-3 ships, or from 2-3 to 3-4 ships in the Frigates-With-Support fleet template.
  
* 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.
+
==== Astro Train Buffs ====
 +
   
 +
* Astro trains mark level goes up based on the number of trains spawned. When they begin spawning stronger variants the mark level resets to 1.
 +
** Previously the astro trains had just taken on the mark level of the AI, which meant it generally stayed low all the time.                                                                          
  
* 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.
+
* The astro trains can now have Guards; each train can have some Guards who will deploy when there are enemies, and will return to the train when there are no longer enemies
 +
* Astro Trains can get more guards when they reach a Station. They also can heal a bit on reaching a station.
 +
** Guard strength increases based on trains killed (regardless of who killed the trains)                   
 +
** Guards are intended to make trains a bit harder                                                                     
  
==== Choosing A Networking Framework ====
+
* Astro Trains can spawn stronger variants after enough trains have been killed by the player                                       
  
* 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 largest balance change is letting the train mark level increase more readily. Guards are intended to be a bit of extra cool/flavour with some balance impact.
  
* 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.
+
== Version 2.617 Calming For The Nerves ==
 +
(Released October 16th, 2020)
  
==== What Is My IP Address If I Need It? ====
+
* Should now be a new Journal message for AI Relic Trains.
  
* In the networking section of the settings menu, it now has helpful informational displays of your local IP addresses and your public IP address.
+
=== Quality of Life Improvements ===
** 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 ====
+
* Add a new Galaxy Map Setting to change how the links look. Instead of using Red for "these two planets are hostile" or Blue for "these two planets are friendly", the game can now show a color gradient between the faction owners
 +
** The old style version is still available as an option.
  
* The old interface for network connections by IP address is restored and works againWe'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.
+
* There is a general problem with "churn" in ships and stacks being so fast that if you have many ships selected it was almost impossible to remove a status effect based off of a simple toggle.
 +
** Our overall logic was "if at least one of the selected items doesn't have the status, then add the status." But this gets intensely confusing, and we introduced transports that is part of why we made L be load and U be unload.
 +
** So let's revisit our older standing orders, too, because this is just problematic with trying to toggle them.
 +
*** G is no longer "toggle group move" it is now "Enable Group Move"
 +
**** You now have to use Ctrl+G to remove ships from group move.  None of this toggling business!
 +
**** Additionally, on the interface for the game where it shows the icon under selected ships, right-clicking that button now removes, while left-clicking enables.  The tooltips are updated to say all this.
 +
*** The same exact setup is now true for "Stop To Shoot Mode" and the K key, including its button and Ctrl+K and all that.
 +
*** Exact same thing again with "hold fire/disable" functions and the N key, and Ctrl+N, the interface button, etc.
 +
*** Ditto again for Pursuit mode and the V key.
 +
*** And a final ditto for attack-move mode and the X key.
 +
** This is something that has been reported since at the very least February, and even before that, apparently.  Somehow or other this still frankly just slipped past our attention.  The amount of information overload that we sometimes face is kind of intense when it comes to bug reports.
 +
*** But with that said, holy cow this was incredibly annoying.  There's nothing like pressing a button and not having it do what you want to induce rage.  We just don't really use these options all that much, or when we do they are with only one fleet selected, and it was working well in single-fleet situations.  Something about multiple fleets in one selection was particularly throwing this off, but it's hard to be sure of the exact full reasons.
 +
*** At any rate, we're glad to have it fixed now, and thanks to folks for bringing this up again so that it finally registered in our attention properly.  This feels like a major frustrating oversight.
 +
** Thanks to Strategic Sage, Asteroid, Arides, and TechSY730 for reporting.
  
* Connections are now able to be established from one computer to another, for the first time since 2018!
+
* The escape key no longer clears your selected ships and fleets.  There really was no good use case for this, and it was annoying to at least some folks.
** 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.
+
** Thanks to Asteroid for suggesting.
** 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 ==
+
* If you are on a map that is large enough that you can zoom out so far that the "Icons By Planets Hides At Distance" setting kicks in (default is 1.5, but you can change that up to 10 if you prefer), then now it will still show any fleets or other on-galaxy-map-units that you have selected.  Later we can customize other display modes to show things in this scenario in various ways.
(Released July 15th, 2020)
+
** Thanks to Asteroid for suggesting.
  
* There is now a galaxy setting to grant players Watch vision for 1, 2 or 3 hops from all command stations.
+
==== Stationary Flagship Mode ====
** Thanks to uhamster9 for inspiring this addition.
 
  
=== Fixes And Tweaks ===
+
* New setting in the Ship Controls section of the controls: Hold To Give Orders To Stationary Flagships
 +
** Normally flagships that are unarmed will not listen to any orders that you give them.  This is because usually you select their entire fleet, and you mean 'everybody but you.' 
 +
** However, there are times when you definitely DO want to give them orders to move somewhere, perhaps transport some ships for you, and holding down this key while giving those orders will make them listen to you.
 +
** The alternative is to take them out of stationary mode, but this is far simpler.  Movement orders on the galaxy map screen are always obeyed.
 +
** Default keybinding: control key.
  
* Improved the way that time-based pools are incremented in time, so that we're never having accidental cases where we miss one.
+
* The pre-existing "Flagship Movement Mode" option in the fleet options panel is now renamed to "Flagship Roaming" for the sake of clarity.
** 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.
+
* A new "Flagship Orders" option in the fleet options panel has been added.
** This lets us tell when these have a memory leak, if there ever is one with them.
+
** It is either "Follow All Orders" or "Stationary Flagship Mode".
 +
*** Unarmed flagships are by default stationary, while armed ones by default will follow all orders.
 +
** Description in the tooltip:
 +
*** Some flagships are meant for fighting, while orders meant for hanging back.  How far back is up to you.
 +
*** When this is set to 'Follow All Orders', it acts like any other ship in your fleet.  This is great for Golems and Arks.  Not so hot for unarmed transports.
 +
*** When this is set to 'Stationary Flagship Mode' mode, the flagship will just sit there and ignore all orders you give it.  The assumption is that the orders are meant for the rest of the fleet.
 +
*** To override this while staying in stationary flagship mode, hold Control down while issuing orders to the flagship.  It will follow them as if this mode was not even on.  This is perfect for rapidly giving different orders to your unarmed transports and the rest of the fleet they are supporting.  Movement orders on the galaxy map screen are always obeyed.
  
* 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.
+
* If a flagship is in this new stationary mode, then they will show up with the "guard" shield icon behind them, which we don't really use for other purposes much.
 +
** This should help players who are jumping right into this new version realize that something is going on when their ships are not listening to them.
 +
** When Ctrl is held, then this shield status icon goes away and whatever the normal status icon would be appears.  This is immediate visual feedback of what is happening, and also lets you check to see that your flagship is indeed in pursuit mode or what have you.
  
* In addition to the existing time based pools, we now have a new ExternalizedPool.
+
* When a flagship is in the new stationary mode, and you are not on the galaxy map (where that is irrelevant), the tooltip for the flagship now shows "Stationary Flagship Mode!" even in the super brief tooltip, and then has more details if you go to medium and then full detail.
** 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 whole thing with the flagships sometimes rushing to their deaths has definitely been one of the most singularly-annoying things since we introduced the concept of fleets, way back in the middle of Early Access.
** This is more efficient and properly uses pooling (which never was working properly before, it turns out).
+
** At first, more fleets than not had big weapons (Golems and Arks), so it seemed like less of a thing.  But over time, it has become more and more annoying.
** It also makes the position of planets automatically react to them having moved in the game sim, without having to do anything special.
+
** This was something we have thought about for a long time, but for whatever reason we never could come up with a good solution for it despite how much it annoyed us directly, let alone player reports.
 +
** Thanks to Strategic Sage, nas1m, Asteroid, and others for contributing to this discussion since last December, and then more acutely more recently when this solution was arrived at.
  
* 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.
+
=== Bugfixes ===
** 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.
 
  
* 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.
+
* Fix a bug where the AI Reserves journal message was playing incorrectly when loading a sufficiently old game save.
 +
** Thanks  to Metrekec for reporting
  
* Added a new debug setting: "Write Detailed Savegame Timings"
+
* Fix a typo in the AIP hovertext in the resource bar
** 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.
+
** Thanks to Puffin for reporting
  
* 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.
+
* Don't let Exos sync with a wormhole invasion if the AIP is too low for wormhole invasions
** 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.
+
** Thanks to NRSirLimbo for reporting
  
* 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.
+
* Fix a bug where the AI was telling you where its major structures are, even on unexplored planets
** This pretty much could only happen if you already had another error first.
+
** Thanks to TechSY730 for reporting
  
* Fixed an exception in SeedNormalEntities that could happen if you rapidly tried to regenerate maps in the lobby in just the wrong way.
+
* Add some defensive code to the DoOnAnyDeath code path for the player
 +
** Problems were reported here in several multiplayer games.
  
=== Under The Hood Improvements For Icon Modding And RAM Usage ===
+
* Fixed a bug in the nanocaust where any savegames that included them and which were from version 2.614 would fail to load in 2.616.
 +
** Thanks to Cyborg for reporting, although we also ran into it ourselves.
  
* 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.
+
* It turns out that in some older savegames, we already had the wrong data types on certain other objects, such as having DoomData on certain ships.
** 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.
+
** We fixed this in later versions of the game and had them become more strict with how they are loading the related data in order to now allow for this sort of wrong data to persist, but in turn this made some older savegames (from the 1.3x timeframe and prior) unreadable.
 +
** For those older savegames, we've now relaxed the restrictions to allow for the bad data to be read in, and it will throw a warning message as you load those saves but should still actually get them open properly (the example save that we have now loads fully).
 +
** Thanks to Strategic Sage for reporting.
  
* 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.
+
* Fixed an exception that could happen in certain circumstances after failing to load a bad savegame.
** Also standardized the naming of certain things.
 
  
* Broke the "official icon dictionary" out into six dictionaries:
+
* Further updates: after a savegame with old bad data is loaded in, it now discards that old bad data after it loads it. This has no effect on gameplay, it was data that wasn't being used anyhowBut this does make it so that if you save it in a newer version of the game and then try to load the NEW save, you aren't just right back in the same boat with it not loading the save because of that bad data.
** 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 isThere 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.
+
* Updated the TimeBasedPool class to no longer expand, but rather to start large and just use the parts that it needs, throwing any excesses away if there really are any that are that far out of bounds.
** This is a lot more flexible, and allows us to load icons from multiple asset bundles and/or multiple files within the same bundle.
+
** There was an exceptionally rare exception that could happen when shutting down the game or going to the main menu out of the game with the way it worked before, but much more common was some extra slowness in how it was having to resize arrays to handle those events in general.  That is all faster now, and can't have that sort of exception.
 +
** Thanks to Endovior for reporting.
  
* 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."
+
* Also put in some changes to further distance ships from pooling, and somewhat start a road toward prepping them more for the new style of PKID generation.
** 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.
+
* Fixed a cross-threading exception that could happen in UpdateEntitiesShownAtPlanetDirectly() if you were on the galaxy map view and a ship died at just the wrong time.
 +
** Thanks to UFO for reporting.
  
* The game is now able to load the xml files for external icons from any mod or expansion, in:
+
== Version 2.616 Stop Printing Money, AI! ==
** Expansions/[ExpansionName]/GameData/ExternalIcons/[thefile].xml
+
(Released October 14th, 2020)
** 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).
+
* Grappler Guardian balance updates from zeusalmighty, for those new units that come as a unique thing in the new AI Reserves mechanics Badger added yesterday.
** 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.
+
* Added a new Dire Singularity Guardian by zeusalmighty, for basically boss-level seeding in the new AI Reserves mechanics.
** 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:
+
* Fixed an issue where black hole generators that were not also on a ship with a gravitic core of some sort would not work.
** 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 ===
+
* Fix a bug where the scourge were spawning unlimited builders
 +
** Thanks to a number of people, including Sombre and ArnaudB for reporting.  Thanks to Badger for fixing even after retirement.
  
* The game is now able to load dlls from mods or expansions, rather than just from the central game folder.
+
* Fix a bug where right-clicking a journal entry could cause an Exception
** 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.
+
** Thanks to Ahnold for reporting. Thanks to Badger for fixing even after retirement.
** 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.
+
* You can read all about [[AI_War_2:Sunset_of_The_Badger_Era#The_Badger_And_Puffin_Legacy|The Badger And Puffin Legacy]], if you like.  Puffin retired earlier this year, and Badger is retiring now, so this is a good time to pay some respects.
** 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 ===
+
* The reinforcements seem to have a math bug in them, so we put in extra detail and formatting in how we export them.
  
* We also now have a non-billboarding version of our shader for purposes of our icons on the galaxy map.
+
* Fixed a math bug in reinforcements that was basically "printing money" once the game really got going, and would let planets of the AI reinforce almost infinitely.
** 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.
+
** We're not sure if this is fully a new bug, but it has certainly found new expression in the new reinforcement logic.
** 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 may have been an older bug that was somewhat suppressed by the old reinforcement logic, or it's a brand new typo, but because of how much code has changed it's hard to be sure.
*** 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.
+
* For the first time, we now have a way for the budgets of the AI to dump their details to log files. What we found was a bit surprising and definitely horrifying.
** 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 drawDefault is 2.2If 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.
+
** First of all, for quite a long time, apparently the logic for partially-neutered planets has been horribly wrong.
 +
*** If a planet was neutered down to 1 reinforcement point, then the budget would be 5% of usual, no problem.
 +
*** If a planet had not lost any reinforcement points, then the budget would be 100% of usual, no problem.
 +
*** If a planet had lost some reinforcement points, then the budget would... be multiplied by whatever the number of reinforcement points are.
 +
**** So, you killed reinforcement points down to 4 left out of 7 originalCongrats, the cap is UP by 400%.
 +
**** The correct number should have been 57% of normal, and now that works properly.
 +
** Then there was a really harsh AIP multiplier that was being appliedIt was adding far too much based on whatever the budget was, and larger budgets were more affected.
 +
*** Now it only adds budget for each AIP above 100, which is softer to begin with, and then it also only adds it based on 10% of the current running total, rather than on the entire running total.
 +
** Finally, there was a portion that was added based on time (number of 10 minute increments).
 +
*** This was also too harsh.  This is now based not on the running total of budget, but 1/10th of it, instead.  Making this also a much gentler slope.
 +
** None of these were new errors, but they were showing up now more because the reinforcement logic calling these budgets was so much more effective.
 +
** Without these in place, AND with the above actually-charge-me-the-budget fix in place, now reinforcements happen at a rate we would expect.
 +
** Thanks to ArnaudB and Crabby for the saves where we could verify it, and others also for reporting.
  
 
== Prior Release Notes ==
 
== Prior Release Notes ==
  
[[AI War 2: Building Multiplayer]]
+
[[AI War 2: Sunset of The Badger Era]]

Latest revision as of 14:46, 3 December 2020

Contents

Known Issues

  • Any bugs or requests should go to our mantis bugtracker
    • If you need to submit log files, those can generally be found under your PlayerData folder in the folder your game is installed in. The most relevant one is called ArcenDebugLog.txt. You can send us the whole thing, or just strip out relevant parts.
    • In rare cases, mainly if your entire game crashes (that almost never happens), we will need your unity player log. That gets overwritten the next time you run the game after a crash, unlike the other log. These can be found here:
      • Windows: C:\Users\username\AppData\LocalLow\Arcen Games, LLC\AIWar2\Player.log
      • macOS: ~/Library/Logs/Arcen Games, LLC/AIWar2/Player.log
      • Linux: ~/.config/unity3d/Arcen Games, LLC/AIWar2/Player.log

What Does Multiplayer Alpha Mean?

Please see this link for details on multiplayer. This wound up taking up too much space in this document, so all of the multiplayer-relevant bits have been moved to the other page.

What's this phase all about?

Multiplayer is fully playable at this point, but still has a variety of glitches and doesn't have all of the features that we intend to have in the long term. So hence it still being in alpha status. But we greatly welcome folks to play, and hopefully give us reports on what is going wrong if something does go wrong.

We expect to be to a fully-polished non-beta status for multiplayer in November or December, if things continue as they have.

Our second expansion for the game, Zenith Onslaught, has a whole heck of a lot of it completed, but still needs more doing. Badger has done all of his parts for it, and has retired like Puffin before him, so at this point we are down to basically a one-person show again (me, Chris) on bugfixing, finishing multiplayer, finishing my parts of DLC2, and finishing the last of the kickstarter obligations. So if the schedule slips some, it's likely because I had trouble juggling that, or wanted extra time to make things truly shine, whichever. But at the start of this phase, things are feeling very positive.

Version 2.646

(Not yet released -- we're still working on it!)

  • Civilian Industries Update
    • Updated for the latest version of the game.

Version 2.645 Hotfix

(Released December 3rd, 2020)

  • Fixed a wide array of exceptions that could happen, particularly as of the last version, if you had a partially failed save or quickstart load. If the playeraccount was missing, which is the real bug, then certain other parts of the code would spam tons of errors and obscure the real one. They no longer do.
  • Fixed a one-line typo with the recent changes to delayed invasion support for the nanocaust that was causing all older quickstarts and savegames that included the nanocaust to not be readable.
    • Thanks to Cel for reporting.

Version 2.644 So Many Good Things All At Once

(Released December 2nd, 2020)

  • Added a new "Invert Mousewheel UI Scrolling" setting to the HUD section of personal settings:
    • Description: Normally when you spin the mouse wheel forward, any scrollable areas you are hovering over in the UI go up; spinning backwards goes down. This lets you flip that functionality. OR, in the case that your hardware or OS is inverted for whatever reason, this lets you correct it to work like everyone else.
      • Note: if you also want/need to invert how your mouse wheel works when zooming the game view, then be sure to also set the 'Invert Mouse Zoom' option in the All Cameras section.
    • We also updated the other setting to also mention this one, so that if you find one of them you can find them both. We left them as two separate settings since some people might want one and not the other if this is a personal preference and not the "backwards linux mousewheel" bug.
    • We thought that this was something we could not fix without unity taking care of it on their end, but we took a peek at some of their old decompiled source code and found an efficient way to find all of the objects that need reversed scrolling and update them in cases where that is indeed needed.
    • Thanks to Blu3wolf, The Main Man, whetstone, TechSY730, Matruchus, Elos, carewolf, and others for raising the issue again.
  • Remove a mechanism where fireteams would deliberately overestimate turret strength; turrets are no longer under-valued strengthwise so this mechanic was now making the Hunter even more timid.
  • The Hunter is no longer allowed to retreat from a battle involving the AI Overlord. They must fight to the death there. This includes Exogalactic War Units.
    • This has been reported in a number of places, but most recently by Waladil on discord

Delayed Invasion Support

  • Marauders can now be requested to do a "delayed invasion", ie they won't start attacking until a ways into the game.
  • The Nanocaust can be set to invade at a random time during the game, or immediately. This replaces the old "Non-Immediate Nanocaust are seeded as beacons" paradigm.
    • If not explicitly requested, the nanocaust will appear in a beacon.
    • This change means the Nanocaust now works "correctly" in the game lobby.
    • This resolves bug reports from ParadoxSong and Isiel. Possibly others as well
  • Also you can request the nanocaust to appear on a player planet. This is a terrible idea unless they are your allies
    • Requested by Arc-3N-4B

Galaxy Map UI Additions

  • On the galaxy map bottom left bar, there are edit planet and ping planet buttons, but for now those are just going to have a "coming soon" tooltip on them. We'd rather not delay the rest of this release another day just for them.
  • The new default for when icons and text on the galaxy map stop drawing is 10, rather than 1.5. It will update existing settings for you.
    • This makes them always show, even if it does get crowded. Trying to use galaxy map filters with them disappearing was an exercise in anger management.

Planet And Unit Search

  • Added a new "GalaxyMapTextboxFunction" xml table, which lets us (or modders) define "a thing that uses a textbox on the galaxy map to do something."
    • That is vague somewhat on purpose. But mostly we expect it will be used for searches of various sorts.
    • For now we have implemented one for finding planets, and another for finding units.
  • There is a new bottom-left UI element on the galaxy map view. This has a number of functions built all into one.
    • First of all, it has a new find planet option, which is extremely responsive and lets you search for planets by partial text, darkening all others that are not including that text.
      • It also shows the names of all the planets that come back as possible matches, even if they would not normally be shown right now.
      • It does not try to do any centering on the planets it finds, as it might find many. But at any rate, this is a very dynamic and simple way to find planets by name.
    • Secondly, it has a function that lets you search for planets by name of a unit (ship or structure).
      • Any icons shown at planets will be shown in this mode, regardless of zoom distance.
      • Even better, it actually hides all of the icons that would normally be shown, and instead shows the first ship icon of each match that it's finding on that planet (if there are 100 v-wings, it will only show the icon for one of them, but you're usually not searching for something like that).

Fleet Status Window

  • Added a general new Window_BottomLeftSelfUpdatingTextWindow, which works pretty much like Window_ModalSelfUpdatingTextWindow from a code standpoint. However, this lets us give a non-modal (aka non-input-blocking) onscreen view of some sort of information over there on the left where chat and such would be. Tooltips and chat and similar will block this view, but otherwise it stays open until you close it, which can be useful for information players want to have at their fingertips and that a modder or developer wants to provide them.
  • Over the last couple of weeks, Badger has been working on a Fleet Status display that was kind of hidden up there on the attack buttons in the top resource bar. There is now a dedicated F Stat button on the galaxy map that you can hover over to find out about this function, and left click or right click to get information on local fleets or all fleets.
    • This is the first usage of the new Window_BottomLeftSelfUpdatingTextWindow, and it lets you keep an eye on your own status of fleets, or the status of allies in multiplayer, that sort of thing.
    • This is no longer openable off of the resource bar, but instead just off this new galaxy map button.

Galaxy Map Display Modes

  • Galaxy map display modes make a triumphant return!
    • All of the prior ones that were there were really old, not having been altered since... goodness, September 2017.
    • When we updated the game to a new UI style in 2018, these were disabled and we never got back to adding them in until now. With that said, we're revisiting what they actually do, or replacing them.
  • Normal display mode (what you've seen always for the last few years):
    • Ignores what factions you select on the left dropdown. Shows your strength on the right of each planet, and enemy strength on the left at each planet. Unit icons shown below the planet are a general mix of high priority units.
  • On all of the galaxy map modes, it now is sure to keep showing your own fleets, since those are useful to be able to select and click and such no matter what else you're looking at.
  • Metal Production display mode:
    • Shows how much metal the selected faction(s) are generating at this planet in gray, and how much is available but not used by that faction in red. Unit icons shown under the planet are one per type of metal generator.
    • Useful for seeing which planets have more metal that you might want to capture, where your main metal production is, and where your metal production has taken damage.
  • Energy Production:
    • Shows how much energy the selected faction(s) are generating at this planet in gold, and how much is available but not used by that faction in red. Unit icons shown under the planet are one per type of energy generator.
    • This is useful for seeing where you're generating energy in a visual way, AND for finding large energy generators that you might want to capture out in the rest of the galaxy.
  • Science And Hacking
    • Shows how much science and hacking points are left to be gathered on each planet. The only unit icons shown under planets are player fleets.
  • Strength:
    • One of the most useful display modes! Shows how much strength the selected faction(s) have at each planet. The only unit icons shown under planets are player fleets.
    • This is the really important filter! This is how you find out just how strong the hunter is, wherever it is, or easily pick out exactly where the warden is hiding. Assuming you have up to date intel, of course.
  • Strength With Top Ships
    • Mostly the same as the Strength display mode. However, this is much more cluttered because of the icons showing the three strongest units of the relevant faction(s) being shown as icons under each planet. So this is less useful than the general Strength display mode for seeing an overview of everything, but it's great for observing what the big hitters are at various planets all at once.
Faction Filters
  • On the galaxy map, there are now detailed faction filters for EVERY faction, including normally-not-listed ones, all organized into various categories with proper explanations.
    • This actually took WAY longer to create than we expected, but it gives the ultimate in flexibility in all that.
    • The nice thing is that this only fills in as you actually encounter members of each faction, so this starts out smaller but then grows substantially as you find sub-parts of the AI, etc. So for example, you likely will not see any Praetorian Guard entries for a while, and you would not see AI Reserves until they have struck you at least once, etc. No tamed macrophage unless you actually meet one.
  • Factions in general can no longer override CheckIfPlayerHasSeenFaction(), which we have upgraded to properly support beacons and other things of that sort.
    • There is now a new DoOnFirstSightingOfFactionByPlayer() that factions can override to get the same sort of effect they used to have.
    • You may need to let the game run for about one second before things will properly show up in terms of factions that should be visible.
  • Added a new FactionGroup class, which lets us start displaying/discussing factions by whatever arbitrary categories.
    • For now we have All, My, Allied, Hostile, and Beacon as the categories, with tooltips explaining each.
  • Added a new FactionFilter struct, which lets us mix actual factions with faction groups, and display them in a nice list that we can also sort.
  • Badger's fancy SortFactionsForDisplay() has been removed off of Human.cs and is now on BattlefieldVisualSingleton.
    • However, it should never be directly called anymore. It should now be retrieved from FactionFilter.GetLatestSortedFactionCompleteList() to get that result which is cached and only updated once every 10th of a second.
    • This now lets us get that from other parts of the code that are not in externalData, too.
  • Beacon factions that have not been summoned yet now show "(Beacon)" in front of their names.
  • Added a new is_considered_visible_part_of_the_ai_faction_for_filter_purposes for factions, which lets us have certain sub-factions like the AI Hunters and such show up more prominently in the list of factions in the galaxy map filters.
    • Also added is_considered_player_allied_for_filter_purposes for purposes of getting the Outguard to show as a player Ally even though they are usually invisible.

Updates To Included Mods

  • Fixed the spire railgun shop mod to use the newer xml that is about spire ships not working when not on a PLAYER planet, instead of a specific owner faction. This was a change we made for multiplayer compatibility, and it changed an xml tag.
    • Thanks to Badger for reporting.
  • Kaizers Marauders improvements:
    • Removed the ability to assign negative budget and in return changed and integrated the Invasion Time setting from Vanilla
      • Assigning negative Budget would work, but had its issues: Marauders were forced to start out very small, the timing was estimated at best and could vary incredibly
    • Now the player can choose Immediate, 1-10 hours and Random /Early/Mid/Late/Very Late game and Random All, which translate to 0-2, 2-4, 4-6, 6-8 or 8-10 hours of actual game time, with Random All being 0-10 hours
    • Essentially the mechanic is that in beacon mode the beacon will self-destruct when the time mark is reached, BUT the player can still destroy it earlier. During this time Marauders gain NO Invasion Budget
    • When not in beacon mode Marauders are prevented from doing any invasion logic until their time has come, but they passively accumulate more budget and will invade with quite a few forces. Note that they do NOT get any bonus budget from owning no planets as that would likely lead to much, much greater invasions yet...
  • AMU now has a new function: parseFIntFromStringUpToFirstSpace(). Can parse numbers like 1 / 1.6 / 100.738, etc. If more than 3 decimals are used any excess is discarded.

Bugfixes

  • Fixed divide by zero exception that could happen in the risk analyzers faction. This was not related to any recent changes, it just was apparently rare.
    • Thanks to Isiel for reporting.
  • Previously, mod names with spaces in them would cause the settings file on your machine to become corrupt and unable to be loaded. This should no longer be the case, although we've not tested it.
    • Thanks to ArnaudB and Isiel for reporting.
  • The capsule colliders on the lines between planets on the galaxy map no longer size up or down. This can mean that on very far zoom on very large maps it can be hard to get your mouse exactly over the line, but it's still very much possible and this is hardly a crisis. The main thing is that these no longer get in the way of the planets themselves, which may have been happening.
    • We investigated the planets themselves getting off on scale, but did not find any evidence of drift, and were already using the careful approach that we were considering "switching to."
    • We did also find a number of cases of places where things like notifications might have been getting in the way, with text that was extending beyond their bounds. We fixed all of those as well, in case those were what the problem was.
    • Thanks to AxiomExotic, afterthought, Vortex, Karlant, and Badger for reporting the problem with the hitboxes on the planets on the galaxy map still being there after long enough sessions of play. This may not solve it, but it does remove several areas of potential problems that were in place.
  • If a dropdown list is extended, and the number of items in the list changes, it now refreshes with the new options included. Previously, you had to close and reopen the dropdown list. That was potentially not possible to have happen as a situation before, but with the list of factions on the galaxy map it now is.
  • Fixed another issue with dropdowns still staying open after you switch to a different context where their parent window area is no longer visible. This was super noticeable with the new galaxy map controls.

Balance Tweaks

  • Fixed Veteran Sentinel Gunboat having lower damage than normal, due to being missed in a long ago previous update.
  • Fixed Cloaked Mugger having less health than the normal version, due to being missed in a long ago previous update.
  • Reduced range of any Tier 1 Extragalactic units that were above 8,000 (before global range modifier) to 8,000.
    • Due to mentions of most Turrets being incapable of fighting these, and these are the tier that will be hit in most normal games, excluding modded ones and Fallen Spire runs.
  • 'Ram' Auto Bombs swap their armour damage bonus for a new one, that works against armour of +90mm. Mass damage bonus increased from 5x to 7x.
  • Altered Parasitic starting fleet. Normal Parasites are replaced with 25 Parasitic Pike Corvettes, 1 Mugger is removed, and 40 Stalkers are added.
    • The Why:
      • Too many Parasites and not much damage led to this being a very slow start.
      • Thus, some Parasitic Pike Corvettes were swapped in for some extra firepower, but keeping zombification.
      • 2 Muggers is actually in excess of the normal cap size, so 1 is removed.
      • Stalkers are added to give this fleet more single target power, making up for the loss of the Mugger, and lets it fight things such as Sabot and Nucleophilic Guard Posts early on (things which counter said Muggers).
  • Dire Tesla Guard Posts weapon jam works on armor <= 90, rather than <= 101.

Turrets

  • Altered "large" Turret energy costs to have the same "cap scaling" as the "small" Turrets.
    • E.g a Pike Turret cost 2,250 energy. A Crusher Turret cost 37,500 energy.
    • A full cap of Pikes would be 5, costing a total of 11,250, compared to the full cap of just 1 Crusher Turret, still 37,500.
    • Now, the Crusher Turret costs the same as that full cap of Pikes.
  • Mini Fortress energy cost halved.
    • An exception, due to a report about its power, this has less of a change (66% reduction often).
  • Crusher Turret magnetic pull range increased from 4,200 to 6,500 (before global range modifier of 0.8x). Crusher weapon range changed from 1,000 to 1,700, hits 20 targets instead of splitting damage evenly, net DPS the same.
    • The last part lets it focus damage more, rather than spreading it out so much it doesn't help to kill anything off.
    • Also hopefully improved its pull targeting.
  • Acid Turret effect increased from 50 to 65, shot count 3 -> 5.
    • Will attempt to add Mark scaling to the effect, requires code investigation.
  • Increased target priority of Bulwark Turrets a chunk.
  • Doubled the self-build rate of the "Raid" technology Turrets, excluding Blitzkrieg which is a "large", and did not have the appropiate build rate for its size. It now does, and then that is doubled, leading to it being 6x what it was before.
  • Fusion Turret reload time reduced from 2s -> 1s, damage 700 -> 350, loses shield bypass. Instead, gains a 12x damage bonus versus personal shielding.
    • This replaces the ability to quickly destroy structures (not too useful on defense) with instead a highly supportive role, potentially useful combined with Imploder and Subverter Turrets.
  • Fuseball Turret range 10,100 -> 15,000.
  • Makeshift and Blitzkrieg Turrets no longer spawn units on death. Instead, they use the "drone guns" present on Combat Factories, as well as Tesla Torpedo and Tackle Drone Frigates (they have infinite range).
  • Makeshift Drone damage reduced 33%.
  • Increased Vampire Turret damage 25%.
  • Shredder Turret range increased from 4,200 to 5,200 (before global range modifier), damage increased roughly 30%.
  • Increased Imploder Turret damage 50%.
  • Doubled Deathgrip Turrets tractor count, increased range from 4,200 to 5,200 (before global range modifier), damage increased 20%.
  • Increased Jammer Turret damage 50%.
  • Increased Translocator Turret damage 50%.
  • Doubled Tritium Sniper Turret damage, halved multiplier.
  • Increased Fortified Tesla Turrets cap sizing to the same as normal 'small' Turrets. Reduced health by 40%.
    • Cap health is the same, cap damage is up 66%, but in the hands of the AI they are easier to kill (who don't get any more or less from current).

Aggro Invisiblity, And Drones In General

  • Added a new cannot_target_or_alert_ai_reinforcement_spots option for ships, which provides the following new ability:
    • AGGRO-INVISIBLE: Enemy target ships and structures (mainly guard posts) that contain guards cannot detect this ship, and this ship cannot fire upon those targets.
      • Once those targets have been alerted and have released their guards to fight, those targets can then be attacked by this ship.
    • Thanks to Strategic Sage and zeus for inspiring this addition.
  • The new Aggro Invisiblity ability has been given to all of the sniper ship variants, sentinel gunboat variants, sniper frigate variants, sniper guardian variants, and sniper turret variants.
    • This prevents them from engaging guard posts and similar unless those guard posts are already aggro'd, and thus not alerting an entire planet just because you bring them along.
    • Why have this on the guardians? Mostly for AI Civil Wars, but also in case you capture some.
    • Why on turrets? Mainly for purposes of beachheads.
    • Thanks to Zoreiss, AnnoyingOrange, Asteroid, Fluffiest, and others for reporting.
  • The various drones that had been switched over to the "drone gun" format as of a few weeks ago have been returned to the regular drone behavior.
    • Thanks to discussion with Strategic Sage for letting us know how much the new format was not great.
  • Pretty much all drones use the new Aggo Invisibility ability.
    • They can still go hit things right next to guard posts without causing an issue, and they can even hit guard posts that have already emptied their guards.
    • Guard posts can even still shoot at these drones if the guard post has any weapons, though the drones can't shoot back until the guard post is aggro'd by something else. These drones would not bother going near the guard post unless there was something else there to shoot, though.
    • Thanks to Puffin for helping set all this up.

Beta 2.642 Nearing Beta For Multiplayer

(Released November 30th, 2020)

  • Fix a bug where the Incoming Exo Notifier would show the wrong % when it was sync'd with something
    • Thanks to afterthought for reporting
  • The Metal Flow Planning screen works again
    • Thanks to Crabby for reporting
  • Scrapping an MDC or GCA now correctly triggers the AIP increase
    • Previously if an MDC was about to be killed, you could scrap it to dodge the AIP increase
  • The tooltips for savegames in the save and load menu now includes what players are in the game in question (with that colorized), and also includes what size the savegame is on disk. The former is particularly useful when you're trying to remember which games you were playing with what other players.
    • We also shifted how we are finding the last write time for each file, which hits windows security less hard and thus makes opening the load game menu vastly faster when there are a bunch of files on windows in particular. This may also be somewhat faster on linux and OSX, but on windows in particular if you had dozens or hundreds of savegames, it could take a second or two to even open that window.
  • The way that error windows appear has been updated to be a lot more legible, as well as a LOT more dramatic and scary-looking. Wow that's a lot of red!
    • This was one of the last parts of the game that was not just in AN old UI style, but in the old UI style from the first prototypes back in 2016. Go figure.
  • There is a secondary error message window now, which is used when you try to load a savegame or quickstart or do something in the lobby or joining a new game and have some sort of error doing those things.
    • Those errors tend not to be fatal, and also tend not to repeat infinitely, and so it gives you a simple "ok" button that you can use to close the error and which then clears the history of how many errors have happened this game.
    • In recent versions of the game, you could try to load one broken save, get a message saying it's broken, then load a valid save and have a permanent blot on your UI saying that there were something like 2 errors since you started the game. Now that doesn't happen.
  • The metadata for savegames is now loaded asynchronously, except for its file size and last modified date. The actual rest of things that are shown in the tooltip data is loaded very fast, but not on the main thread. This means that the load menu opens even faster, on any OS.

AI Intelligence Improvements

  • Fix a bug where fireteams going after MDCs could get hung up on not wanting to attack planets between the MDC and the Hunter.
    • Hunter ships required to go after a particular target (like an MDC) are now allowed to explicitly attack planets on the way
      • Thanks to ArnaudB for reporting
  • Tsunami CPAs will now wait a minute or so after launching to gather their forces before they attack. The goal is to make the initial CPA punch a bit stronger; previously they were trickling their forces in piecemeal and not providing as much of an impact as desired.
    • It will still look just like the same behaviour to the player once the attack starts, there will just be a bit of a pause between the CPA spawning its ships and then those ships actually hitting your planets.

New PKIDs Approach For Multiplayer

  • WARNING TO MODDERS! We don't suggest you just do a global search and replace for your various places in the code that are now calling methods marked as obsolete.
    • As tedious as it is, you should go through those line-by-line and swap them over to the new non-obsolete variant, which will note that it returns null in MP.
    • With all of these calls, it's up to you to check to make sure that if the method you just called returns null, you ignore whatever happens next.
    • In general, if there's anything that is changing more data about the entity that was just created only-on-the-server-but-null-on-the-client, then have it skip that logic, but do all the rest of the logic. A general return out of the method you are in is not usually the desired approach (but it does vary by situation).
    • The faction data will catch up on the client either way, and all of those changes you make to the entity after the null-return-point will be passed over to the client as well. However, if you don't handle the null-return-point, then players will get nullref exceptions in your mod only in multiplayer, which will be frustrating for everybody.
    • The one exception is CreateNew_DuringMapgen. You can just search and replace for that with CreateNew_ReturnNullIfMPClient unless you were using it wrong to begin with.
    • There may be entire methods now where you want to check if ArcenNetworkAuthority.DesiredStatus == DesiredMultiplayerStatus.Client and just return before it even thinks about making any entities. See things like ReactToPowerLevel() on the AI for examples.
    • TLDR: This is a minor pain in the rear right now, and looks a bit tedious to do. But this is far simpler and far less tedious than getting bug reports from MP players that you have to chase down for your mod in the future.
      • If you wind up with questions, then @ chris on the Arcen discord channel.
  • Added a rather complex new ArcenDelayedDeserializationBurst class, which uses a really efficient way to store network message for future deserialization.
    • We normally reuse our deserialization buffers, so it's an extra delicate class. As long as nobody ever tries to use this in some new way beyond the way it is currently used, all will be well. The code is filled with dire warnings in the comments.
    • The capability that this adds is essentially for us to have slightly time-delayed execution of network data unpacking from the host to clients, if the host is a bit more than 1 sim frame ahead of the client.
  • The MayCreateEntities bool has been marked as obsolete, and is never set now, as all threads (even long-range planning ones) are now considered A-OK for immedidately creating entities as much as players want to.
  • SpawnEntity and SpawnEntityOrReturnNull have both been marked as obsolete (and will block modders from compiling against them), but will still for the moment keep working with existing compiled mods.
    • This is how we're going to try from now on to handle when we change the specifications of things that would break mods, where we can. It gives modders a chance to catch up.
    • In this case, it now wants you to use the new SpawnEntity_ReturnNullIfMPClient() method.
    • The same is true for the various CreateSquad methods, all of which now want you to use CreateNew_ReturnNullIfMPClient.
  • GlobalLastSquadIDSourcePrimaryKeyID no longer exists in savegames.
  • The ability to generate PKIDs for speed groups, fleets, squads, shots, and otherIDs are all now exclusively host abilities.
    • If a client tries to call these, it now returns -1 for the client and throws a visible error message on the client.
    • A bunch of cases where we were syncing these over to the clients are removed. We no longer care, for the most part.
  • The game now has a new "Fast Blast of Created Objects" that the host sends to clients.
    • In these cases, essentially when you go and try to create something that requires a PKID that would be consistent on the clients and the host, the clients just skip doing it, but the host does it and then sends it to the clients asap.
    • The host is usually a few hundred ms ahead of the client at minimum, and so if it's on a future frame number from them, then it tells them at which frame to unpack its new data.
      • If the client is closer to the host in time, and the frame gets there late, it still just unpacks it and can sort out minor discrepancies later.
    • The idea here is that a LOT more things are just being done on the host, and skipped on the client, and the client is getting the information in small download packages that it inserts into its own sim at the appropriate time.
      • There is some very slight divergence in sync caused by this, but it's pretty darn slight in most cases.
      • The great news is that this uses less network data, and substantially less CPU power, on clients than having wrong IDs assigned does. This lets us just send the correct object once, rather than creating the wrong object, discovering it, requesting a fix, getting the correct object, and deleting the wrong object.
    • This is a fundamentally different approach to object creation, and in some ways this has a bit more in common with an MMO architecture, except things are faster and more responsive than your average MMO. But this is now blending a third general model of network code into our existing interesting stew of models. It pairs really well with the other bits.
  • On GameCommands, we now have the ability to specify how many entities of various sorts we plan on creating (or potentially creating), and then the host provides available IDs that will be consistent on the client and the host before the execution happens.
    • This is yet ANOTHER approach, but is one of those cases where we take the most efficient networking approach for any given type of data event. That is surprisingly optimal, it turns out.
    • The idea is that which networking model is superior is really contextual, so we look at the context and use the best one in any given circumstance. Any errors we make are already handled by the sync code (that's not new), but this cuts down on the number of errors.
  • Added a new "Log Decoded Network 'Fast Blast' Sync Data To Disk" setting to the network section, which does what it says on the tin.
  • The way that shots appear, and the way that shot sound effects are triggered, have both been updated in order to support the new way things function in multiplayer.
    • We were looking in particular for silent shots, or shots that did not show things like their AOE effects. Those are all working.

Other Multiplayer Miscellany

  • Unrelated to the rest of this, the clients now send their GameCommands completely separately from their "finished a sim frame" messages.
    • This lets the client send the GameCommands in a more timely fashion, thus reducing command lag on the clients.
  • Fixed an issue that we don't think anyone hit, but where if you were playing one multiplayer game and moved to another one it could execute some commands from the prior game on a delay.
  • Fixed a wide array of minor glitches and annoyances that would give clients warnings or errors (visible or otherwise) in multiplayer.
  • A lot of classes serialize themselves more clearly, ranging from shots to wormholes to gamecommands and beyond.
  • In the event that the host sends over world data that errors, the client should now wind up back on the main menu.
  • Fixed a number of small serialization issues between multiplayer, including errors when new planets are created. The creation of new planets and their various links between one another are now verified to work properly between the client and host. Aka the Dark Zenith invasion in DLC2 (spoiler alert, though that doesn't tell you much).
    • We have NOT yet verified if nomad planets work properly in multiplayer now (displaying properly on clients to match the host), and would appreciate if someone checks that out once this build becomes public.

Version 2.638 Why Do We Fall, Master Wayne?

(Released November 25th, 2020)

  • strength_multiplier_for_turrets has been 2 since we added this, but that seems to overestimate their power a bit.
    • We've adjusted this value to 1.55, per discussion on discord and a suggestion by TechSY730.
  • Added a new strength_multiplier_for_armed_guard_posts, which lets us adjust up the strength of guard posts to be more accurate if it seems to be undervalued.
    • We're starting this off at 1.25.
    • Thanks to TechSY730 for suggesting.
  • We also added a new strength_multiplier_for_non_combatants, which lets us adjust down the strength of anything that doesn't have any guns.
    • Sometimes things without guns still have a lot of health and shields, and that's really not something we want to consider as strongly since it can't hurt you directly.
    • This would affect forcefields, any sort of captured buildings, and things like unarmed transports.
    • We're starting this at 0.4.
  • A new balance_seconds_after_transport_change_before_can_switch_back has been added, with default value of 3, that prevents players from putting ships into and out of the same transport more frequently than within 3 seconds.
    • In multiplayer, we need a small bit of time to refill the list of pooled IDs for upcoming player transports. In reality that only takes a second or two to refill, but potentially less than a quarter second.
    • Originally we had thought to have this be an even larger window, like 30 seconds to prevent players from messing with the AI by popping in and out of transports, but there's already a 5 second no-firing time limit that covers that. And folks on discord made their feelings about that change pretty clear (it was not welcome).
  • Home forcefield generators can now be scrapped just like all other FF generators. From back in the pre-fleet days they were not scrappable because at the time you could never then rebuild them. Now you should be able to rebuild them, so you can also scrap them.
    • Thanks to Democracy for reporting.
  • Updated AMU
    • Now uses all the new Icons for Metal, Energy, Hacking, Science and Strength
    • Removed the SimpleStringBuffer as it is now less efficient compared to the ArcenCharacterBuffer and ArcenDoubleCharacterBuffer
    • Gave the latter two 35 new functions, most of them adaptions from the SSB or shortcuts from formating inside the AMU Core
    • Thanks to NR SirLimbo for adding.
  • Updated Kaizers Marauders
    • Tooltips, based on the above logic, are now faster and produce less GC Churn
    • Also dynamically rounded the percentages in the outpost description to show up to, but not always 3 decimals
    • Removed an extra line inside the Player-Owned Kaizer full descriptions.
    • Thanks to NR SirLimbo for adding.
  • When a stack dies and is going to spawn something on death (such as hydra heads as one example), then the new things that are created come out pre-stacked in the same ratios as the original.
    • So for instance, if a stack of 3 is vaporized, then a stack of 3 heads is created. If each should create 2 heads on death, then 2 stacks of 3 heads are created.
    • This is a lot kinder to the CPU and performance in general during heavy death situations with hydras aand similar.
  • Before you can start hack, the game checks that you have enough hacking points. This check now also counts active hacks.
    • The goal is to make it harder for players to wind up with negative hacking points.
      • Thanks to ultamashot and NRSirLimbo for reporting
  • A ship in an exogalactic strikeforce now shows "Exogalactic Strikeforce" instead of its faction name when hovered over
    • Previously it was really hard to tell if a unit was in an Exo or not.
  • Rework the way Exogalactic War Unit spawn locations are chosen to prevent the case where the AI was accumulating large numbers of Exogalactic War Units on its homeworld, if they were required to go after factions with other things in the way.
    • If the War Unit is against the player, the war unit spawns at the AI homeworld.
    • If it is against a non-player faction then if there's a safe path for the war unit to get to the target faction from the AI homeworld, it will spawn at the homeworld.
    • If not it tries to find any warp gate with a safe path to the target.
    • If it can't find a safe path at all then it will spawn directly on a suitable target. Minimally tested but seems to work
    • Only applies to newly spawned Exogalactic War Units
      • Thanks to a number of people for pointing out that Exogalactic War Units could get stuck, most recently zharmad and ArnaudB
  • Since we are not actually using the SquadIDSources, it makes sense to provide older methods that the various code mods like Civilian Industries were looking for. StarKelp is not able to update that this week anyhow, so we made some changes to make sure that his stuff still is compatible with the new version of the game anyhow. So far as we can tell, Civilian Industries seems to work again.

Bugfixes

  • Improved the error handling on incoming_damage_modifier to be more clear.
    • Thanks to NR SirLimbo for reporting.
  • Fixed an exception where any damage modifiers that were hull only would throw an exception when you tried to apply them.
    • Thanks to NR SirLimbo for reporting.
  • Fixed an unusual error that was possible to happen in ReinforceSpecificPlanet(). Not sure why this was happening, but there's a vague chance it may have been related to mods. At any rate, it's no longer possible to get the exception.
    • Thanks to Isiel for reporting.
  • Fixed an issue where cluster bombs would not spawn more bombs because they were not dying from enemy fire. Now the only reason that sub-bombs won't be created from things like this is from a unit intentionally being scrapped.
    • Thanks to Puffin for figuring out what this problem was, and to ArnaudB, Isiel, and Democracy for reporting.
  • Fixed an issue with the name generation for multi-owner factions so that it now properly says the names of the multiple owners. Previously, each party was incorrectly just seeing their own name as the owner. Of course, in these situations it's best of all to give your empire a specific name, but you don't have to.
  • Spire cities should now work if they are on planets owned by other Players
    • Reported by NeverZero

Improvements To Error Handling

  • Put in a bunch of wrapper methods for various faction methods that are commonly used by mod factions. These wrapper methods let us gracefully catch exceptions from the mods and then disable that part of the modded faction so that the game can continue without you having an endless spiral of exceptions.
    • For instance, in this build of the game we have broken both Kaiser's Marauders, the AMU, and Civilian Industries. Rather than having those be absolutely unplayable savegames with infinitely logging errors, it now pops up some errors the first time, then shuts off the brains of those particular factions. So you'll see those factions stop working and just kind of sit around (or use whatever intelligence there is that is coming from the central NPC logic), but the savegame itself won't be a total loss.
    • It's still best to stop playing after you have exceptions like these, but it doesn't make you completely dead in the water.
    • We also implemented a neat new thing where we are able to detect even caught exceptions inside these methods, so if the mod author is doing their own error handling, we still find out about the error and shut off that faction.
    • It's worth noting that this applies to base game and expansion factions just as much as it does to mods, frankly. In general this is pretty handy for letting parts of the game essentially have a stroke and die without turning off the rest of the game or leading to endless errors that cause lag.
  • In the list of factions in the escape menu, if a faction has had any sort of fatal error, it now shows "FATAL ERROR IN FACTION" next to it, with animated red and orange colors going past.
  • Whenever you have an error message popup, it's only showing you the most recent error out of potentially a long series of errors. Now the game has a first line there that is "Errors since start," and that counts up as more errors are logged. It may count up while you're reading an exception, for that matter.
    • The idea is to make it so that people don't just see the last error and think that's it.
  • If you have had an exception happen in your game in the last 5-10 seconds, then it now shows the count of errors since the start in the chat sidebar. This way you can't miss the fact that errors have been happening recently, and if you're in the unfortunate situation of having ongoing errors every few seconds then you will see that counting up and be aware of it. Sometimes people would hit "ignore all" and not realize why their disk was still being slammed by errors, and the fact that things were probably not working quite right. Now it will be impossible to miss.
  • Similarly, if any factions that have partially shut down from having errors, it now has a count that just won't go away up in the chat area that says "Factions Shut Down From Fatal Errors: 3" or whatever the number is. This is not so obtrusive that you can't keep playing, but it's obtrusive enough that maybe you'll realize you should stop playing if you care about those factions doing anything.

Failed Experiment: PKID Generation Revisions For MP Client Smoothness

  • An older approach that we were going to take with Primary keys, with a new PKID struct and a PKIDGenerator class, has been stripped out. It was going to be too unwieldly to implement, and would have made filesizes and network data a bit larger. We have come up with a better approach since coding that. It was never used, but the plan was to use that to keep multiplayer sync in better shape.
  • We only care about PKIDs for squads in terms of where things are diverging so much, so we've got a new SquadIDSource class.
    • The squad creation methods (in the codebase, "squads" are all ships and buildings and units) now mostly require a SquadIDSource to be passed in.
    • These sources keep some certain number of "for future use" PKIDs either for the faction or some other scope, and usually for some sort of sub-purpose on a faction.
    • These are serialized to disk and across the network, and every sim step have their pools replenished and synced over to other players from the host.
    • In the event that a source has run out of IDs to distribute, it has a fallback source which is usually the "failover" pool of IDs on the faction in question.
      • This first level of failover means that it is more likely to not have collisions when trying to find something to fill in for a source that was too thinly populated at the time of being called.
        • A single faction is more likely to mostly be synchronous relative to itself in terms of actions, so desyncs between clients are less likely.
        • But additionally, even if it is a desync, it winds up limiting the scope of the cascade of desyncs to mostly be limited to that one faction rather than affecting many factions all at once.
    • In the event that the failover has ALSO run out of IDs to distribute, then it goes back to the main central ID generator that has always been used up until now.
      • This is almost certainly going to cause a minor desync, or several minor ones, in multiplayer. However, these are going to be corrected by the same process that currently corrects multiplayer and makes it work as smoothly as it does.
      • Right now, MP clients are seeing things like every new ship that is spawned getting duplicated and then recreated, or just shifting spots. This is annoying in terms of how constant it is, but overall even with it having a desync EVERY time something is created, it's not that in-your-face that you can't play just fine.
      • So at any rate, there are multiple levels of prevention aimed at stopping this in the first place, but when it does happen it's not the end of the world and the game just recovers and keeps going like it has in all the MP versions prior to now.
    • The goal with all of this is to make things more smooth for clients, particularly when they are building ships from a factory or placing turrets and similar directly. And a secondary goal is to reduce some extra sync fix network traffic. But in the grand scheme, long-term sync is already assured by all the other characteristics of our multiplayer engine.
  • To support the new SquadIDSource class, there are a wide variety of sources that are placed throughout the codebase for various purposes.
    • As noted, all of the CreateSquad() and SpawnSquad() methods now require a SquadIDSource to be passed in, but if you don't then they will work out how best to get an ID to work around that lack.
    • However, for modders and faction coders, the way to update your code is relatively straightforward.
      • If you are doing something in the "long range planning" that creates a squad directly, just know that you're already immediately creating a desync, since that only runs on the host.
        • The game will recover from this automatically, but it will be wrong on the client with these new units you just created for 1-5 seconds, and may be wrong with some other units created around the same time. So ideally don't do that.
      • If you are creating squads directly in the "stage 2 or 3" methods, then you will now want to almost always use CreateNew_ForFactionBackgroundGeneration().
        • That method gets its own SquadIDSource inside itself, and there are loads of queued IDs in that source, so your risk of causing any desyncs at all with this is remarkably low. And if any do happen, it's probably not going to bleed over to something the player notices very easily.
        • There is also a version on faction that is SpawnNewUnit_ForFactionBackgroundGeneration() that takes the place of what was SpawnNewUnit() before.
      • If you are creating squads during part of mapgen, such as initial seeding logic for instance, then you should use the CreateNew_DuringMapgen() method.
        • This method entirely bypasses the SquadIDSource class, and just generates IDs directly. Mapgen only happens on the host, prior to syncing to everyone else, so there's no need for those sort of ID queues there.
        • If you mess up and have a method that uses CreateNew_DuringMapgen() both during mapgen and after mapgen, then you've probably introduced a minor desync with whatever is created, but again it's something the game will auto-correct within 1-5 seconds. The good news is that it should not really affect any other units than the ones you used this way.
        • Conversely, if you mess up and use CreateNew_ForFactionBackgroundGeneration() or similar during mapgen, then it will just do things as normal with not even any slight ill effects.
  • In single player and multiplayer, you can now see the ID stores and the statistics about the ID usage in the memory pooling section of the escape menu.
    • All savegames are a bit bigger now, maybe about 100kb or so. It's a fairly small addition in general, but in one example save we have an extra 65 thousand IDs pre-generated for use in specific scenarios. We can see even in a single-player game if it's ever hitting the central stores, etc.
    • You might wonder why we are also using this in single-player, but in general this does not cause a performance hit, and we have always tended to do everything the same between single and multiplayer even if that's not strictly required, so that we could maintain as few differences and as consistent of performance as possible.
  • The PKID Sources are now fully synced over the network in multiplayer, and they are centrally stored for reuse and assignment within savegame and across the network.

The Actual Result, With Intriguing Data

  • For now, after all the immense amount of work to get SquadIDSources working (and the two days after it to figure out the one-line networking error --which wound up having us greatly expand a bunch of debugging tools for multiplayer in general at least), we're currently choosing not to bother filling the SquadIDSource objects at all.
    • With this in place, they wind up adding an incredibly minor amount of overhead, but no actual functionality.
    • The fundamental premise of these is to try to reduce collisions of PKIDs between the clients and the host by having them queued up and ready to go, but that... really doesn't seem to happen. There are too many things in motion constantly, perhaps? It's honestly kind of hard to say exactly why this doesn't work, at the moment.
      • The most obvious answer is that the timing is too tight, but the Sources being filled with a certain number of values in advance really should be working around that. So that would seem to indicate that maybe there's some secondary problem, like the order of the queues getting messed up during sync, or something like that.
      • A more subtle answer, which is probably the correct one, is that we have two different timescales of network communications. On the one hand, we have the network sync info, which gets applied immediately. On the other, we have GameCommands, which get applied 100-200ms later. It's seeming likely that the sync of the queues is removing key entries from the client before the client can actually make use of them, since the client may be on a 100ish ms lag from the host. This could be solved in a variety of ways, but would need more testing.
      • However, seeing these in practice, the savegame sizes go up dramatically, and there is a notable slowdown in performance on the clients, which we didn't really expect. Part of it just has to do with how many factions can be in the game, particularly factions that are minor-use or only have a few units in them (tamed macrophage, etc, which may not even be active). This whole thing adds a definite per-faction extra cost in terms of data usage, and running out predictions for a long games is fine... but doesn't really feel great. What's notable is that turning this off feels like a breath of fresh air in terms of performance immediately after, so that says something right there about how advisable this is. Is this worth fixing?
      • Deciding if this is worth fixing or not is not something we want to decide late at night after three very frustrating days of staring at this and related problems, so for now we're just leaving it empty and pushing out this release so that folks can have the many many other fixes that we put in this build. This build has been delayed long enough by this blasted feature.
      • If this particular approach for PKIDs isn't used, then what do we do? Well, there are a variety of options.
        • On the one hand, we could do nothing. The sync code already corrects divergences, and is doing so with a minimum of bandwidth and no extra savegame file size, etc. However, it does cause minor jitter on new ships on the clients, which we don't like. So that' not our first choice. It seems like a lot of people don't notice this much, but at the very least for directly-placed human ships we can do better.
        • So, on that note, we can adjust the way that units are created. Right now, there are many places where the simulation creates a unit, and it tries to do that in lockstep on the clients and the host. This... may simply be not the way to go. We've contemplated this before, for a long time in fact. It may be a lot more tenable to make it so that the "create unit" code actually only runs on the host, and then that data gets synced over to the clients asap.
          • Originally this was something we had discarded because it would require a huge refactoring of all of the code for all of the external factions and mods. Not just a search-and-replace sort of change, but a really deep dive shift in the creation of all units. That is highly undesirable for many reasons. One of the reasons is that it would negatively affect the feel of the game on the host, and in single-player, because in theory we would be creating new units via GameCommand, which is something that happens on a delay.
          • The thing is, creating units only on the host doesn't mean it has to happen in a GameCommand. Actually one of the things that this entire code branch with the sources has demonstrated is how VERY fast we are able to get information over to the client. Normally we want to have new things get created and sent to clients via GameCommands in an orderly fashion as part of the main sim loop... but the thing is, the sync code is really freaking good. In almost all cases, if the ships actually appear 100-200ms early on clients, that matters... why? In reality, it doesn't seem like it matters much at all. If that causes a minor desync, it's still far more minor than the desync that we're getting right now with units having wildly wrong PKIDS. Likely their position or other stats would be slightly off on the client, and that is REALLY trivial to fix within seconds, and happens automatically already.
          • Overall, even though the PKID Sources approach was a complete dead end (probably) in a direct sense, this does provide some ways that we could theoretically reduce sync errors when it comes to even things like shots, which we've been concerned about for a while with IncomingShots being off since we don't consider shots worthy of sync (they last too short a time). But if we used the back channel data to generate shots only on the host, and had those synced to the client only once, on creation, that might be very interesting indeed. One of the possibilities with shots and even units is that we add a new SimFrameStartedExisting or something to that effect, and if that's in the future then the client just keeps them as invisible and not part of the client sim just yet. That would allow the host to give early "hints" to clients, who then have data ready to go as soon as the appropriate sim frame rolls around. Heck -- the clients don't even have to have fancy new logic for holding those units in abeyance. They could simply keep the data in its packed form until the appropriate frame. This would be very lightweight.
          • Ironically, this even paints some ways in which the "only create ships from gamecommands" approach of the "long term planning" code that is host-only is something that we might need to do away with. That would make things a bit simpler on modders if we go that way, and it would even allow us to in theory shift some of the per-faction processing onto non-sim-blocking threads. The only reason that those need to be sim-blocking right now is in order to maintain sync in multiplayer. But the thing is, we never expected for the general baseline sync to be this good... or for there to be such an effective faster-than-sim backchannel for the host to shuffle data over to the client. Despite this being our third coded multiplayer model over the span of 7ish released multiplayer games, this one really takes the cake for being the most advanced, and it has revealed some interesting new avenues to consider.
    • So the bottom line is, at first this really felt like a huge waste of time, on top of being a monumental disappointment. After taking a break for an hour or so and putting my kids to bed and thinking about it some more... this is actually pretty interesting data, and suggests that we may be able to be even more "fast and loose" with things than I ever expected, and thus really take the potential worry away from modders and faction designers, lower the network load, keep the savegame sizes small, and still improve sync. Having the host be fully authoritative over PKIDs was not something that seemed like it would be possible without introducing input lag on both the client and the host... but we already have the most minute (100-200ms) of timing lags between the client and the host, so that actually opens up a ton of options.
      • Crazy sidebar? One of the things that particularly bugs me about playing multiplayer right now, as the client, is the input lag. There's a lot of strictness that we have going on with trying to keep the client close to the host in timing, and making sure that GameCommands are executed at just the correct timestamps in the correct order, etc. But what if... we didn't care? Why not let the client instantly ask the host for things, and the host instantly execute them, and tell the client to also do the same? Sure it would introduce some new timing inconsistencies, but... so what?
      • Also crazy, still sidebar? This is even a way to potentially get around dropped packets and other situations with high latency or high ping. Let the host just get ahead, who cares, have the client blunder on without permission and catch up with what the host wants in a few hundred ms after the network blockage has cleared. This pulls the game further and further away from even pretending to be a lockstep multiplayer model, but to be frank, the performance that we're seeing, that we're able to get, is what makes that a feasible thing.
      • Want to stay in crazy sidebars? Things like FInt, our fixed-integer math struct and its related code, could largely be removed from the frequent sim calculations. There are some MUCH faster floating-point math functions, several of which use SIMD, that we use right now only for non-sim purposes. But it's already clear that the amount of drift we see in a few seconds is next to nil, and we're syncing things so frequently that any real drift that mattered would be correct within seconds, and typically would be smoothed out by the very awesome lerping that the vis layer does to keep things smooth in general.
    • So... yeah. This experiment was a huge disaster, on the surface. On the other hand, it took me through every piece of the code that creates units at the moment, and gave me an enormous amount of data on how some of the data is able to be passed around faster than game commands. I will need to weigh my options carefully, and probably focus on gradual improvements over time since the baseline is already pretty good right now. But making things more host-driven ought to be one easy quick improvement for sometime very soon.

More Multiplayer Technical Work

  • Removed some debug lines on the network clients about wrong key syncs (which always showed as zero because we wound up never deciding to check for that).
    • The adaptive system for sync that has continued to evolve out of seeing real data basically made that irrelevant.
  • The new sync of the PKID sources is now split out into its own separate sync cycle (for time slicing purposes mainly), separate from the faction sync.
    • Also separated out the "external data" of factions rather than having that be in the "Faction basics" sync.
  • The "Show Network Sync Details In Escape Menu" option in networking has been moved to the top of the other networking features, as it is the most helpful one by far.
    • It has also been given the prefix "Helpful: ".
  • Added another new setting to the network section, as well: Log Decoded Network Faction Basics Sync Data To Disk
    • Description: Same as the 'Log All Decoded Network Sync Data To Disk' setting, but only writes data for the faction basics that are periodically synced. If something gets awry with that data, this is a way to figure out why there's a discrepancy.
  • Multiplayer sync messages are now numbered by the host, and the clients read the number out when they get the message. This way, if a host sends out a sync message prior to a client joining, or a client misses a message or whatever else happens, the logs will still match up on both ends and are something we can compare.
    • We were running into the baffling situation where the logs did not match in ways that should be impossible, but this was because the clients and host were being allowed to number their own messages independently.
  • ArcenExternalData-RowIndexNonSim is no longer logged in general, because it is specifically something that is non-sim and thus will be different on the clients and the host. The matching isn't done based on it, so it's not a part of sync that matters.
  • We slightly reduced the maximum fragment size that we're willing to send, from 512kb to 500kb, still minus 100 bytes in both cases.
    • We had one report of a user on Steam getting an exception when trying to connect with the prior limit and the new limit does not make much practical difference to anyone else.
    • Specifically it complained about 524,199 bytes, when 512kb is actually 524,288 bytes; with the new limit of 500kb, that is coincidentally 512,000 bytes, which is potentially the actual accidental number of casual-math bytes that Valve actually is limiting to. We thought we remembered seeing in their code that it was 512 * 1024 that they defined their limiter as, but nonetheless that was only in a header file and so the internals might be defined differently.
    • Thanks to NRSirLimbo and CRZgatecrusher for reporting.
  • Fragmented error messages now give more informative error messages when something is off.
    • It's now vastly more common for savegames to be over the limit, since we now have all the pre-caching of PKIDs. One small 275kb savegame changes to 527kb in the new version.
    • Good thing we spent so much time on data efficiency earlier this year, because we really require an abundance of extra data to make sure PKIDs come out nicely between the client and the host.
  • Completely re-wrote our custom packet fragmentation-and-reassembly code. It's more efficient on the client now in general, and works properly.
    • We've tested this with a maximum allowance of 50kb so that it fragments a variety of messages rather than just the initial savegame. It was all working well, now, so we've gone back to 500kb.
    • It turns out that, previously, we had an accidental game of Russian Roulette going. Depending on what bit the last of the fragment header ended on in its final byte, it might automatically advance to the next byte on its own. That gave it a 1 in 8 chance of dying on a fragment by skipping one random byte of data. That's no longer possible, but took us forever to track down.
  • ArcenSerializationTester, which was used as a single static-style class, has been removed.
    • Because of its static-class nature, it was not threadsafe, and we could not guarantee that we were not having mixed serializations or deserializations in one batch.
    • As part of this, we have replaced it with a new ArcenSerializationLogger class, which lives on actual serialization and deserialization buffers and thus can't be confused across threads.
      • As part of THAT, we are also now making it always write directly to disk, rather than buffering in memory sometimes. So the settings option "Write Savegame Serialization Logs In Realtime" has been removed, as it is now always true.
    • It is worth noting that this method of logging is somewhat less performant, and definitely wastes some RAM, but that's not of relevance to our purposes. If you have this logging turned on, you're already in a debug mode that is going to have performance that suffers by its very nature. What we prize most in that situation is accuracy.
    • This removes any doubt of any logs getting scrambled by simultaneous writes, or by overlapping requests to log, or things of that nature.
      • As a side effect, if you enable several kinds of overlapping debugging at once, it is possible to get an exception now, but that's better than before where it would just scramble your log happily.
  • Added a new setting to the network section: Log All Decoded Network Data To Disk
    • Will massively slow the game down, but dumps ALL messages as they are encored or decoded to the disk in files inside the PlayerData/NetworkSentDecodedData and PlayerData/NetworkReceivedDecodedData folders. This covers absolutely all data, and includes message headers that other forms of decoded-data logging do not. With this logging enabled on both the client and host, you can compare the output and see what serialization problems are happening, if there are any.
    • This is a last resort sort of debug option! Since ALL data is being actively decoded as it is written, it is far larger (and in plain text) than the actual data being sent across the network. A typical ratio might be 40MB of decoded data for 500kb of actual network traffic. You can have a few GB of data on your disk after just part of a minute of letting the game run in this fashion.
    • Warning: do not use with 'Log All Decoded Network Sync Data To Disk' or any of its sub-options also turned on, or you'll get errors.
  • The game now sends a unique 64bit messageID with every message from the sender, in sequential order of send, so that the sender and receiver are able to compare notes.
    • Full support for understanding the serialization of message headers is also now in place.
  • The game is now able to do some temporary buffering of serialization data to write to disk, prior to knowing what the name of the file should be, and then come in later after it has done a bit of deserialization and knows what to name its new message.
  • These new abilities combine to give some really rock-solid and overkill-style logging abilities that let us find bugs that otherwise escape us in the networking code.
  • After about two days of wanting to tear his eyeballs out trying to find an incomprehensible error, Chris found the single-line typo that he was missing.
    • The PKID syncs work fine on clients now when it comes to things like building structures directly, but for most other purposes there are just as many catastrophic mismatches as ever. Sigh. This is going to take some doing.

Version 2.637 Threatfleet Conversion, Chat, And Clickable Planets

(Released November 21st, 2020)

  • The game now tracks a new BecameThreatfleetAtGameSecond on each entity. When it is detected than an AI Sentinels ship is in Threat status (meaning it would show up as Threatfleet), it now logs the current game second so that it remembers how long it has been threat.
  • Added a new seconds_threat_exists_as_threat_before_joining_hunter_fleet on AI difficulty, which is currently set to 2x seconds_threat_waits_before_joining_hunter_fleet for all AI difficulties.
    • This sets a new and absolute timer on how long threat can be threatfleet for the AI Sentinels before getting transfer orders to the Hunter Fleet.
    • Previously, based on the other timer, if the AI Sentinels threatfleet is engaged in whatever activities, even if that activity is indecision, then it would never switch to the hunter side.
    • This makes it impossible for ultra-long-term threatfleet to remain in the galaxy, unless it is pointed at a non-human faction, or it is of a specific type that can't convert (usurper, overlord phase 2, drones, etc).
    • Overall in some edge case savegames, this makes it so that suddenly a bunch of idle threatfleet that was too stupid to figure out your particular empire now gets converted to the far-smarter hunter faction and joins teams dismantling you.
    • Thanks to TechSY730, Metrekec, ArnaudB, and Crabby for reporting.
  • Previously, it was up to the host and the clients individually to tell when the game was won or lost.
    • Sometimes there is a tiny bit of a disconnect between an event happening on the client and the host, however, and the client has a part of a second where it might think that you've won. We're being vague here to avoid spoilers, but it's a pretty common result that would happen at the end of each game.
    • At any rate, now the multiplayer host is exclusively in charge of saying when the game has been won or lost, since it never has any missing data even for a part of a second.
    • Thanks to Daniexpert for reporting.
  • Made a number of changes to the in-game chat textbox to prevent it from capturing your input even after it was closed, thus leading to mysterious sends of extra keys as well as your keybindings in general not working while the capture was in place.
    • Thanks to StarKelp, Puffin, Democracy, and Badger for reporting.
  • Also wound up re-plumbing the entire textbox input pipeline, because there were a number of cases of strange and annoying lag that could happen with them. So far all the ones we've tested are working great now and are more responsive. But please do let us know if there's any that are funky for you.
    • This could in some cases lead to race-condition-like behaviors, and repeat sends of messages.
    • Thanks to Sigma7 for reporting.
  • Fixed issues where pressing the escape key while in a chat textbox would send the chat rather than erasing it. This is because of our use of OnEnterOrReturnPressed(), which apparently also fires on escape being pressed. So now we have left notes in the code to that effect, and use a different method of detecting that enter is pressed to send chats.
    • Thanks to Sigma7 for reporting.
  • Should finally have fixed the super annoying bug where sometimes a planet on the galaxy map is un-clickable. We did this by making sure that the collider box for the planets is now way taller than anything else, and so things like the links between planets can't accidentally override them.
    • On the off chance that somehow the collider was actually being turned off for the planet icon, we actually are now always making sure that is on every frame, too.
    • If you were seeing some sort of other tooltip for something but unable to click the planet, and you see the problem again, please let us know what the tooltip is for. If you were seeing no tooltip at all, then that was probably the collider being disabled in some fashion. We do turn off the colliders for icons that are supposed to be off, but that should never affect planets. If it was affecting a planet icon previously, that should no longer affect a planet icon.
    • Thanks to Badger, TechSY730, GreatYng, CRCGamer, RedPine, denko, crawlers, Isiel, Cyborg, Asteroid, Kizor, Strategic Sage, and probably others for reporting.

Version 2.636 Text Hotfixes

(Released November 21st, 2020)

  • Shots now visually scale up at 6x the rate they previously did when you are zooming way out from a battle. This should keep them visible in farther-off battles, while not being so large when closer in.
    • They also now only start scaling up after a distance from the camera of 150, rather than 50, and their scale factor subtracts off the original 150 so that there is not a sudden jump in size when you cross that distance threshold.
    • Thanks to Badger for suggesting that these be scaled up better.
  • Fixed a bug in the prior build with how integers and chars were being written using the revised ArcenDoubleCharacterBuffer. It essentially either made numbers stay stale, or be outright invisible, in a wide variety of situations. Other times they looked just fine, but it was dependent on exactly how the calling code worked. From what we can tell, all instances of this are now fixed.
    • Thanks to Wuffell, ArnaudB, Daniexpert, TechSY730, Smaug, and Crabby for reporting.
  • Fixed one other issue with the revised ArcenDoubleCharacterBuffer, where if the next string from the buffer was SUPPOSED to be blank, it would just return its most recent string instead. So messages that were popping up various places but then should disappear when no longer relevant could not do so. They could be replaced by a different message, but could not actually just fade to nothing.
    • Thanks to Wuffell, ArnaudB, Daniexpert, TechSY730, Smaug, and Crabby for reporting.
  • If an exception happens in FromServerToClient_PeriodicPlanetFactionSyncDataThatJustOverrides, we should now get far more useful error messages now.
    • In this method and in a variety of other network sync methods, it now also checks to see if the galaxy is null, and returns early if that is true. This basically prevents errors from stray network syncs that are trying to be processed after the game is being disconnected.
    • Thanks to Daniexpert for reporting.

Version 2.635 AOE Visibility

(Released November 20th, 2020)

  • Some improvements for frigate roll colouring in games created on this patch
    • Thanks to Daniexpert for suggesting
  • Fix a bug where Discoverable factions weren't appearing in the Edit Factions screen
  • Some minor UI improvements to the Active Metal Flows screen and the Brownout Notification
  • The descriptions for the AI Reserves unique units now mention they are used to combat player Deepstrikes
  • Fixed a couple of exceptions that could happen if you were viewing the tooltip for an ship or structure right as you exited the game. There were probably a few other cases that could also cause this.
    • Thanks to Corpserule for reporting.
  • Majorly reworked how the "time do die now" code paths work for ships and units in general, so that we can more accurately tell them when they should explode or when they should not explode.
    • This solves the problems of ships exploding when they are removing one to add itself to a stack, as well as the problem of ships on MP clients exploding as they move to their proper position after a sync error (if the PKID itself was off).
    • It is likely that there may be some bugs resulting from this, but fingers crossed nothing too severe after we fix the initial raft of those issues.
  • The settings for screen edge panning have been moved higher in their respective camera controls sections, and have been renamed slightly to make it clear that it's only for the single camera type, not both cameras.
  • Fixed an issue (that was probably not new) where when you had the camera low enough that gimbal icons for ships were not showing, those gimbal icons would still show their explosion animation when the ships under them died. Now you just properly see the explosion animation of the ship itself.
  • Fixed some minor bugs that may or may not have been present previously with srapping units not always showing them exploding as they do.
  • The game will now complain if it can't find various materials and such that are used for things like under construction status, etc. At the moment, nothing complains.
  • Fixed a very small parser error that was causing AOE effects to not show up at all, ever. This was introduced a bit ago when we improved the xml parser for modders.
  • When Autobombs blow up, they now have a flak-style effect that appears around them.
    • Same for all of the minefields.
  • Added a new xml flag, is_okay_with_null_aoe_effect_for_aoe_attack, which is used for the ExplosiveInvisible shot type, aka for Crusher turrets and weapons.
    • These are meant to be invisible AOE damage that crushes stuff near them, and so we don't want the (new) "usual" error of "hey there's a missing AOE visual effect when you are doing an AOE attack" to happen.
    • Actually, we wound up suppressing the error, because more things were hitting it than expected and it's not worth it.
  • The flak effects now appear again properly, we can now verify. This being with grenade launchers most notably. They're on the small side, but that's somewhat by design so they are not overwhelming the battlefield.
    • The tesla effects are also back, but again more thin and more reasonably sized. We may need to look into scale on these some in the future at some point.
    • For the flak effects, they do seem to be strangely crunched down on themselves compared to what we were seeing in our videos, but we'll have to investigate that at some point in the future.
    • Thanks to TechSY730, Badger, Isiel, Puffin, and Corpserule for reporting.
  • Fixed a variety of sync exceptions for multiplayer that would cause duplication of various things on ships:
    • The ships granted if they are hackable, etc.
    • The amount of damage dealt to ships of various death-types.
    • Various data relating to AI reinforcement points (guard posts, etc). This was not endlessly duplicating, but was causing some funkiness.
    • The incoming shots.
    • Various things with forcefields protecting a ship.
    • Various bits with where an AI ship thinks it is guarding something.
    • Any techs that were granted by hacking a ship.
    • This should handle all of the cases that people have reported, plus some things that were not visible to people directly. Please do let us know if you see more of this!
    • Thanks to Puffin, Arides, Daniexpert, jrad, SilverLight, and others for reporting.

More Performance Improvements

  • A new version of our internal ArcenCharacterBuffer has been added, which now wrappers a StringBuilder and uses many of the benefits that has been added to that class over the years. The performance of adds and updates should be a couple of orders of magnitude better than what we've had up until now, making large interface elements more responsive.
    • Though in fairness, we don't use too many ArcenCharacterBuffers, it's mostly another class which will also be updated.
    • Thanks to NR SirLimbo for benchmarking all this and figuring out where there were some major slowdowns with this.
  • A much more substantial performance boost has been achieved by replacing ArcenDoubleCharacterBuffer's internals with a new approach that uses a mix of StringBuilder and our own form of logging of "WrittenValues."
    • This makes really long text displays that are continually updated much faster (before they would take you down by 10-20 fps on a fast machine just for viewing them), and that includes really large tooltips.
    • This also seems to make the game load a bit faster, and also in general makes the UI generate faster all over the place. It seems to be around an 8-10 fps bump on a very fast dev machine. Slower CPUs should get more benefit.
    • On the escape menu, under the memory pooling section, there is now a "Texts saved" versus "texts new." In under 1 minute of just sitting there and moving around a bit, we wind up with values of around 500 new, and 500,000 saved. That's.. substantial.
    • Based on testing by NR SirLimbo, all use cases of this are faster, but in general the average improvement in speed is using 98% less processing power to draw text than we used to (and the processing power was nontrivial). The load time of the game itself has also improved by at least 2 seconds for most of the faster machines, and maybe more for slower ones.
    • Thanks to NR SirLimbo for sparking this line of inquiry.

Visual Improvements

  • On February 4th, 2020, we had an accidental regression that caused the "ship placement" material, and the under-construction and under-construction-stalled materials to all lose their shaders and some of their textures. So when we tried to draw units with these visual effects on them in the game, they would just be invisible (icon aside).
    • This was during a larger purge of some unused shaders and textures, and had this as an unfortunate casualty. We've now restored those items, and things from those areas should "just work" again in the next version.
    • Thanks to a lot of folks for pointing out that this had gone missing, including RabidSanity and Mckloshiv.
  • Arcen "Death Chain Effects" have long been used for things like flak hits and tesla attacks. However, they were entirely scripted and robotic, before. The only difference between one playback and the next was the rotation of the entire effect.
    • We've now added a tremendous amount of randomization in how these play out, including to the position and scale of their sub-components, how fast they move through their animation per explosive, and things of that nature.
    • The end result is that we're now able to make a single death chain effect look a bit different every time it plays, for almost no extra processing power, and so the entire battlefield will look way more alive and unique when these things are happening in large numbers.
  • The shader that we use for our "death effects" for AOE damage, most notably flak explosions and lightning explosions, has been rewritten to use a custom lighting path rather than using surface lighting.
    • When we redid our lighting pipeline earlier this year, it unintentionally made all of our death effects of this sort look TERRIBLE.
      • Essentially, they were showing up for a bit before visually appearing, in kind of a ghostly form, and they were also then showing up a lot more white than they should have been. This was them interacting with the HDRI reflection cubemaps that are now in the scene.
    • The new version of the shader looks better than the old one ever did even pre-lighting-update, and no longer has any of the above issues.
  • The flak explosions have been completely reworked to the point that they are almost unrecognizable.
    • All we've done is adjust the shaders and the randomization of the chain effect, but this went from an effect that made us cringe to one that we'd love to see in massive quantiles taking out our foes.
  • Plasma AOE explosions are far simpler than the flak explosions, since they only have one main body of the explosion, but that's no reason for them not to look cool.
    • We've introduced some new variance into this effect, and in general made it look better, so that now it has a distinct "rush and pop and slowly fade into wisps" feel to it. With the speed and details being randomized, this definitely brings it to the next level.
  • The tesla AOE effects, both the "guardian" level and the "regular" ones, both look vastly better now and way more like lightning.
  • A new "Victory" fire text has been created, for purposes of being used like the "you have lost" text that can happen when you lose.
  • When you lose the game, it once again shows the "You have lost, humanity has perished" message in big burning letters.
    • That lasts for 7 seconds, and then immediately after that you go to the loss screen. This makes it so that the transition to the loss screen is not so abrupt. Plus people liked the text.
  • When you win the game, it now says "VICTORY" in giant fiery letters, rather like the "You have lost" for when you lose.
    • This one waits only 4 seconds, and then transitions to the normal victory screen. This again makes the transition a bit less abrupt.

Version 2.634 Multiplayer Solidification

(Released November 18th, 2020)

  • A new planet naming scheme, Oddball, has been added to the game:
    • Aims to give a sense of history. One heavy with warfare and bored scout captains. Created by Kizor. Thanks to Loweko, R. Jean Mathieu, Vornicus, McMartin, Reiver, Quasispace, Derakon, Kyoshyu, and the anonymous.
  • Several updates to journal entries for extra lore details.
    • Thanks to Puffin for writing these!
  • The sabotage hack, when there are multiple viable targets on one planet, now includes the text:
    • Whichever of these is closest to the hacking unit will be the one hacked, so park your hacker right near the target you intend.
    • Thanks to Daniexpert for suggesting.

MP Performance Boost

  • Previously we had a rate limiter in place for only checking if background work threads were done if it had been at least 50ms of time since the last check. This is not a super expensive check in the grand scheme, and we'd rather react to these being done as fast as possible in order to avoid small timing discrepancies causing larger delays in sim cycles kicking off or moving to the next frame. So for now we've just entirely taken the limiter off, which should have only positive effects from what we can tell. The limiter was originally put in place out of an abundance of caution, when we were not sure how slow it was to call ThreadState on threads.
    • Update: apparently this actually majorly cuts down on multiplayer lag and small jitters. This tiny bits of timing really add up when you have to wait on the other computers in particular. What a lucky find! This would have taken us ages to figure out if we'd actually been looking for it, but instead we found it while fixing the flickery dropdowns.

Bugfixes

  • When a client is getting sync correction data from a host about entities, there were several cases where it could detect some invalid data, and it would then throw a visible error... but it would also just keep trying to process this now-known-bad data, and thus run into further problems.
    • Now it actually stops processing all of the sync fix data from that batch, and logs warnings into the log silently. This way we can go back and find them if need be, and certainly if your log is filling up with these that would be bad. But these will not affect the running of the game (just how rapidly sync correction happens for this specific batch of units), so they are starting their lines with "Not fatal - just a warning" to be extra clear on that.
    • There were various errors that would show up after these, previously, that were simply a matter of "hey, bad data was sent, but we tried to parse it anyway, and of course that went about as well as you could expect."
    • Thanks to Daniexpert for reporting.
  • On the host in multiplayer, it now does a last-minute check to see if it's about to send the sort of mangled data for a ship that would cause the client to have to do the sort of toss-out of the entire batch that the clients were doing in the most recent fix. If it finds that it is, then it should now just skip that unit and leave it for a future sync pass.
    • At this stage, we can assume that maybe the unit JUST died on the host, and so within 2-4 seconds the client and the host should get synced up properly regarding it. But in an abundance of caution, there's always the chance that actually this unit is still alive, but just was changing planets or something, so let's not tell the client to delete it just yet.
    • This sort of scenario should be an edge case, but the idea here is that we make it less likely than the client would have to throw out an entire batch of divergence data, and instead just the one problematic ship will get re-evaluated next cycle and we don't even need any bad log messages about it, etc.
    • Thanks to Daniexpert for reporting.
  • Fixed a minor bug in the macrophage, which nobody has ever even hit, where if the king was not found it could wind up having some pathing errors unless you had debug flags on.
  • Fixed a really rare bug with the Zenith Trader where, two seconds into the game, it was theoretically possible for multiplayer clients to get a nullref exception when the trader was trying to spawn. No one actually hit this yet.
  • In multiplayer, on the client, if findHumanKing() cannot find a result, it no longer throws any form of error (they were silent errors in the log, before).
    • Essentially, sync data must be slightly off, and that is fine and something that we should just ignore. The host will take care of giving proper orders to ships, and the client will find out about that soon enough and have all its data corrected anyhow.
    • Same logic on findAIKing().
    • Thanks to Daniexpert for reporting.
  • Some of the data for how things that use internal build points (for things like viral shredders in particular) was being set up on the fleet memberships, and cached there as well.
    • Now it sets it up once only, at game start, in ComputeBalanceStats_OneTimeOnly(). This is more efficient, and also gives us errors on load if our xml is wrong, and also fixes a compatibility problem.
      • There was previously a bug in multiplayer where viral shredders would lead to endless exceptions on the client because it was missing the extra cached data on the fleetmem, ouch.
    • As an additional bonus, we are no longer storing this data on fleet memberships in general, which means we no longer have to serialize and deserialize that.
      • The fact that we WERE serializing it was making the question of the exceptions in multiplayer even more confusing, but at any rate now some sync data and all savegames will be a tiny bit smaller.
    • Thanks to Daniexpert for reporting.
  • MP clients in general will no longer throw any exceptions related to things with internal build points on their fleetmems. If something is off, it will just let the host take care of that and inform them within a few seconds.
    • However, the error will still happen on the host if something is messed up, but it will be more informative and not block the rest of the execution of this fleetmem per-second cycle.
    • And based on the fix above, this should now just work properly in general on clients, but we prefer an abundance of caution.
    • Thanks to Daniexpert for reporting.
  • Previously, in multiplayer if there was a reroll hack that was done, it would give a different result on the client and the host.
    • That has been corrected by making it so that on the host it now calls FlagAsNeedingForcedFullSyncToClientsJustInCaseIfInMultiplayerAndWeAreHost() on completion of the hack, which is the general standard that we should be aiming for with this sort of information in the future.
    • This applies to the ARS, FRS, TV, and GCA.
    • There is a slightly-more-automated fix for this that doesn't require individual mod-author (or faction-designer or unit-designer) input, but this is still a good idea to do.
    • Thanks to a variety of folks for reporting this, including Arides, Daniexpert, and others.
  • Apparently it is possible to get an exception when hovering over a tech tooltip in multiplayer. This has not yet been fixed, but now when it happens it will be sure not to be destructive to the rest of the game, and it will give a far more detailed error message. Right now we really have no idea what the actual error is, but this will at least contain it and let us fix it after we have a new report in the next release.
    • Thanks to Daniexpert for reporting.
  • TextEmbededSprites now have a few new capabilities:
    • The scale float xml parameter allows you to set the scale of a sprite relative to what it would normally be (default is 1.0).
    • use_geometry_queue as an xml parameter allows for you to make a for-the-galaxy-map-by-planets-text version of sprites.
      • If this is set to true, then those versions of the galaxy map sprites will be vastly more efficient and will dynamically batch as we set up last build.
      • If this is set to false, then this is for use anywhere else in the GUI, including the header and tooltips and whatnot. If this is set to true and you try to use it in the interface elsewhere, it will be invisible, as we discovered yesterday.
  • Using the above, strength icon is now properly batched on the galaxy map (as with last build) but all of the other sprites being drawn in the GUI now actually draw visibly again (unlike last build).
    • Also, while we were at it, we adjusted the scale of the strength icon to be 0.9, since it was a little bit on the large size in most text.
    • Thanks to Badger, Daniexpert, TechSY730, and Crabby for reporting the invisible icons in the GUI.

MP Sync Improvements

  • During multiplayer, if there is a hack happening, then every second where something is changing, the host does an extra forced sync of the hacker and the hack target (if there is a hack target) to all clients, thus keeping them all in the loop.
    • This is central and automated, and should probably actually catch cases like "something was different after a hack between the client and the host" even if the end programmer/modder/etc doesn't account for it fully. This is just a handy new feature in general!
  • When units are claimed, or when they complete construction for the first time, there is now an automatic forced full sync of that unit from the host to the clients.
    • This gets rid of a lot of potential desyncs that otherwise could linger for a bit.
  • The ability to set the importance of intel tab entries is now shared among players in multiplayer.
    • This was previously set up to only be local, kind of by accident.
    • This has some code to keep it nice and responsive as if it was still just a local change, but if you click really rapidly on the same intel entry and cycle it through, you may see some slight funkiness to that. Should not be a big deal, but we'll see.
    • Thanks to Daniexpert for reporting.
  • FlagAsNeedingForcedFullSyncToClientsJustInCaseIfInMultiplayerAndWeAreHost() has been renamed to FlagForForcedFullSyncToClients_FromHost().
    • Added a new FlagForRequestedForcedFullSyncToAllClients_FromAnyClient(), which lets clients request updates on an entity rather than the host having to tell them.
    • Both of these calls remain utterly impact-free when we're talking about calling them repeatedly, or calling them during single-player. They intelligently weed out extra requests, and don't do any substantial processing directly.
    • The FlagForRequestedForcedFullSyncToAllClients_FromAnyClient() method in particular throttles itself so that a fresh flag can only be set on a given entity on 1 second intervals. So if the client is repeatedly asking the host for updates on an entity, that's just fine, but it will only get results on that given entity once per second. Other entities may be requested inside that timespan.
    • The upshot of this is that, whenever you look at a ship or structure as a client, by hovering over them to see the tooltip, you immediately get a refreshed copy from the host (within 100ms or so at the most, probably less, so too fast for you to notice), and then every 1 second after that you get further updated info.
      • There's a lot of extra data that is stored normally only on the host. That gets sent to you as a client when you first connect, but it's mostly stuff happening on background threads and affects faction decision-making. Some of the DLC2 factions gather various resources that you can see in the tooltips, for instance.
      • Previously, before this addition, clients would just have incomplete tooltips. Now their tooltips are updated with host data as-needed, and already the behavior of those sorts of ships would be updated by the host (so if you're not hovering over something for a tooltip, it will still act correctly; and you don't need the extra data in the tooltip unless you were to hover over it).
    • The other side effect of this is that if you feel like maybe there's a sync error with some ship or structure, and you go to hover over it to check that out and see for sure... it's going to instantly fix itself. So do be aware of that, though it's more or less a good thing.

UI Improvements And Fixes

  • The concept of "Update Cycles" in the ArcenUI framework has been removed.
    • Instead we are basing things on ArcenTime, which was developed after the initial design of the ArcenUI.
    • This in turn lets us have reactions which are framerate-independent, which is thus more consistent across machines.
  • Using the above shift, plus also an extension to allow dropdowns to properly handle tooltips even on their "off frames," we have fixed the flickering dropdown tooltips that were introduced in the last update of the game.
    • Thanks to Daniexpert for reporting.
  • Various lobby dropdowns have been improved as follows:
    • The tooltips for map type planet count entries still retain the header text of what you are doing. Also, colors for the selected vs potential items has been added.
    • The tooltips for the planet naming types are a bit more clear in general, and it now shows the name in a line above the description for extra clarity. Also, colors for the selected vs potential items has been added.
    • The tooltips for the map types explain themselves a bit better, include the name of the map type, and have the new colorization.
    • Tooltips for the map linking flavor and planet layout and such now match the others in function and colorization, including showing the details of currently-selected item when you hover over the closed dropdown for the first time.
      • Also discovered a special discrepancy in how these were being handled that was causing these to still flicker like crazy even after we fixed dropdowns in general.
        • Also found and fixed this on all settings on the personal settings window, although all other windows seemed to be okay.
  • Put in a fix that will prevent dropdowns in general from using the code combination that leads to flicker:
    • Essentially, HandleOverallMouseover() has been removed, and you should now use HandleMouseover() for that, and continue to use HandleItemMouseover() for items.
    • We are able to control how this flows properly and remove the flicker, whereas before if someone used HandleMouseover() by mistake -- when they were supposed to use HandleOverallMouseover() -- then they would get a flicker.

Version 2.633 Roaring Performance

(Released November 17th, 2020)

  • Civilian Industries Update
    • Put in some defensive code to prevent potential pathfinding lock ups when multiple civilian factions are in play.
  • When hovering a Flagship, the 'max possible strength' value in the tooltip is now colour-coded to let you know what percentage of that strength currently exists. So if your fleet has taken heavy losses, the Strength colour will be darker. If you are at full strength it is brighter. This matches the behaviour of the tooltips for Factories.

Performance Improvements

  • On the main menu scene, improved the culling mask on the scene-view camera to greatly improve efficiency of that scene.
    • It looks like the main menu may have been accidentally drawing 1.8 million tris rather than 800k tris because of this being set wrong.
  • The reflection probe on the main menu scene has also been updated to have an appropriate culling mask, for the same reason.
    • The reflection probe updates, which are quite heavy and frequent, should also thus be correspondingly faster and draw so many fewer triangles as well.
  • Poly few has been employed on the main menu scene to combine all of those meshes of the hangar into just a single mesh with 16 submeshes for the various materials.
    • This cuts the number of draw calls on the main menu down from about 3000 to about 250. The visual end result is identical. The performance gain is potentially massive, but varies heavily by hardware.
  • We have historically had static and dynamic batching disabled for this game, because we use GPU instancing instead (which is far more efficient and direct).
    • However, when we made the new main menu, we had implemented things such that this type of batching would be useful there, so we turned it on.
    • We have now changed things around again to remove that, and so once again removed those from being on in the application as a whole.
    • It's quite possible that these were dragging down performance on some machines in general, as the game may have been spending some CPU cycles fruitlessly looking for things to dynamically batch during the main game itself.
    • It's irrelevant to the end result of how things look, but there's no chance of that popping in and impacting performance negatively anymore, which is good. If it wasn't a performance impact, then no worries there, either.
  • Using Blender, we've manually removed some off-screen sections of the main menu meshes. This has overall reduced our polygon count in the game on the main menu by another 300k or so triangles.
    • This sort of hand-optimization is something that we had been saving until it was clear this is where the bottleneck was, and after it was clear that the new main menu was a winner (and that we had time aside for it).
  • With these changes, on Chris's main two computers he sees:
    • On the main menu on his main dev machine (GTX 1070 and a few year old i7 laptop) a jump from about 55-60 fps to instead being about 100fps.
    • On the main menu on his MacBook Pro from late 2013 which has an i7 but does not meet the minimum system requirements in general, it jumps from 26fps to... 26 fps. So there's a different limiting factor other than polygon count or draw calls on this ancient of hardware.
    • Most likely, any machines that are actually meeting the minimum system requirements, or vaguely approaching the recommended, environment, should see a substantial performance bump on the main menu. And for everyone, the disabling of the static and dynamic batching may improve performance beyond the main menu.
  • In our main menu scene, the way that the reflection probe is update has been changed fairly substantially.
    • Previously it was every-frame every-face if you had at least 30fps, and every-frame individual-face if you had at least 15fps, and below that would not update over time.
    • The individual-face updates were really jarring, however, and not something that is a good idea for any sort of smooth feeling.
    • Now only if you have at least 50 fps will it do every-frame every-face updates, and below that it will just not update over time, instead only having the reflection from the initial onawake event.
    • On Chris's main machine this makes no difference since it runs at 100fps now, but on the under-min-specs OSX machine this brings performance up to 31fps from the previous 26fps.
  • On the main menu, a number of lights were set to affect more than just the Scenes layer. This probably did not affect performance, but we are correcting that anyhow.
  • On the main menu, we had one extra spot light that was drawn in a not-important weighting, and that was very dramatic and looked good in general BEFORE we started having ships with lights on them moving around.
    • Since having ships moving around, that spot light would disable itself as the spotlights overtook it, then re-enable itself, and the transitions were jarring. It did not seem to affect performance much on the high-end or ultra-low-end machines, but in the middle-tier it might, also
    • This spot light is simply removed, as it was not needed for the new scene composition.
    • We experimented with turning off the point lights used on the ships, or even with turning off the reflection probe from being on at all, but the former gave 2fps on the super-old mac (from 31 to 33 fps), and the latter gave no boost at all.
    • Whatever is holding back the ancient below-specs mac is really not the sort of thing that is holding back the rest of the potential computing audience. And this is one excellent reason why we have system requirements in the first place. Not that 30fps is a cardinal sin; the original AI War was hard-locked to 20fps most of the time.
  • Added a new Performance tab option: Unrestricte UI Update Speeds
    • Normally, most UI windows only update their contents every 50-100 milliseconds. If your framerate is much higher than this, however, you may prefer that the UI update at whatever your actual framerate is.
    • This will likely reduce your framerate, potentially substantially, but it leads to the ultimate in responsiveness. Prior to version 2.633, and since sometime in the game's alpha, the UIs were all running on unrestribted update speeds.
    • We are not noticing any substantial benefit from this on our powerful machines, but on lower-end and middle-tier machines this may make more of a difference.
    • At the moment, things seem to perform equally well either way, but it's nice to put a lesser load on things where we can. Since this does not seem to make a visual/feel difference that we can detect at the moment, this seems fine to have with a differing default from the past.
    • Thanks to Daniexpert for inspiring this change.
  • In the ArcenUI_Element class, we have a SetActiveIfNeeded() method that long ago had some gating that was based on a cached wasLastActive in the class.
    • This was working poorly, back in alpha or beta of the game, because of how unity handles commands to enable objects that are disabled in the heirarchy, and things like that.
    • The game has now been updated to do a check against the activeInHierarchy property of the gameobject, which will always give the real result. This should not result in bugs, and should in theory result in some slightly better performance in certain cases where large numbers of ui elements are turning on or off frequently.
    • We don't really see much of a difference based on this, but in general this was something we noticed that was an optimization we had wanted a long time ago, and being able to have a tamer version of that back in here now is nice.
    • Thanks to Daniexpert for inspiring this change.
  • Over the last few months, as we've added functionality, the performance of the galaxy map has dropped notably.
    • In combination with a much-more-recent performance drop related to how we draw sprites-in-text and how that affects the galaxy map only, full galaxy maps were down in the 25fps range and really choppy to move around, today.
    • We've now restructured a lot of things to update in a time-sliced fashion, and the performance is now in the range of 90fps when zoomed all the way in, and 60fps when zoomed all the way out on a full map.
    • There are still some performance improvements we need to pursue related to sprites-in-text in this specific instance, but those will be in the next build.
      • We did experiment around with trying some things like adjusting the sprite-in-text shader to allow for GPU instancing, but that went absolutely bonkers in a way that we don't care to untangle. There's a better approach that we'll implement soon.
    • Thanks to Daniexpert for reporting.
  • A whole messload of the new background images and other accents that are used in the new UI have been made vastly more efficient.
    • This may actually vary by OS just how much more efficient they are, but in essence these are all now able to be stored in DXT1 format, and all of the ones where relevant now have mipmaps for more efficient drawing at smaller resolutions.
    • The amount of VRAM that this should save, and the extra load removed from the GPU pipeline, should be substantial.
    • Thanks to Daniexpert for getting us to look into this.
  • Discarded these changes: Rather than using raw "TextMeshPro" text renderers for the text that is shown all around the galaxy map, we are now using individual Unity GUI Canvases with embedded TextMeshProUGUI objects.
    • Visually this looks identical, but now we are able to take advantage of the compositing stages that unity canvases go through, and thus we can have things like strength icons be embedded directly in these canvases without them causing extra draw calls.
    • At the moment we have one canvas per planet, with three text sections inside of that. This is less efficient per update of text, but more efficient for drawing text, which is the more common operation.
    • None of these respond to mouse raycasts at all, so on the off chance that the occasional (could not click a planet on the galaxy map) was relating to these, that no longer is possible.
  • Replacement changes for the above: In the end we went back to raw TextMeshPro text renderers, as their performance was superior to anything we tried with an abundance of canvases.
    • We did wind up also making it so that the shaders for TextMesh Pro sprites now use the Geometry queue instead of the Transparent Queue, which improves performance on rendering and also allows for batching.
    • And for the various ship icons in both the main view and the galaxy view, those also now use the Geometry queue. Those should generally get picked up by GPU instancing, but in the event they do not they will now get picked up by dynamic batching instead.
    • We actually have re-enabled dynamic batching for the game, but still left static batching off, and this seems to give the optimal performance when that's paired with these shader changes for the sprites.
    • Sprites used to always do perfect instancing, but now the sort order sometimes messes that up since there are multiple materials and it feels like it needs to handle them in proper order (really, z buffer ought to be sufficient and overdraw is probably preferred, but anyhow). The queue change makes these more likely to instance, and in the event they don't instance it makes them batch, thus leaning on the z buffer as noted.
    • The end performance boost on the top machine we have is now getting us back into the 90s fps on the galaxy map, up from the high 20s in the prior build, and still in the 90s on the main planet view. And both feel smooth rather than jittery, now, which is good.
    • Thanks to Daniexpert for reporting the performance loss observed lately.
  • On the galaxy map, we are now properly buffering text such that we don't put back in the same value into a field that just had that value.
    • This was causing some needless thrashing and re-parsing of rich text tags.

Version 2.632 Multiplayer Sharing

(Released November 16th, 2020)

  • Fix an XML parsing error related to the Human Marauders
    • Thanks to Crabby, zharmad and okonomichiyaki for reporting
  • Add a setting for 'Show Faction Ring Around Ship', which displays a circle around a ship of the colour of the faction.
    • This is intended to make it easier to follow how battles are going without icons on, since it looks really cool that way.
  • Add some Red text to the Delete Campaign popup to make it a bit harder to do it by mistake
    • Prompted by the woes of Pat on the forums
  • Mod updates: Fixed Tugboat Drones always slowing enemies by 80%. Instead they now start at 20%, increased by 5% per mark beyond 1, ending up at 50%. Note that Tugboat Drones can still archive the maximum slow if their slow fields overlap.
    • Thanks to zeusalmighty428 for reporting.
  • Micro Mod Collection fix/balance:
    • The Energy Converter no longer produces negative energy and instead consumes the same amount of power. It was causing errors when a bad brownout could turn the energy generation of the player negative.
    • Doubled the metal cost of the Research Expedition.
      • From zeusalmighty428's balance feedback

Multiple Players Controlling A Single Faction In Multiplayer

  • In the lobby sidebar, you can now see on the client and the host if other people are in spectator mode, not just if you are personally.
    • This is quite helpful for knowing if the multiplayer lobby is truly ready to start.
  • Under human player entries in the factions tab in the lobby and the factions screen in the main game, you can now add and remove players from factions.
    • The tooltips make it pretty clear, but basically you can switch who is controlling what faction, or make someone just a spectator, or have two people share control of one faction, etc.
  • Fixed an issue where regenerating maps was causing faction assignment auto-allocation previously.
  • Two players are now confirmed as being able to share the same faction, and both can order around the ships of it and see everything as if it was just controlled by one of them.
    • What is not shared is the state of your GUI, such as what you are looking at or what you have selected, or what you are hovering-over, etc.
    • This is essentially the same as even really old RTS games like the original Age of Empires that would let you share a faction if you gave two players the same color.
    • However, with this you are able to still do text chat with the colors and the names of the individuals who are a part of the game, whether they have their own factions or no faction or share a faction. This feels pretty awesome!
  • Joining a game late as a spectator is confirmed to still be possible, but now that's the only time it warns you that you are a spectator.
    • If you join the game in spectator mode during the lobby, or the world is regenerated while you are in the lobby, it doesn't show the "hey you're a spectator, is this on purpose" message. That was really annoying when changing galaxy sections to have fewer factions or while someone was just intending to spectate.
  • New feature, after someone has joined a game late (or frankly, even if they have been there from the start):
    • You or they can unassign them from factions, and assign them to other factions or no faction.
    • This is great for having a game where you were playing solo, but now have some friends coming in as extra sets of hands.
    • But surprisingly, since this is so quick and so seamless of a way to pop over and see the perspective of another player, I can see this potentially being used as a "hey, look at my metal flows and such for a minute" type of view, too. You can do it while paused or unpaused, the game doesn't get interrupted while people change status or come and go in general, and overall this is just really smooth.

Version 2.631 Multiplayer Swaps And Performance

(Released November 13th, 2020)

  • Fixes to when GetIntValueForCustomFieldOrDefaultValue or GetValueForCustomFieldOrDefaultValue have empty strings in them, to where they will now return the default values properly.
    • Thanks to NR SirLimbo for identifying the problem and likely fix.
  • Kaizers Marauders fixes:
    • Fixed another exception in relation to missing settings. Tracing the issue back lead to finding out that Vanilla GetValueForCustomFieldOrDefaultValue() sometimes still does not return the actual default value but an empty string. OnS0_KaizerUpdating() now detects this and produces an informational popup before correcting it to "Never" which is the actual default value.
    • Debugging lead to the discover of a bug in the Budget Updating logic where (due to the same issue) they would every second set the starting budget of [nothing] without ever beginning to accumulate budget. They now start with 0 and begin accumulating.
      • Thanks to Isiel on Discord for reporting and delivering a save to reproduce these issues with.
  • Fixed an exception that could happen in RemoveInvalidatedOrdersAndReturnFirstValid_IncludingDecollision() somewhat at random on multiplayer clients, mainly as a race condition.
    • Thanks to crawlers and Driftwood for reporting.
  • For whatever exact reason, the Macrophage faction really doesn't work well if the client is also trying to calculate all the decisions for things in multiplayer. This is referring to the DoPerSecondLogic_Stage3Main_OnMainThreadAndPartOfSim() method in general, but the telium spawning logic in particular.
    • Since this was a constant source of errors, and since the desync repair code should catch things like this quickly in general, for now we're just not running this on the client at all anymore. This stops the errors, and any divergences should be quickly and easily picked up by the desync repair logic.
    • Thanks to crawlers and Driftwood for reporting.
  • Fixed potential exceptions that could happen in OnlyInMapgenOrInActuallyGettingRidOfEntities_ImmediatelyRemoveFromSim() in general during cross-threading, but most often on multiplayer clients.
    • Thanks to crawlers and Deadwood for reporting.
  • A variety of data that is only relevant in single-player or on MP hosts no longer shows up on MP clients in the escape menu sidebar.
  • Previously in MP, it was possible to get some errors like "Hey, we have generated drones from a ship of type CarrierGuardian that can never be properly deployed by the fleet it is not the centerpiece of, of type NonPlayerDrone" on the client in a spurious fashion.
    • These are simply not written right now, and the natural sync process fixes those already within a couple of seconds.

Swapping Fleet Lines Between Multiplayer Players

  • Created the ability for players to swap out ship lines between each others fleets in multiplayer.
    • For the sake of convenience, every player can slot in every other player's ships into their fleet, or grant their own ships to any other player's fleet.
      • In AIWC, we required players to actually gift ships or similar from themselves to someone else, but in this game you can outright take from others. You're all on the same side, so divide up tasks how you will.
    • The owner of the fleet is included in the row of the swapping target so it's easy to see who owns it.
    • For balance reasons and to prevent technical hiccups, any ships that are swapped between players in this fashion get destroyed and have to be rebuilt by the player on the other side.
      • This is fairly similar to how, when ship lines are swapped between fleets on different planets, the ships are scrapped and have to be rebuilt then, too.
    • It's worth noting that this sort of thing does allow for a lot of extreme focusing of tech lines in multiplayer, making MP even easier than it would have been before (you take all of the ships that benefit from tech X, give me all the ones that benefit from tech Y), but this was always a feature we were planning, regardless. Player flexibility and the ability to coordinate is more important.
      • We could implement punitive-style tech costs in MP, to make it so that it was more costly to use techs, but that would probably just encourage even more specialization.
      • In general, it's simply worth noting that a MP game is substantially easier than the equivalent game played solo. So either up the difficulty, or add more secondary foes to deal with, or enjoy the extra ease.
      • The original AI War had a much more limited set of factions at the start, and only could ever have two AIs, etc. So it was important for that game to scale the difficulty up as more players were added. But in this sequel, the amount of other factions, and their power, make it so that you can really tailor it to your own needs, instead.
    • Huge thanks to NR SirLimbo for implementing this! This was on our list to do, but to have a modder implement it for us in advance is a great time saver.

Multiplayer Performance Improvements

  • The multiplayer sync-repair of planets, with planet-factions included inside of them, was by far the largest amount of bandwidth being sent by the game during gameplay, and it has now been set up in a time-sliced fashion so as not to cause a bunch of lag on the client.
    • It's quite likely that, on some certain very heavy games on Steam, this was actually able to cause an exception where the amount of data being sent in one message was larger than what Steam allows.
    • At any rate, this was causing periodic lag on the client that was so severe in some games with larger counts of planets that it was making the entire game laggy.
    • We have not only started time-slicing the planets, but we actually split out the data for the planet factions themselves and also time slice THOSE now, too.
    • As a direct result, the performance of multiplayer games has skyrocketed when it's involving large number of planets and/or factions, but we're going to take this a bit further.
  • Previously, we had a system where ALL of the various types of network sync repair work shared one large time-slice.
    • This really only worked when we had fewer types of sync repair, and when they didn't also internally have lots of time-slicing happening.
    • As we have added more types of sync repair, and have started wanting to time-slice those, this would otherwise mean that the really core stuff -- namely ships/units -- could fall further and further behind, which is not good.
    • Therefore, we've moved both the "ship sync checks" and the "divergent ship fixes" out of the central time slice group, and they are handled every sim frame instead.
      • For ships, these were already time-sliced, and so those happen over the course of a couple of seconds. Probably closer to 2 seconds now, rather than 4, but it depends on the number of ships in the game.
      • For divergent ship fixes, those now don't wait on anything, and just get sent to clients asap after we realize that it is needed. This makes that far more reactive in a good way, and ultimately the data is small enough not to be concerning.
        • As we get to fewer PKID conflicts in the future, this will dwindle even further, but having it be nice and reactive is good.
  • Now that we don't have to share the time-slicing with the time-sensitive ship fixes, we can make some of the rest of the sync repair data happen on a more relaxed schedule.
    • This actually is a dramatic reduction in the amount of data transferred, and even more importantly is a dramatic reduction in the amount of CPU processing on clients required to handle this.
    • Planet Faction sync is by far the slowest stuff to sync, and has the most data, so we're time-slicing it over 20 frames now, which is about 2 seconds, rather than 4 frames like earlier in this build (before this build, it all happened in a single frame every two seconds or so).
    • Planet other-data sync is not exactly small, either, so it's being time-sliced over 8 frames now instead of 4 frames like earlier in this same build. Again, prior to this build this AND the planet-faction data was all in a single giant laggy frame every 2 seconds in large games.
    • The data on these things is just not all that visible or important in this sort of time schedule, so cutting it down in this fashion keeps things from drifting over long periods of time without impacting game performance like it previously was.
    • We may add in extra time-slicing in the future if it really becomes needed, but at this stage it is seeming to be a good balance between keeping things up to date quickly and not draining performance.
    • Thanks to crawlers and Deadwood for providing an MP savegame where basically the performance was stop-and-start laggy; in this new version, we can run it at full sim speed with no waiting on the client, which is really awesome!
  • Non-new ships on tier 3 planets now get synced FAR more slowly, and are counted as skip-syncs.
    • These catch up at a rate of roughly "one full sync cycle multiplied by 1/10th the number of planets, rounded up). In practice in one large savegame with 12k stacked ships and 93k ships total on 120 planets, this winds up being about a delay of 68 seconds at most for any given ship. If players moved onto a planet that is slightly stale on the clients, that planet would be immediately updated.
    • The main cases where we might have a problem here is with strength calculations being off on planets where there are large numbers of reinforcements suddenly dumped into new ships. The host would always be correct, but the client would have some slightly stale data in the galaxy map for up to 60 seconds, which would be annoying.
    • There are some ways we can adjust for this for specific ships as they are updated, though, and the next step is to add that. This whole process at the moment does wind up saving a ton more bandwidth and CPU processing, though, which is excellent.
  • Added two new methods to GameEntity_Squad for ships:
    • FlagAsNeedingForcedFullSyncToClientsJustInCaseIfInMultiplayerAndWeAreHost() causes a ship to immediately be fully synced from the host to any clients. It is unused on the client side.
      • This is a great way for mods in particular to, after having updated some sort of special mod-only data (like resources they are carrying) to cause a full ship sync.
      • This should not be done too frequently! But if you have a mod that is gathering resources, and periodically updating information that would not normally be caught by the sim thread, then having this periodically called on the gatherers would keep the tooltips of clients up to date.
      • In the escape menu networking details on the host, you can see how many of these have happened via the "Ship Syncs Forced" item.
      • BUT, this may actually wind up never being needed, stay tuned. We're going to make some additions so that anything a client is hovering over to get a tooltip gives them up to date info without you having to be predictive about it.
    • FlagAsNeedingFullSyncCheckIfInMultiplayerAndWeAreHost() is specifically to say "ignore my tier3 delayed status," to work around the feature we just added today where background ships get ignored a certain amount.
      • This is mainly something to use when something unusual changes (other than a ship existing at all) that would be visible on the galaxy map for client player, without them clicking into the target planet.
      • So for now this is something that happens whenever a ship marks up, and it also happens whenever the AIReinforcementPointContents contents are changed (increasing, decreasing, transferring, deploying).
      • This should keep the galaxy map accurate for clients, while at the same time not having so darn much data transfer for ships on planets where players are not active.

Version 2.630 Arbitrary Icon Inclusion And Weapon Exclusion

(Released November 11th, 2020)

  • Add death effect damage a unit has sustained into the tooltip for it at or above Medium detail.
    • Each type of damage is listed separately, and displays the current damage, and the amount required.
    • Thanks to Puffin for adding.
  • Fix a Macrophage typo
    • Thanks to crawlers for reporting
  • Fixed a bug in Astro Trains where they were looking for a nonexistent variable in their custom xml. This was always a harmless bug, but newly showed an error while in the past it was silent.
    • Thanks to ussdefiant60 for reporting.
  • GetDefaultValueOfWhateverSort() on the SpecialFactionData object has been updated to match the way that the default values were returned on the faction screens.
    • Thanks to NR SirLimbo for reporting that this was not working consistently.
  • The CustomFieldValues array on faction objects is now private, so that people don't try to directly add or find data from it.
    • Instead, mods and factions and whatnot should set data through SetCustomFieldValue (which works the same as before), and they should get data via either GetCurrentIntForCustomField() or GetCurrentStringForCustomField().
    • Both of those latter two methods have a method that lets you pass in the specific field (more efficient), or which just takes the name of the field (less efficient).
    • Either way, the idea is that there's never confusion with not getting the default value back when there is a blank present in the main data (which might be an old savegame or quickstart, or various other valid conditions).
    • Thanks to NR SirLimbo for finding this accidental modder-landmine for us.
  • Fixes for Kaizers Marauders:
    • Instead of failing horribly when added as a Random Faction, or when loading older saves where old Marauders were enable (be it just as a beacon), which includes quickstarts they will now use somewhat defaulting values. It's not perfect, and not really intended for use this way (simply because of the sheer amount of options available) but it works.
    • Fixed a potential issue with Debugging global stuff for Marauders (such as logging Kaizer Updating or the Shared Planetary Cooldown List) where the debug could be turned on, but when only a specific Marauder Faction was set to be debugged it could re-overwrite with false later on, leading to no printouts.
  • Remove mentions of 'tiers' from the scourge unit hovertext, since it was confusing peoople. It was only ever a cosmetic thing.
  • Suppressed a pair of harmless-but-annoying exceptions that could show up in your log files if you were shutting down the game from the main menu in just the wrong way. These were related to the Slate cutscenes trying to stop at the same time they were being eaten alive by your OS taking back its memory. All is well, no need for a dying scream.

Fix To Ship Weapons Mismatch

  • Added a new ArcenNonTableUniqueStringList class, which we can now use for keeping lists of arbitrary string that we want to serialize.
    • We're going to be using this for entity systems.
  • EntitySystemTypeDataTable has been removed, and EntitySystemTypeData no longer inherits from ArcenDynamicTableRow.
    • This was really old logic, and is the one instance in the codebase of us really not using dynamic table rows properly.
    • The result was slow during startup, in the best of times, and more recently it has been actually scrambling up the data for systems between different ships! That latter part may be new in the last few builds, or it might just be more common. Either way, this has needed a shift for a while.
    • The EntitySystemTypeData no longer has an InternalName, but instead has InternalName_Original (which is just the raw xml name like FusionBomb), and then an InternalName_Longer (which is the entity type appended in front of it, like "Mugger_FusionBomb").
    • The new serialization for these by index uses the shorter name, which just makes savegames a bit smaller. But it doesn't really matter what is used in the longer-term effect, because these are no longer stored in one central lookup. They are now properly full sub-entities of the GameEntityType.
  • With this change, shockingly, we have still NOT solved the issue of things like Mugger frigates sometimes getting Brawler weapons. So that's going to need even more investigation.
    • This overall change is still worthwhile, as it shrinks future savegames a bit (not ones from prior versions saved in the new build, though), and it also makes loading the initial game program a bit faster and less prone to potential issues... despite still having this particular issue.
    • Note from later: this actually solved 90% of the problem, but there was still a case of us managing something slightly wrong that let it keep bleeding over. So the last 10% is below.
  • The "copy_from" tag, which was never used on entity systems inside an entity, and which probably would not have worked well there if it had, has been removed.
  • Fixed a bug where our "dump data tables on load" debug option was no longer working (the hotkey was, but not the on-start version).
  • Fixed a very peculiar issue that only affected a couple of unit in the prior version (in the main game and DLC, anyhow -- more may have been affected in mods) where if there was a unit that had its systems altered on a child, and there were then other co-children, the other children would sometimes get those altered stats and sometimes not. Normally it should just pass to grandchildren and so forth, not to siblings.
    • Essentially, the way that we handle partial records is normally very explicit (is_partial_record="true"). And in fact, when we have a partial record like that, we WANT for it to inject itself into any other descendants later.
    • But in the case of entity systems, we have this kind of implicit "child partial record" system going on, where you just name the same system in the child as you had in the parent, and make some changes, and those changes then keep going in that lineage.
    • What we do NOT want to have happen is the siblings to also pick up those changes, which is what was sometimes happening here because of the funky way that we handle systems and systems alone in the game.
    • From looking at the raw data, without mods in play this mostly just affected muggers and brawlers, and a few spider turrets. Most everything else was already consistent properly. But if you play with mods on, you may have seen a lot of other chaos happening beyond these particular ones.
    • Thanks to crawlers, Ovalcircle, Spaz, Puffin, and Darkshade for reporting.

Work To Allow Arbitrary Sprites In Game Text, Part 2 (Complete!)

  • The sprites in TextMeshPro have been updated so that their default index is 0, not -1. That way if no sub-name or image is specified, we are still able to figure out where they are.
  • We don't use the mspace monospacing markup, so we're keeping things simple and redefining that to mean "no advance"
    • This essentially lets us put <mspace>around things we want to all be on top of one another</mspace>, which is really useful for our compound icons.
  • Since we already use non-atlased sprites in every location in the UI, and have those present and available as needed, we're just going to go with that for the TextMeshPro sprite embeds as well.
    • There aren't any sprites that we only have in atlases but not also in asset bundles directly, although there are ones that are loose and not in bundles.
    • With that in mind, this lets us avoid the glyph metrics that were working so poorly with our sprite atlases, and the efficiency of the whole thing is not much changed given how compositing on the UI works and how infrequently (overall) we include extra sprites.
    • This actually turned out to be a particularly good move, because what we've discovered is that if there are two different sprites used in a single text area, the following happens:
      • The draw order is based on the order of the first sprite dictionary used that is shared, not the order of the sprites in the text.
      • When multiple sprites are in one dictionary, this can lead to funky results. When there are single sprites per dictionary, the only time this can mess up is when there is a single sprite used more than once AND you want them to overlap one another.
      • It's worth noting that we don't care about the order of sprite drawing, normally, except for the new mspace markup.
  • The new custom TextMeshPro dll has been updated (by building the WorkingTextMeshPro project, as silly as that is) and the result has been put in ReliableDLLStorage so that we can compile against it and use those capabilities in ArcenUniversal, etc.
  • The copies of TextMeshPro code for the other three main projects that use it have all been updated to match the new capabilities.
    • This won't work in the main game build until it actually has a build done, though.
  • Added a new TextEmbededSprite and TextEmbededSpriteTable table, which are in ArcenUniversal and PARTLY filled by xml entries from the new TextEmbededSprites folder.
    • The rest of these are able to be filled programmatically as we load sprites from other locations, specifically when it comes to ships by name.
    • The purpose of these are to define sprites that can be used inline in text for improved display purposes. You can expect to see us doing more of this over time now that we finally have the capability.
    • It is possible for an auto-added sprite in here (such as for a specific unit type) to manually get some tweaks by adding xml for it. The order of that happening does not matter, which makes the system extra flexible.
      • This does mean that, because of the lack of order mattering, this table intentionally allows for malformed entries (those defining some metadata but having no actual sprite assigned). That's a necessary byproduct, since other parts of the code are assumed to add those sprites later, but might not do so if they were themselves removed.
    • bundle_name and filename are optional, and specify the location of where to directly load the Unity Sprite or Texture2D from during game load.
      • These are NOT used in cases where another class (like GameEntityTypeData) is creating new TextEmbededSprites on its own. In those cases, the sprite or texture2D is sent from the other class.
      • In the case where these ARE used, we need to know whether we can load it as a Sprite (ideal) or a Texture2D (slightly slower). The xml tag bundle_target_is_texture2d defaults to false, and so tries to load the target as a sprite. Anything used elsewhere in the UI would work this way. But if you need to load a Texture2D and make a Unity Sprite out of it at runtime, you can set this to true.
  • Added a static CreateRuntimeSpriteFromTexture2D() method on the TextEmbededSpriteTable, which takes in a Texture2D and returns a Sprite.
    • This is something that is particularly useful, because it keeps track of ones that were previously created, and reuses them rather than creating extras. This can only happen on the main thread.
  • About 50 initial sprites have been set up as text embedded sprites for use coming up.
    • There is more metadata that we want to get in there, plus some other things to make these as simple as possible to call on, and we need to actually cross-wire this to the new TextMeshPro stuff that we worked so hard on. But that will come tomorrow.
  • Fixed the AIW2ModdingAndGUI project so that it now has the proper TextMeshPro code embedded within it and so that it won't erase our customizations every time it is reopened in the unity editor.
  • Fixed the WorkingTextMeshPro project so that it now has the proper TextMeshPro code embedded within it and so that it won't erase our customizations every time it is reopened in the unity editor. This is how we build our custom variations on that code, and now we're not at risk of random regressions from unity package manager automatically wiping our changes.
  • The following float options are now available on any of the text embedded sprites for manipulating how they fit into the text they are embedded in:
    • x_draw_offset, y_draw_offset, width_draw_offset, height_draw_offset, advance_draw_offset.
      • All of those do the basics of what you might thing in tems of adjusting how the sprite draws, while advance says how much space to go over before the next character draws (or how it plays into word-wrapping or whatever else).
      • All of these are in fairly abstract units, where roughly something like 100 is about the height of a line, regardless of how many pixels that line actually is.
      • Most of the time you won't want to mess with these at all, but in some cases you may want to adjust the vertical centering by using y_draw_offset in particular. Beyond that, most people would not use any of these.
      • Frankly, to get the kerning of the strength icon working perfectly, we will probably add a few more dials to this soon.
  • Our TextEmbededSprite sprites are actually loaded up into TextMeshPro sprites now, completing the main integration of arbitrary sprites.
  • default_color_hex is a new string option available on the text embedded sprites, for allowing a default color to be applied to sprites.
    • Please note that, unlike sprites we had in the past that were based on vectorized glyphs inserted into a wingdings-like font, these sprites can be full-color to begin with.
    • The one "downside" is that these sprites can't be infinitely zoomed-in-on like a font, but that's hardly a downside given that we could render these crisply on an 8K monitor or more.
    • The default text colors are nice for purposes of things like resource icons that are embedded in text.
  • For now, ArcenFormatting has been updated to stop using the old font-based resource sprites, and now use the new TextEmbededSprite sprites.
    • This is a major jump up in quality in general. Also, now all of the resource icons properly match all throughout the GUI.
    • One thing to note, however, is that these sprites no longer inherit the color from their parent font.
      • So, in order to match the text color properly, we needed to add ArcenExternalUIUtilities.GetStrengthIconWithColor_Wasteful(), which hits the garbage colletor, and ArcenExternalUIUtilities.WriteStrengthIconWithColor(), which does not (use the latter if at all possible).

Main Menu Further Refinement And Expansion Logos

  • The planet that scrolls by in the background of the main menu sometimes has been removed, as it was having some glitchy effects on it that we definitely did not want. In the end, we don't really need the planet in order for this to be a very interesting scene as it is.
    • Thanks to Badger and others for reporting the problem.
  • The material properties of the main game logo have been updated substantially so that they look more natural in the light and shadow of the main game.
    • Thanks to Badger for suggesting.
  • The main menu now has logos for all three of the current and upcoming expansions, and they are more lit-up if they are on (installed and enabled).
  • The AIWarExternalCode library now links against ArcenThirdPartyCode so that it's able to make changes to certain things in the front-end game.
  • The main menu now uses a hook to go in and find our custom BetterRotationScript on the background that spins the space skybox, and slows it down substantially compared to prior releases. This saves us the wait of a 40-minute rebuild process, and in theory actually would let us have a variety of random rotations if we felt like it.
    • Thanks to Badger and Asteroid for suggesting.
  • In fact, since we can, the rotation of the stars in the main menu is now entirely random, but at a much lower overall speed than it was before. It can rotate at a combined maximum velocity that is still only 3/4 of what the prior maximum speed was, and almost all of the time it will be vastly smaller than that.

Version 2.629 Ship Cap Hotfix

(Released November 10th, 2020)

  • Corrected the OpenGL launcher script on GOG, thanks to GOG support (it was our error -- thanks to them for figuring it out!).
    • It appears that the issue didn't affect all flavors of linux, but it certainly did affect some.
    • Thanks to rudhek for reporting.
  • A simple typo was breaking all of the xml parsing for sub-lists of data of the following types (unless they had the requirement of IsUnique on): fint, arcenpoint, vector2, vector3,
    • Most of these were new or unused in general, but fint was not new and is used for the scaling of ship caps in the game, as well as for the engine stun seconds progression.
    • All of our other list parsing, which are more commonly used, were all working fine.
    • Thanks to Wuffell, ArnaudB, ThyReaper, and other for reporting.

Version 2.628 Mod Proliferation

(Released November 9th, 2020)

  • Fixed a bug where the Tame Macrophage Hack was not correctly responding on certain Quickstarts.
    • In actuality, the Enraged subfaction was entirely missing from those quickstarts! Very bizarre.
      • Thanks to Smidlee and Metrekec for the bug report and saves for testing, and StarKelp for fixing.
  • Fixed Cloaked Transport Flagships from starting fleets having the default transport direct tech upgrade costs instead of the higher ones that captured cloaked transports do.
    • Thanks to NR SirLimbo for fixing.
  • Adjusted the amount of Combat Engineers Support Factories get for both starter fleets and captured fleets, balancing them a bit and bringing both spawned and captured fleets more in line:
    • Rejuvinator: 8-13 (starter fleet remains at 10)
    • Overloader: 4-7 (starter fleet changed from 3 to 6)
    • Everything else stays the same, but the Combat Factory starter fleet goes up from 6 to 8 engineers
    • This hopefully kills the bug where Combat Fleets spawn in with 2 Sentry Frigates too.
    • Thanks to NR SirLimbo for making these changes.
  • Added 2 more tiers to Metabolization and Greater Metabolization in preparation to additions to ESV.
    • To clarify: This is NO new types of Metabolization but simply new conversion ratios damage/shot -> Metabolization points. By default Gangsaws for example deal 10x as many Metabolization points as they dealt damage.
    • The new tiers are "BigMajor" for a conversion ratio of 5x, and "SupportWithoutDPS" for a conversion ratio of 50x.
    • Thanks to NR SirLimbo for adding.
  • Some minor buffs to Shark B
  • Fix a typo in the Mesopotamia planet list description
    • Thanks to Lord of Nothing for reporting

Included Mod Updates And Additions

  • For modders reference: rename BadgerFactionUtilityMethods to FactionUtilityMethods.
  • Disabled mods and/or expansions that are installed on your machine no longer temporarily show up as enabled for just a few moments during the initial load of the game. That was confusing.
    • The Settings from any installed-but-disabled mods and expansions ARE loaded, so that those can be kept properly if you are enabling and disabling mods over time, but those are the only parts loaded when they are disabled.
  • KM / AMU mod fixes:
    • Fixed a very strange bug about fireteam debugging where for some reason it couldn't find the Fireteam.GetDangerOfPath() function.
    • Hopefully fixed another very strange null ref exception in the Marauder LRP
  • Civilian Industries mod:
    • Fixed a bug where Fireteams were being rude and not letting civilians use their danger pathing code.
    • Optimized a few pieces of code to hopefully help with the performance issues some people have been recently having.
  • Fixed a literal 1-symbol-bug in Kaizers Marauders where they would not accumulate AIP but instead reset their AIP to the most recent increase.
    • This also lead to the discovery of a bug for the Debug Mode where Marauders produce and use real AIP that multiply AIP by the number of AIs present.
    • Thanks to ussdefiant60 for noticing.
  • New content for the Extended Ship Variants mod and its counterpart for Fallen Spire. Do note that the latter now requires the base ESV installed!
    • Extended Ship Variants:
      • Added 4 new types of Transport Flagships: Engineering (hybrid between a stronger engineer and a transport), Vanguard (hybrid between a Vanguard and a transport), Tugboat (has small drones accelerating everything to at least 700 speed and can slow down enemies) and Target Painter (long-range beam that amplifies damage dealt to a single enemies)
      • Added 3 more types of Mobile Factories: Metabolizing (launches Metabolizing drones), Rescue (creates rescue-beacons that can revive ships), Translocator (good AoE explosion that pushes small ships back and paralyzes them)
      • Added 6 new mobile starter fleets with ESV ships and transports included into them.
      • Added 5 new support starter fleets, 3 with ESV mobile factories and 2 with vanilla mobile factories that did not have a starter fleet before
      • Buffed the Agile Transport: +25% speed on entering a new planet for 5 seconds, -50% damage if attacked from >= 5000 distance, 21 gx engine to resist Black Hole machines
    • Extended Ship Variants for Fallen Spire:
      • New Transport Flagship: Cyber Command (reduced hacking response, much more expensive, much more fragile hull but decent shields)
      • New Mobile Factory: Acidic (launches drones spreading acid onto enemies)
      • New Mobile Starter Fleet: Hacker Fleet (designed to deal with AI hacking responses)
      • New Support Starter Fleet: Combat Engineers and Acidic Factory
  • Increased the timer on Kaizer's derelict to allow for a longer time period to save him. Instead of 1% health per second he now loses only 0.3%, which grants 334 instead of 100 seconds time to save him if the player so desires.
    • From a discussion with SilverLight on Discord.
  • Updated Kaizers Marauders to be compatible with this new AIW2 version (no functional change) so players should be able to hop back in as soon as the update drops, without having to wait for an update of the mod in response to an update of the game itself.
    • Updated the source files on AMU.
    • Worth noting that the Civilian Industries mod did not actually need an update for this new version because it didn't happen to be using the features that changed.
  • Fixed a type mismatch now exposed through the new External Constant Loading in Kaizers Marauders: AIAlliedInvertedTechBonusFactor was declared as FInt, but loaded as int. Is now also declared an int so it works.
    • Curiously this didn't seem to have any impact on the mod in any way... Strange, but ok.
  • ExampleMod and ExampleMod2 have both been removed from the game, as they were utterly pointless at this point.
    • There are more and better ACTUAL mods of all sorts for you to look at if you're thinking of getting into modding.

New Micro Mod Collection By NR SirLimbo!

  • Added the Micro Mod Collection mod to the off-by-default mods.
  • Currently adds:
    • 4 types of Distribution Nodes: 6m metal for 1 AIP, 45 hacking points for 2 AIP, 3k science points for 3 AIP, 4m metal/30 hacking points/2k science points for 4 AIP.
    • Energy Converters (10 for Home Command, 5 for every Economic Command Station) that convert 50k energy to 150 metal/second
    • Research Expedition: Mobile science/hacking gatherer that can speed up gain on owned planets but also extract from allied/neutral worlds, scout adjacent planets and at higher levels decloak/cloak itself. Fragile, high-priority target for the AI, producing 20 AIP on death.
    • Reinforcement Seeder: AI ship dropping Minor Reinforcement Warp Gates that increase planetary reinforcements by 5% per gate.
    • 3 types of AI Command Stations with escalating levels of strength: Gravitic (slow aura), Tachyon (decloaking aura) and Pulsar (periodic paralysis aura).
  • Balance and general feedback required and sought after!

Work To Allow Arbitrary Sprites In Game Text, Part 1

  • Added a working testing project for altering TextMeshPro, while retaining compatibility with all the various unity scenarios in which we use it.
    • Attempted three different ways of updating it to have new sprite embeds, but so far those methods were all a bust. Going to try another method of injecting our own sprites, instead, and for that we need to start basing our things on having some sprites and then shoving them in. Thankfully we have a nice little isolated test project for this, which now has some added info in it.
  • Added some code in ArcenXml that lets us parse xml directly from TextAssets, mainly for testing.
    • This is also used now in parsing the sprite dictionaries that we are creating via TexturePacker.
    • Also set things up so that we can now have sprite dictionaries that are a single sprite loaded directly from a unity-style sprite with borders, etc, intact.
      • This is useful for some of the other new icons-in-text that we want to do.
    • The general purpose of this is partly for test loading sprites of two different categories in a way that we can start trying to get them into TextMeshPro programmatically, but this also would be used long-term once the testing phase is past.
  • Made a change that makes it so that if a sprite material is destroyed (such as one that was created at runtime in the unity editor) it will now just display as a blank image rather than throwing errors inside TextMeshProUGUI. This is mostly helpful for our own internal testing of our injection of our custom sprites into TextMeshPro's rendering pipeline.
  • References to ArcenSprites are now stored on their parent ExternalIconDictionary.
    • We never needed this before, but now that we are translating entire dictionaries into use for TextMeshPro, it's a thing.
  • TextMeshPro has been expanded to allow for us to inject our own images at runtime, from any source (not just Resources, but rather asset bundles and whatever else).
    • We can inject unity Sprite objects, unity Texture2Ds, and our own custom ArcenSprites in their entire ExternalIconDictionary.
    • This new capability is set up so that we can also control things like how they are scaled and offset, and essentially how the kerning works.
    • Whether we use all those features or not is not really relevant, but it's good to have options.
    • This is far more powerful than our old method of drawing images in text in TextMeshPro, which was limited to a special "Arcen Icons" font where we had vectorized some of our icons into a font format and were using that to draw icons.
      • In some respects that was nice because that gave us infinite zoom on those icons, and now we're using raster images with a fixed maximum resolution, but those other icons really did not behave well when it came to trying to line up with varied fonts. Often the offsets and kerning were terrible, and updating them at all required a rebuild of the central game executable, which is time-consuming to say the least (that's about a 40 minute wait).
    • This new approach allows for images to be inserted into text by mods, let alone just our own code.
  • We don't yet have the new TextMeshPro stuff integrated into the main game, but it should be tomorrow.
    • For now, we've got our new data formats and are testing the last of the capabilities we need, and trying to make sure that our sprite dictionaries translate properly to theirs, which is so far not quite working right but getting close. Single images are working great.

Giant Overhaul Of Xml Parsing For Accuracy And Speed

  • exclude_children_from_copy was not an xml feature we were using, and it was slowing down xml parsing in general, so we've removed it.
  • The way that child nodes and attributes are determined to NOT be copied in xml is now vastly more efficient, and doesn't involve any GC churn.
    • This should lead to more accuracy when we pair it with some other changes, as well as faster loading times in general once we finish with our changes.
  • Really substantial xml processing speed improvements during game load. These have to do with our checks to make sure that the xml is correctly formatting and we are importing all the proper nodes.
  • The way that attribute-checking is logged and verified is now vastly more efficient than it was, so again loading is faster in the initial part of the game.
  • The xml parsers that were able to give back a list of children no longer do; there are instead DoForChildren methods that don't require a hit to the garbage collector, and which also make it so that they don't have to be wrappered more than once.
    • This is substantially more efficient in several ways.
  • Instead of copying xml attributes and nodes from parents to children in partial records and copy-from records, these are now linked, and calls like GetBool() and similar are able to process through them much faster and with accuracy.
  • Added a new EqualsCaseInvariant() overload to strings based on ArcenUniversal.
    • It turns out that this is very slightly more efficient than doing a ToLower() and comparison to the lower-case version.
  • Our xml parsing now gives visible errors when trying to parse integers that are not valid integers. Before, it was just failing silently and returning the default value.
    • GetInt32List was removed from our xml parsing, as it was inefficient and not something we've been using in AI War 2 in general. This was generally used in some of our older titles.
      • Same with GetInt16List, GetByteList, and GetFloatList.
    • Also, a variety of duplicative methods that were concerned with complaining if a value was missing-or-default have been folded into the main methods for getting from xml. We also now only complain if the value is outright missing, as in basically any case where the default value is specified that is an intentional thing.
      • We have now removed the ComplainIfAttributeNotFound() method, since that was only used when we were looking at complaints about "missing or default, but actually default is fine." This makes for far cleaner code.
  • Our xml parsing of vector3s is now much more efficient, although we do not process those very often anyway.
    • Our xml parsing of FInts is now a bit more efficient, and that is processed extremely often.
    • Our xml parsing of enums is now a bit more efficient, and more normalized (same with FInt actually), as these are processed very frequently.
      • One change that may affect mods is that FillEnumIfPresent has been removed, and is now just FillEnum. Assuming you pass in false to ComplainIfMissing, it will act as you previously experienced.
      • Another is that FillEnumAndComplainIfDefault has been removed, so now you'd just use FillEnum and pass in ComplainIfMissing as true.
        • This is technically a difference in functionality, because this only checks to see if something is missing, not if it has a default value (usually None or whatever).
        • Generally speaking, our experience has been that if someone sets up a default value in xml explicitly, then they probably have a reason to do so. We've been having to work around this with reading in xml in general, and now it doesn't complain about explicitly-set defaults with other data types, either.
        • This should not negatively affect anything current, as any xml that was "invalid" by the old standard would have been complained-about already and preventing clean game launch. Any new xml that is created in such a fashion is probably on purpose.
      • We also got rid of GetStringAndComplainIfMissing(), which had basically the same sort of issues. Just use GetString() or FillString() and complain if it's missing, but if someone sent in an empty string from xml, they probably meant to.
  • The way that we were previously handling "custom data sets" on xml rows was incredibly slow as well as kind of brittle, particularly when it came to modding.
    • This is seeing an entire rework, with the pattern for getting custom data becoming far simpler (but also more powerful, as mods and copy-from and partial records will now work correctly in all cases).
    • First of all, the CustomDataSet class and all its methods have been removed in general. ParseCustomDataIntoSet() and GetCustomAttributeNames() have also been removed. Also the CustomDataLookup class.
    • Custom attributes are instead something that code is able to parse as-needed later on from the xml, and the "requested attributes" code just ignores anything that begins with "custom_"
  • The ExternalCoreConstants, which was not actually used for anything, has been removed.
  • Vector2 xml processing is now consistent with Vector3, whereas before it had only a subset of the capabilities.
    • Same with ArcenPoint.
    • AngleDegrees has instead just been removed, as it's not something we use and we can store that in different formats more easily.
    • Loading DynamicTableRows from xml has also been given full parity, and in addition to that they are now able to take empty commands now to set null instead of the prior row reference. This is a new ability.
  • We were previously using various forms of XmlElement (which is a built-in-class) manipulation in order to handle copy-from and partial records cases.
    • This was not appearing to work as expected, and at any rate is generally something that is probably pretty slow.
    • We are removing our TotallyReplaceContentsOf, CopyAttributesIntoBlanksOf, and CopyChildrenTo methods entirely.
      • The CopyChildrenTo, which affects child nodes, had some notable strangeness that it was overcoming when nodes were being copied from one document to another (aka two different xml files). We just don't need that sort of hassle.
  • The ArcenXMLElement RawElement entry on ArcenDynamicTableRows has been renamed to be OriginalXmlData instead.
    • This is far more clear, and is going to be very key for the later forms of parsing that we're doing.
    • ArcenXmlElements now have private DirectParentsICopiedFrom and PartialRecordsLaterAppliedToMeInOrder variables that get set as-needed. Internal processing handles these properly so that end-user modders or developers don't have to think about these details.
      • These help to ensure that data is applied in the correct order, as intended, and that the data can be reconstructed as needed.
    • HasAttribute() has been removed from ArcenXMLElement, and instead we have GetMostRecentAttributeValueIncludingParentsAndPartials() and GetMostRecentAttributeValueFromSelfOnly().
      • This will seem inconvenient in a variety of places for modders, but it saves us a ton of extra read calls into a potentially expensive method (especially now that we properly handle xml inheritance). Just read the value once, if it's a string, and if it's blank or null then that's your answer. Or use any of the fill methods and just say you don't mind blank entries (or only do if it's not a partial record, your choice). It will fill things properly.
    • During the read of nodes, it now causes either RegisterMyDirectParentsICopiedFrom() or RegisterAPartialRecordAppliedToMe() to be called, and/or OriginalXmlData to be set.
      • From looking at this, in the past versions, most likely OriginalXmlData (aka RawElement) was probably being overwritten improperly once a partial record was applied, and this was probably where our errors were coming from in parsing certain mods.
    • Additionally, if a single xml record is defined as being both a partial record and a copy-from record, it will now throw an exception. That should not have actually been the case on any, but now it should check on them properly.
  • On ArcenAbstractExternalData and its descendant classes, like ExternalConstants for instance, there is now an ArcenXMLElement OriginalXmlData property.
    • This one works just like the one on rows, although in this case it's just used for partial records, mainly (there are not child nodes, and there's only one root node in these files).
    • This then lets us make direct calls to GetCustomFInt_Slow() on the ExternalConstants singleton and similar in order to get "custom" xml data that is added belatedly, as we see for a lot of the faction data and mod data.
    • This particular change will require changes to most mods, as the CustomData by namespace and all that is replaced by far more direct and efficient calls here, now. Though if the results are checked with any frequency, you should still be caching them for sure.
    • We are using wrappered methods, rather than giving direct access to OriginalXmlData, in order to control error handling and make sure that if your mod is looking for a field and fails to find it, it will yell.
      • Bear in mind these particular fields are not found at game launch, but rather whenever the faction or mod initializes. So typos are likely to be cause errors during first unpause with a faction present, rather than during load of the initial game like everything else.
      • The extra error handling that is in this is absolute crazy, incidentally, so if you're not getting the result you expect, then you automatically get an entry in the log with the details of what was present so that you can figure out what your typo was.
  • With external constants and similar dictionaries, it now ensures that the base data is now read in before any partial records are read.
    • It seems like someone was referring to this being hard to mod, and this would likely solve that. At any rate, with our new more-strict reading this also became needed in general.
  • With the new XML parsing, the game does a far better job of reporting problematic data from xml (aka something like a floating point number being imported into an integer field).
    • Why this was not working properly before is a bit of a mystery, but it works now, which is the important thing.
    • There were several bits of rogue data that we've thus fixed, including the amount of extra intensity the scourge gets from human science amounts. This may have some balance impact on the scourge, as those values were probably previously reading in as zero.
  • Full list of data fields now corrected that were previously not reading in properly and thus probably affecting faction performance in some fashion:
    • Scourge difficulty:
      • AllowedBuildersIncreasePerScienceUnit (was always 0 because of type mismatch)
      • BuilderIncomeIncreasePerScienceUnit (was always 0 because of type mismatch)
      • SpawnerIncomeIncreasePerScienceUnit (was always 0 because of type mismatch)
    • Human Resistance Fighters
      • RatioForFriendlyPlanet (was always 0 because of a typo - RxatioForFriendlyPlanet)
  • In the event of partially-mangled data from entity systems, the game now does a bit better job of reporting clearly what the problem is with the xml and setting some general defaults rather than just starting in a completely invalid state.
    • This is most notably with a missing range being set on a system.
    • Additionally, we've added a new WriteSystemDataToLogDueToError() onto GameEntityTypeData, to let us see what the state of all systems on an entity are when a problem arises.
  • There was some funkiness in how some of the passive systems were looking for ranges that they did not need to have, in ComputeBalanceStats_OneTimeOnly(). Those have been corrected/
    • This is a case where we wonder how this was not causing errors in the past, but whatever. Again, it works now.
  • Further cases of fields that had malformed xml and thus did not read in properly:
    • Settings:
      • Windowed Mode Window Height maximum (typo of case Max instead of max led to it being infinite rather than 7000).
      • Kaizer's Marauders Marauder_DebugID, same typo of Max.
      • Hidden field of FullscreenHeight, same typo of Max.
      • Kaizer's Marauders Marauder_FireteamDetailLevel, same typo of Max.
    • AI Types:
      • SimpleEnsemble was not having its type_Difficulty read in, because it should have been type_difficulty
  • The game now allows any fullscreen resolutions that your OS/hardware reports as being available.

Version 2.627 Hotfix

(Released November 5th, 2020)

  • Hopefully make Warden fleet ships less likely to turn to the Hunter when in combat
    • Noticed by a lot of people
  • Make reconquista a bit less one-dimensional.
  • Fix a bug where the galaxy map was showing the wrong faction colour for enemy units.
  • Fixed a bug in the prior version where the scrollbars and scrolling in any dropdowns was not working.
    • Thanks to JonnyH13, Karchedon, and Badger for reporting.
  • The selected status of the stance buttons in the bottom left of the screen have been adjusted once again in order to be dimmer and less distracting.
    • Thanks to Metrekec and crawlers for reporting.
  • Balance Adjustments to Kaizers Marauders:
    • Changed the budget income modifiers per intensity to be based off the 0.4 + (AI income/1.5):
    • Also increased higher-intensity base defense buildup cap: Medium Intensity from 40 strength to 50 strength, High Intensity from 70 strength to 125 strength to make them more defensive.
    • When their budget was increased gradually to compensate for the high growth of strength that high-ranking AIs had it made them too powerful when fighting lower-intensity AIs.
    • Now, hopefully, Kaizers Marauder intensity roughly follows the same scaling as AI difficulty, but lower ranks are still supposed to expand further and by comparison are stronger.
    • When picking the intensity for Kaizers Marauders I suggest: Think about their most lik