Neptune's Pride Agent αλφα Edition

Since I last posted, I have released 2.2.9, 10, and 11, which were individually small bugfix releases but add up to a fair number of changes now that there are three of them.

The bulk of these changes have been focused on making the time machine and its corresponding reports more robust and – dare I say it? – bug free. Now that all API keys are automatically discovered from your messaging, the time machine and reports know how to properly use all the data available to give you the best historical info possible given what you know. The ownership report and activity report no longer require you to have merged your own key to know what to do. The key report can recognize dead keys and tell you when they were invalidated so that when someone revokes a key on you, you’ll know when they did so.

For formal alliances, the combat calculator now recognizes stars and fleets belonging to your allies and gives you more correct combat outcomes taking that into account. As far as I’ve seen, this works well in formal alliance games to enable you to properly plan defence and attack with multiple players’ fleets on the move. Also for formal alliances, your counterparty gets charged 150 until they accept, and acceptance refunds 75; so on the accounting sheet the balance will show you what they owe you from your point of view if you offered the alliance.

For bulk trading, if you had to send multiple levels of the same tech it used to show you the correct cost but then transmit only one level of each tech. Now it transmits all levels that are missing to the recipient.

Game messaging read/unread bugs are improved, but I don’t think they are completely eliminated. I would really value bug reports on specific cases where it failed for you as this is turning into a thorny problem that is outside the clients’ control.

The economists have come to town. They would like to advise you so that you can figure out when Terraforming is a better tech than Banking. They report as follows:

First off, they assume you’ll spend your cash stockpile on econ (the number in brackets in the header). Then, they tell you how much income that’ll buy you if you have no tech in time (the $170) or if you get banking tech first ($245), or if you get Terraforming first to make the econ cheaper ($200). Then they compute the balance you’ll have right after paytime and tell you how much Econ, Industry, OR Science you could buy if you spent it all in one category. As expected, you can buy more with less in late game Terraforming, but in early to mid-game banking is quite competitive. Happy researching.

The controls table is updated. It’s as ugly as ever but now lists the hotkeys in the hopes that will make it easier to absorb them for future use. In addition, if you press a hotkey when the UI is already up it will show you the correspnoding report rather than just silently putting it on your clipboard (it is still on the clipboard and in the ‘Intel’ button as before). Finally, hotkeys that conflict with browser hotkeys, like Control-8 and Control-9 on Windows and Linux now take over the functionality so that they work without triggering browser behaviour too.

Speaking of C-8 / C-9, if the territory display is not visible and you try to change the style, the first “change” will make it visible instead of changing it. So when players are confused that it is missing and try to change the style to bring it back, that will now work as they expected (2 users with this bug report).

Pimple drawing on range and scanning territory didn’t used to adjust when you used the combat handicap to see what you’d get with one more level of these techs; now it does. Substitutions in messages used to cap at 1,000 which was too few for really big games; increased the cap. And the QUIT QUIT QUIT bug came back and had to be fixed again.

commit 81f64369355c5cdb1dc067c65ad79f88263a794d

Some fixes for unread state; still unsure it is working.

commit 8e2fabefa38677c47a731d4a1952dc397b0989bb

Update star ownership to work across multiple API keys.

Following the same pattern as for activity, walk through the ticks
using all available API keys to generate the best star report this
user can.

commit 25ebcace38603a746bad29f75451b19b88e98c02

Fix a missing case for alliance detection.

The allied fleet check for the combat calculator only worked
in one direction; but alliances go both ways and so the condition
needed updating. I think it is correct now.

commit d3c1ec8f6a7e488907526f2a3c08790a7d223615

Fix the activity report to use all available scan data.

Instead of relying on the user to have a single key for the whole
game, search all known API key data to build the activity report.

The approach taken is horrifically inefficient, but after caching
the JSON.parse results the time varies between about 60 - 100ms,
fast enough to be not worth fixing yet.

commit a3d9db3ae139337ff98819d31be837ddeae0c43b

Charge for alliances in the accounting screen.

When you request peace, consider that the other owes you the full
price of peace until they accept. If/when they accept, count that
as half the value so they still owe the other half. On game defaults
that means someone owes you $150 as soon as you offer peace and $75
if they accept.

commit 8ea09b3b43c8bb249bc395dfc6301de15393917a

Attempt to fix unread state after load time too.

commit 3c17e74ba3a429b46fa6442d9fa2328e931186a4

Update the economists report to include buys.

In addition to your balance, show how much of each thing you can
buy after the tick so that it's clear when Terraforming has made
your money more valuable than $75 more of today's dollars.

commit 87979f80c8f4a08bee2127ebe001b796d0e58fc5

Try a different layout for the controls table.

The controls table was already not very nice looking; try
having a single column with hotkey reminders on the right
to see if that helps users find/remember the hotkeys.

commit 10a415aa5706ff81cc2c006aadac3c89537710c5

Update battle calculator for allied fleets.

If we know a fleet is allied with us or we are allied with
the destination star, show an arrival rather than a combat.

commit 8478cef51a8738ad86a558d2eddfd474ae2b6275

When the UI is already up, visibly display reports.

If the user has brought up the UI and triggers a report, immediately
display it as well as putting it on the clipboard.

commit 0825d747759c860baa136554d063a177a401eb5a

Change territoryBrightness behaviour when display is off.

Sometimes users have turned off territory display with ) by accident
and then try to use ctrl-8 / ctrl-9 to change the style to fix it,
but think it's broken. If display is off and you change the style,
turn it on first (and don't change the style); then if you change
the style again it will change as expected.

Also attempt to make all hotkeys override browser hotkeys by telling
Mousetrap that is what we want, so that c-8 / c-9 don't also switch
tabs on Windows and Linux.

commit 4133290545a1db6ac5a027ac6d1be56483cd1e4e

Fix up some bad boundary condition bugs.

In bulk trade, if you didn't have the cash to send a level, the
new code to try to send all levels would wind up in an infinite
loop. Just give up in this case.

In time travel, traveling forwards across an API key reset
boundary would fail to start at the right place in the new block
and give up on finding data. Fix it to start at the beginning
when moving forward, and at the end when moving backwards. Linear
is still fast enough but probably I will want to make this a binary
or galloping search if the tick # is far enough away from the current
index...but at least it is now working well in the presence of
multiple API keys in all directions.

commit edade32cf242cf9c2761c693eefda52fa9bf0f3d

Record eof so that the key report works again.

commit c55caba409325af5c37b8b11767994f56970d3ed

npaserver doesn't yet recognize bad keys, defend for it.

Since the server will happily return error codes for every tick
after someone invalidates a key, be sure to trim those bad entries
off so that the time machine still works.

commit a3b1af644f1216c243f61559c1382f0db43685fd

Fix key report to handle regenerated keys.

Once a key is regenerated, recognize it and find the last good
scan from that key. Report that timestamp in the table for all
seen keys.

commit 6e7e363c370a51aca676b4d186e8309069fef054

Early version of the economists report.

commit ea6e48323b3a8127d7df1f0be36d5798f06319f4

Bulk send wouldn't send duplicate techs.

Bulk send would send only the first level of each tech instead
of sending all of them. The price listed was correct but the
transfer was incomplete, fix it to send all missing tech levels
at once.

commit 74514e22f29d8d0b5ce7d24997723ba1ee37efbc

Accept dashes in youtube video IDs.

commit 9588bd50d2d35408aed13c44602474cb2d5ad714

Have the message cache read state be authoritative.

The server expects that if you request a comment thread, you must
be on the screen that displays the comment thread because that's
the only way that ever happens in the vanilla game. However since
NPA is caching all the diplomacy for you behind the scenes, that
means that the read state is wrong for the UI.

Update it so that the read state in the database cache is
authoritative, and that read state changes will trigger database
updates. This seems to fix the unread count/unread message problems.

commit 873fd759fae3c7aa2c87b94adebe8a80e2dadec6

Increase substitution limit to 5k for big games.

commit e84145699f025e45bd9b6939b34c96cde8f6a108

Update pimple drawing to respect range adjustement.

Previously the pimples for borderline stars were based on the
star owner's true range, without the handicap adjustment. Fix
up the drawing to be simpler for star territory so that the
range adjustement would be factored out, and then use the
refactored range calculation for the pimples too so that the
feedback is always right.

commit 7e660570d8d8d63eff4e297bb42d301f929056c3

Add visibility pimples for stars on the border of range/scan.

Shrink where the border is a bit so that it clearly excludes stars
that are out of scan/fleet range, and then route the border around
stars that are close to the border but actually in range. Should
make it much clearer what is in or out.

commit da5516cac7f774b5d62285182783b61ea7b9ff64

A first cut at typescript types for scanning_data.

The API returns the galaxy wrapped in an object named scanning_data.
Provide typescript types for this structure to make it safer to take
apart correctly.

commit 5abb84dec993183b18481bb9b885931348a75e28

Fix the QUIT QUIT QUIT bug again.

When the early exit was added to avoid merging one's own scan
data, it also bypassed the fix for the QUIT QUIT QUIT bug on
each merge. Fix it so that the player name reset always happens.

commit b3b9924bed293a7b748278aba437edd086911ae5

Make the time machine move in turn increments.

In turn based games, it is annoying to have to step through multiple
ticks of "missing data" because of the 8 tick turn increment. Instead
read the game configuration and jump around in turn increments so
that you can play back the game as you might expect given that there
are no intermediate updates.


This feature also looks particularly excellent! I might make one request on it though - I’d like to see an adjusted amount for how much my new income could be if I bought the tech rather than researched it. This would assume a purchase cost equal to the transfer cost, and would just help planning if it’s better to buy the tech before or after the cycle from an ally… and if you’re feeling adventurous, then allow the user to put in a custom cost for if a “neutral” party is willing to sell the technology for more than transfer cost.

Thanks for the suggestion! Like this, you mean?

Pretty much exactly what I was thinking.

1 Like

OK I apologize it has taken me quite a while to get a version suitable even for the αλφα Edition as a major rework of the format for the time machine caused me a lot of issues. However at last v2.2.15 is up and is on the path to becoming v2.3 in a few more point releases…

Most changes in this release have to do with reducing memory footprint of the time machine, which was topping 1.5G of RAM on my 64p game with multiple ally keys merged. With v2.2.15 this is cut back dramatically and the client no longer constantly crashes on mobile.

The very nasty messages unread bug is finally fixed, so that the unread state in messaging can again be relied upon and the correct messages show up as unread in your list. A side effect of this is that for NPA to know about someone’s API key you have to have opened the thread that contains it, but as soon as you’ve done that the new key will appear in your key report.

One relatively uncommon but nasty bug with scan data merging is fixed: if a star has a ship transfer from an outbound fleet, the ships at the star would be shown incorrectly when the owner’s scan data were merged. Now the owner’s scan data are seen as authoritative, allowing you to see correct state. This also means that if the owner built a warp gate this turn, when you merge their scan data you can see it and use it. Neither of these things work correctly with scan data sharing from your Formal Alliance, so it is desirable to both have an FA and merge the FA’s keys using (.

For messaging, the star and activity reports get too long for the substitution limit in big games, so the limit has been increased. For bulk trading, an uncommon bug where the footer numbers wouldn’t be in the right order relative to the column headers is fixed so that they correspond to the empire whose column they are in instead of being scrambled.

The UI is no longer hidden by time travel, so it’s easier to find the tick when someone received a tech for example; just bring up their empire page and walk back 1 or 20 ticks at a time to find when it changed.

The biggest features are a new (and therefore probably not bug-free) line in the combat HUD that tells you what is needed to reverse the outcome of combat:


This feels pretty good both for fixing your attacks, fortifying your defences, and figuring out if your target is truly vulnerable or if they can defend with sufficient force. In addition to these changes, ensured that FA defenders use the max WS to defend so that FA defenders are properly accounted for by the battle calc.

Along with this, there are two new filtered fleet reports, one which shows you all the combats that are upcoming, and one which shows you all fleet activity related to the selected object on the map: if a fleet, then just that fleet; if a star, all arrivals and combats at that star. The fleet reports also include the new data on how to reverse the combat outcome.

Thanks to @BelSon for his FR on the economists, they now report on bought vs researched tech. Thanks to @Gingey for his FR on the time machine, you can now press control-m or control-/ to jump one cycle’s worth of time instead of only being able to move one tick at a time, and in addition all times are now links that will jump you directly to that tick. Future time travel does not work (yet…).

commit e89ab5a14cc3a4681ceb6e5f31bf14fd7e033db4

Fix a star data merge bug.

Take the owner's scan as the authoritative one for a star so
that in-flight orders like ship transfers are properly accounted
for in the merged view.

Note that even FA scan information doesn't give you this view, so
you're better off looking at the map with the API key merged than
relying on the FA scan info sharing, which doesn't include fleet
orders and ship transfers.

commit 41d16494746dc12ccb852b341b05819ad711e5ad

Up the substitution limit again, still too low for 64p star report.

commit f34ed66a92f815771b22d4df6db2973b38f53bd7

Manually cloning scandata is 6x faster than structuredClone.

window.structuredClone handles special cases that don't exist in
the data structure and this makes it a lot slower than just slogging
through and copying the keys by hand :(

commit d09413cc753d98871cf998fa9e91bc9fa25c181d

Change patch to for .. in instead of entries.

Calling entries is about 40-50% slower than looping over and looking
up each key individually.

commit 78664d3a21922b0a413a0fa9d50c0c71bcea9fbc

Add filtered combat reports.

Make it possible to see the equivalent of the long fleet report
but only those stanzas which contain a substring of interest. Two
new reports added, one that looks for "Combat!" so that you can
review all combat outcomes, and one that looks for [[NAME]] so you
can look for a specific space object (fleet or star) and see all
the fleet travel projected to affect it.

Ultimately this will be used for notifications to take you directly
to a combat summary of what the notification was about, using the #
portion of the URL to query the filtered fleet summary.

commit 5f53ea8c71175a1f7db0f10b1a731a771074a6f7

Update battle calculator to display the tipping point.

Now, for every combat, indicate what the losing side requires in
order to change the outcome, regardless of who is losing. Useful
to see what you need when your attack/defense is lacking, and also
useful to see if the enemy has a hope of defending against you
with the help of nearby systems.

commit 1212fb880052712fd655821d195b414b7391be79

Don't hide the UI when time traveling.

It is actually often convenient to have the UI up when moving
through time, for example to watch a player's empire page for
tech changes. So leave whatever UI screen the user had up up
when they time travel.

Unfortunately for NPA's own UI this takes you back to the
relatively useless home planets report. That probably needs
fixing in a future patch.

commit 86956fd19e39ea720264f228f2e2db277dd23181

Record API info per key to make activity report better.

Base the activity and star ownership report only on data
from the user's own key as a quick hack to make these
reports run much faster in large games with multiple keys.

commit 6b8f23b9fd1af66ed0ed158d7873ed09daaf20bf

Cloning at the end of getTimeTravelScan is 3x more efficient.

Still too slow but the 3x time savings is noticable.

commit 89997d9b994b972b7e8007363e1f9325a7d5f1ed

A slow but definitely working version that clones scans.

The client code in intel.js was relying on the fact that the
scans were all separate, mutable objects with long lifetimes
and this meant that the new diff-based approach to scan data
made the star ownership and activity reports and long-range
time travel all not work properly.

As the simplest fix, clone the return value of getScan in a
new getScanClone entry point and verify that everything is
now "working"; and it is working, it's just really slow.

commit deba4a8648139fa61d2d1089ce348e8cc8e4bb31

Patch based time machine v2.

In this version, only patches are saved to the database and the
database is validated at load time and rebuilt if necessary. The
rebuild is quite costly on big games like the 64p game, but on
normal size games it is not really a problem.

This sets the stage for receiving diffs from the server side, which
will be in the same format and require much less bandwidth to sync
not to mention the already huge RAM savings.

This was quite tricky to get working so it may be a few days to get
it out to real alpha users, let alone stable.

commit 5900d1de54867ee41b6fe115e96dac6035eb98c7

First version of patch based time machine.

With Rob's help, implemented two versions of patching and
used the object based one as the basis of a time machine
that no longer stores full states except for the endpoints
of each block of API data. The code now needs dramatically
less RAM and performance is OK except at initial load time
when all the patches get computed.

commit 62da53f7c1da62b923055c0b8b77fa9f74297ef9

Build column list once to ensure it is consistent.

The order of the keys in the map and the player indices
is not consistent; doing it this way keeps the footer and
column headers aligned.

commit 4e58b46f15c0602509006f503557e43d03ec5fcd

First version of diff/patch for incremental scan storage.

An almost generic diff/patch that can make one object into another
by recording the minimal diffs between them. diff(obj1, objj2)
produces the required patch input, and patch(obj1, p)  takes obj1
to obj2.

commit 1a6c61721c70c71d9adef5bbc8a37c49f85d21b7

Make format format test code, too.

commit 045153d1980b248d665d5c8358f01158889a46df

The beginnings of efficiency for the time machine.

The strings of game state alone can add up to about 1G of RAM
in the client, and the parsed game states in that case were 700M,
both just too much RAM enough it runs fine on today's crazy
powerful devices.

Try out an object prototyping approach which ultimately turned
out to be a failure, saving not nearly enough RAM and costing
a ton of execution time. A diff/patch system that can only move
from one game state to an adjacent one is going to be the clear
winner because that's how we navigate game state anyway and the
diffs/patches are dramatically smaller than the entire game state,
often just a timestamp.

commit 0eb59a54eb94d2e32bc0c84ce258eaac2b7e6448

Remove hacks for unread state to focus on the new approach.

commit e82c5209c175cda5ae207d38fc8de930e54700c3

A brainwave on message read state - don't cache unreads.

The big issue with the message indexing/caching is that it
triggers the server side to mark threads read when the user
hasn't read them yet. I really wanted to know all the information
for API key surfacing and search purposes all the time, but
the set of hacks and fixes to try to get the unread state
to be correct just kept building up and up.

Finally the brainwave: if the issue is unread threads getting
marked read without user action, simply don't add those to the
cache until the user _reads_ them. It even makes a sort of sense
that NPA shouldn't show you information from threads you haven't
even opened, and of course the expectation is that everyone will
open every thread over the course of the game so all the useful
information will eventually wind up in cache. And it seems to me
that this guarantees correctness and will enable removal of all
the prior hacks.

Time to test it out and see...

commit 2a68a47ce899348206f5adb3d1b118ccf90629d4

Another fix for inbox redisplay

commit ea120ce6ad324ad078da64862eb3b3ffe672b425

Another partial fix for message unread state.

Choose to show the unread state from the DB instead of the
server all the time, if it is unread in the DB.

commit 006cec425e9d9d6b0f247438d0eccfaf04d14964

Fix allied defense weapons tech.

When allies are defending a star, use the maximum weapons tech
for defence, not the weapons of the star owner.

commit 9e5fdb47534567fa5cf461dd127725d9d831696e

Another piece of the puzzle for unread messages.

The inbox changes the type of to_puids and then calling it
repeatedly throws an exception. Restore it each time so that
it will now continue to see messages as unread instead of

commit 728acd53087c0a373f70f984ea9b7b487f94c17d

Implement Gingey's suggestion for faster time travel.

Gingey suggested it would be great to be able to move back and forth
multiple ticks at once, or to be able to jump to a specific tick.

Added hotkeys control-m and control-/ (these are on either side of
the < and > keys which correspond to control-, and control-.  for
moving the time machine one tick) as "fast" movement, which move
you an entire cycle's worth of ticks in one keystroke (typically
24 or 20 ticks at once).

Also linkify everywhere a time appears in the UI so that you can
click that time and it will immediately warp you to that tick. Great
for jumping to a specific spot in the star ownership report or
activity report. Eventually when forwards time travel is implemented,
will also be good for jumping forward to next production or to a
research complete tick to view the galaxy with the production or
research applied. But that's a dream for another day.

commit 70c08e1999a320a0332a9002dbbeb8b2870fc8d3

Add buying tech options to the economists' report.

As per BelSon's feature reqeust on the forum, add rows for buying
the tech instead of researching it yourself in time.

commit 08cd703c0d0911c922fe5d0b3730c3cb5d9d683a

Formal alliances were not crediting the right person.

When you were the initiator of an alliance the balance was correct
but if you were the recipient of the alliance it would show you
owing yourself cash. Fixed it to debit/credit the right player.

commit 5fbe5e403668663ac85ea09a321d63556e26dfe5

Avoid subscribing to the same API key twice.

If getServerScans() was called twice for the same key - as it is
routinely for the user's own current key - recognize that and avoid
listening to the database a second time.

commit 8b29bf95d3cc3070db1af31a6bd580817bcf214d

If the galaxy is already loaded, record the true tick.

In the previous implementation there was a race condition where
the time wouldn't get set if the universe was loaded before the
extension hooked the event. Now check for that and initialize in
either case so that the Tick indicator in the HUD is always correct
and reports that rely on it like star ownership are populated.


Version 2.2.16 is now up for firefox, iOS and on the Chrome Web Store. As usual it may take about 24h to update in Chrome.

The two main features added in this release are filtering for all reports screens and autoruler combat HUD enhancements.

Filtering comes from a great FR from @Gingey that the accounting screen be filterable. At the top of every report screen there is a ‘Filter’ text field and as you type into it the underlying report will be filtered down to show you lines with the words you’ve typed.

For the autoruler, it is now aware of both range restrictions and formal alliances, and it will automatically show you potential combat outcomes at the destination star. For example:

In the example shown, the 9 hotkey has been used to add two potential attack vectors, and both are in range for a potential attack. The HUD shows the maximum attack that could land, includes the 720 possible additional defenders, and shows how many land or live depending on whether the defending star wins or loses.

In another example, here is a system where there is unknown info:

In this case two other features are shown: when there is unknown info, the conclusion is marked with a question mark; and when a star is out of range, the number of range upgrades needed is shown and the arrow is greyed out and not considered for combat.

The hope is that these features make the autoruler even more useful for figuring out attack and defence scenarios, especially in combination with 8 and 9 to dial the considered stars up and down and look at various scenarios.

In addition to the above features, there is a formal alliances report that shows the last tick when you observed two enemy empires on the same star, thus confirming a formal alliance between them. It is not yet aware of declarations of war.

The combat HUD for fleets was off by one round for the flip calculation; that is fixed so that the flip shows just enough to have 1 ship survive. In addition it wasn’t calculating FA captures of stars properly, but having the allied parties fight it out if they captured a star jointly; it now recognizes this situation and has them jointly defend for the next round of combat. Finally there was a very nasty bug in the star ownership report which would make it display the wrong ticks if invoked via hotkey instead of via the UI.

commit e6e0cead7fc13433173e26659e7b2fde6e53cea5

Add filtering to all reporting screens.

Use the new filtering support to filter every reporting screen
if the user types in a query string into the filter box.

commit ffb1f30b2769f414e14d144ebf1dbf8700190d4f

Create a general filtering mechanism for all reports.

Change reports to be defined in terms of "stanzas" and "lines". A
report is now an array of either individual strings or subarrays
of strings called "Stanzas", and filtering works by always including
all the top level strings but including or excluding entire stanzas
based on whether or not any line in the stanza passes the applied

This means, for example,that you can have a top level structure to
define a table (for the accounting ledger for example) but the rows
of that table are isolated into stanzas so that they can be filtered.

In addition, you can have a lengthy multi-line result like in the
long fleet report, and filter out only those that relate to a star,
player, or specific string (like "Combat!") to then see the subset
of the report you're actually interested in.

Implement the filtered combat reports on top of this new structure
and pull the mechanism out into its own unit tested file for
documentation purposes. Next up, adding a UI to let the user custom
filter any report they are looking at.

commit 66591485d10a1989e5ab58f16a2238b784e78ace

Use raw distance for range requirements in autoruler.

Don't use the warped distance, because that makes the autoruler
think stars are in range that players can't reach just due to the
warp gates.

commit f4159b7dca3675c07dcf5c1f68b9e3fea71f153a

Set defenderWS correctly from the star.

Instead of relying on defending stars to figure out the weapons,
ensure that the selected star also participates! As at a minimum
the garrison there sets the weapons.

commit 76f3fd4f5a774c3ddc3b2cc8473a7b369c6cf52e

Add a combat projection to the autoruler.

For those arrows the user has decided are in scope, project
an all out combat outcome and show the result to the right of
the star's selection ring.

commit f8e69154a0e2d1c85c3e8e6e491a880f670fca41

Update autoruler to be range aware.

When you see autoruler vectors, grey out those which represent
out of range travel and indicate the range research required to
be in range. Respect the handicap, so if you grant range to people
out of range vectors will become in range.

commit 824f3def6c65f6b554cfffde44b17c30cc58ad0e

Update formal alliances to know the most recent tick.

In preparation for being able to process declarations of war (which
the code still doesn't do as I don't have a ready exmaple of it
yet) the knownAlliances are recorded with the tick # of the most
recent observed allied activity. So now, if someone declared war
_after_ that, the end of the alliance can be known and used to clear
out the alliance to enable correct calculations.

Also updated the autoruler to take allies into account, making it
more useful for seeing real attack vectors and enabling you to
consider your allies as possible defense vectors.

commit 42c16a9192daaf91d16f3b6959b1d46ee1160abd

Remove the handcoded clone in favour of the generic version.

The generic version might be a tiny bit slower but it is much
less error prone than the handcoded scan clone.

commit f23fae0d41f85baca2a766e9409a36f4dd286f8f

A first cut of formal alliance detection.

This doesn't yet take into account declarations of war, but
merely assumes any players who have ever shared a star are
in a formal alliance. The combat calculator then correctly
accounts for their fleets.

commit bdd353ab1012f469017f98969f630a82691322b8

Fix an off-by-one-round error in the required flip calculation.

For both defense and attack, the calculation provided an entire
round's worth of buffer needlessly. Change it so that the flip
combat is just one more ship than required.

commit 29f3082e4ab656ba96af6dda5d82d592a0adbea4

Rename diff2/patch2/Patch2 to diff/patch/Patch.

Now that the old implementation is gone, use sensible names
for the "new" version.

commit c7aed6d650d31b204eb7a375d5fd68e568b74b23

Remove unused original diff/patch implementation.

Having the old version there kept causing me to write incorrect
tests that mixed the two approaches. Remove the obsolete code.

commit 93e66c2b29142a012114852c89380c11b6bd90ad

Fix a nasty bug in the star report caused by corrupt diffs.

The new diff code has a flaw where if either the source object
of the diff or the patched result of a diff are modified, that
could corrupt the diff itself, making repeated diffs produce
incorrect answers. This shows up in the ownership report which
is executed twice due to a different bug with hotkey implementation
and the second execution gets the wrong result, so that the
star report is only reliable if chosen from the GUI dropdown
after a reload.

Add tests for the problem in diff2/patch2, fix the underlying
problem, and fix an object aliasing issue in the star report.

commit 9e7f7f0ba0f0c993802ff62227a6fbf938d0136b

Update the combat calculator for multi-round FA combat.

If multiple players from a formal alliance landed at once,
defeating an enemy system, the code would then have them
fight it out as usual without realizing that they are allies.

Now, the system is credited to the FA's biggest contributor,
and all incoming FA fleets are added to the star's total
defenses, and combat will continue if any offense remains.

Possibly/probably there will be a bug in cases where the FA
wins initially but then loses to an incoming FA. It's a hard
situation to manufacture.

commit 3c3e69b9e5d7d532724b0d0340f7082be742a200

A heap data structure to be used for priority queues.


v2.2.20 is now available. This release contains a two bug fixes that attempt to make the userscript more reliable on iOS, hopefully fixing a load-time race condition and a load-time repeated crash. In addition, the territory display has been made more efficient reducing jank significantly on large displays, and the star ownership report runs a bit faster to make it easier to work with in 64p games.

Feature wise, this release contains two hopefully significant new reports: a trading report and a combat report. Each of these reports is meant to make it quicker and easier to determine who is trading with who and who is fighting with who, especially in early game stages.

The trading report looks like this:

Each line begins with a clickable timestamp to take you back to the relevant point in time in the time machine, then lists the recipient of the tech, and finally lists the icons of every empire that could have sent that recipient that technology. In a trade scanned game, this knows about the rules and will only show candidates who had the destination player in range on the historical tick in question. In order to do all this, the report needs your historical game data, and the easiest thing to do is to generate your API key before or at game start so that you have the history gathered. The report is conservative and will not show a player acquiring tech on production, so if other players are extremely prompt trading (within 15 minutes of production) a trade could be missed; but by and large this report captures trade acrivity and makes it pretty easy to see who is trading with who.

Similarly, for probable combat activity, the report looks like this:

Here we see several examples: on some lines, just one player has lost ships that tick and it isn’t clear against whom they suicided – this happens when a tiny exploration fleet encounters defence in early ticks of the game. On other ticks, exactly two players have lost ships and it seems most likely that it was player A vs player B, though it could also be twin suicides. Finally, on some ticks multiple players lose ships and you’d need to go look at the tick if you really wanted to be sure what was happening. As with all times, once again the tick #s are clickable to rewind the game state to that moment in time so that you can see what was happening, or check the pre-existing star report to see who lost a star on the relevant tick #.

All of these reports: combat activity, trade activity, star ownership, and activity, rely on having historical game state and can only report accurately since you started collecting it (which means when you generated your API key). I hope you find them as time saving as I do!

commit f262b706b41e6aa2700f0133bad857add2d0a3e6

Detect and defer event handling to prevent race on iOS.

commit 6b8ab03a4f3f13c0d392b84b9733f5add7a0cf51

Force long polling for Safari to reduce RAM usage.

commit b986f66dc107dc0ef5f4cef07f222a3de8f1134b

New combat activity report enables spotting conflict with precision.

commit 606a9841c06a8d3eb7843989e186cb3b0bc873e1

New trade activity report enables spotting tech transfers.

commit 79bdd7ccf84dd0eb4413cbc36469eb3530f71089

Got distracted speeding up the ownership report.

The ownership report felt really laggy on the 64p game in combination
with filtering. Make the report itself require 50-100ms but ultimately
it is still laggy if you generate a giant report with thousands of
lines. It's probably good enough for now and long term fixes would
be to optimize Crus.format or to automatically truncate or filter
huge reports (e.g. by showing only the last 100 ticks).

commit b18bbadc5d7e10249a814a2c9a08c071c54799bb

Avoid drawing territory that isn't even on the screen.

For large galaxies, maybe it will make performance slightly better
to draw star discs that might be visible to the user and avoid
drawing the rest. This too doesn't seem to result in a perceptible
performance difference but doesn't seem like it can hurt performance.

commit 4954b20c17ac0a6746bfe2f29cfb2e5d3ddd22db

Star territory performance fix #1: don't recreate the canvas.

In the original code, canvas elements were being created on demand
during the requestAnimationFrame callback, and this was causing a
lot of jank. Change it to have one globally allocated canvas that
gets re-used, which seems to eliminate almost all of the drawing


Well αλφα users, it’s been a rough ride but I hope it’s been worth it. I believe that the bugs are starting to settle and the time machine and enabled reports hopefully make the bumpy ride worth it.

The latest issue in αλφα is that the new database code could sometimes lose a record. This update fixes the only way I could find for that to happen as well as puts in a sanity check on the event log if you review your event log manually in the UI.

This release also adds a new “Empires” report which presents empire stats in an easier to consume way than paging through all the empires one by one. All tables are now sortable, so you can click on a column, for example ships/h, and see who is doing best in that category:

It makes for a better leaderboard than the leaderboard, because you can easily focus on whatever dimension you feel is more important at the moment; and at a glance you can see how you’re doing by the prevalence of red and green. The empires report also shows you a table of just your own alliance members aggregated. Alliances are still determined solely by API key merging.

commit 4f555a9d93602152fea573144d3cbf710a4f4309

Add data validation of event cache when the user views events.

Though hopefully the previous fix made it so that the event db
can't be corrupted, since we've now seen corruption in the wild
make it so that when the user views events there is a sanity
check on the database and a forced restore if a record is missing.

Some kind of server side logging will probably be needed for
αλφα Edition users so that occurrences of this problem can be
metered to prove that it is either fixed or that people are
hitting the restore case.

commit 4bdf6fcf6de6ed6f81523b111a7797b54c11d1cf

Make filtering pick up shape icons for aliases.

Now if you type someone's alias but they only appear in the
output as their icon (as happens in trading activity and
combat activity) the rows with their icon will still be
found and shown.

commit 983dda335609113e39cdae5d21115eb06e0c04d9

Move in memory append to after successful store.

One of the few ways I could see that it is possible to lose
a record in event storage is if the store request fails once
and then starts succeeding, causing the in memory store to
know about the unpersisted record and then skip over it forever
for future storage.

This change alters the order of operations so that if the persistent
storage fails, it won't be cached in RAM which will force it to
reattempt download and storage of the event.

commit efe5e4d40d814192ba55694d581fbcea2410bd99

Add sorting to all NPA tables.

If you click on a header, the table will be sorted by that
column. Repeated clicking will cycle between ascending, descending,
and original order.

commit 651b75eaed95a08e2caa86836fe6a2a11c2fcb3e

Row based version of empires report.

commit 1c201e6664a03e97e965ce8379e70b11a4641b4b

First version of the empire report modeled after tech.

This version turns out to be no good. There's no nice way
to sort and get a leaderboard style view, no nice place to
put allied sums to get an alliance v alliance view.

Fundamentally modeling this report after tech was wrong,
instead it should be one row per player and columns for
each stat. Checking it in just because I hate deleting


v2.2.22 is just a few bug fixes, plus a new menu.

The new menu is adjacent to the main NP menu, and contains all the reports as well as their hotkeys in the hopes that they are both more discoverable and easier to access on mobile devices.

@BelSon reported a nasty bug where if you had generated an API key but never shared it with anyone, the time machine couldn’t find your data. Fixed it so that it will, and also changed it so that it sends a message to yourself with the API key so that the API key will also be found if you use multiple browsers/devices.

Fixed a long-standing bug where if an abandoned star had fleets departing it, the entire combat HUD would be disabled.

Fixed the built-in filtered reports, which were broken by a recent change to add user-driven filtering.

commit 4c422b6ac5e51474df68cb3d435c53e9e34f3976

Automatically send a message with new API key.

Each time the user generates an API key, send yourself a message
with the API key so that it is findable by the code on other clients,
as well as known in case you regenerate it.

This fixes the edge case in the prior change by making it that
all keys are in your messages and repeatedly generating your key
won't cause the time machine to lose it.

commit 636898cb33bc13032c2894f5f74d8a157387ff41

Make time machine work when you've not shared your key.

A bug in prior versions relied on the idea that you would have
mailed your key to yourself for reference or to another player
to share, and if neither of those things had happened the time
machine would fail to pick up your scan data.

Change it so that any key you have merged is also in the list
of keys, and since generating a key merges it, the case where
you've never shared your key works.

This does still leave a bad edge case where you generate a key,
never share it, and then for some reason regenerate it. In that
case the older key data will no longer be found. I'll fix that
in a follow-up.

commit ae5517e5b3dedb6a6ee2101bf776bfb91aec7be1

Make star weapons robust for abandoned stars.

commit 13838f1989f0e0cb45a54f4e108e4a3e40369397

Fix the built in filtering for case and translation.

When I made search operate on formatted text and be case
insensitive, I failed to change the built-in searches to
account for that and broke the built in all combats and
filtered fleet searches. This makes those reports work

commit fc00ad3c37c459feb5dcd512921cd72b16740297

First version of menu access for NPA.

In an attempt to make the NPA functionality more discoverable and
the hotkeys more memorable, add a top level menu that lists all the
reports and their hotkeys. The top level menu itself can be invoked
with the 'm' hotkey, and if it is up, any menu item hotkey will
both execute and display the relevant report.

Thanks to Rob for proposing this FR.


Thanks for fixing that time machine bug!

Also the menu looks great, makes things a lot easier to access. Only problem I’m having is it auto-opens upon game loading.

v2.2.24 is dedicated to improving the stability of NPA.

The main thing added is that stack traces will now be recorded on the server so that if users are encountering bugs I can much more quickly diagnose and fix them. The only information other than the stack trace that is logged is the game id, so that if you report a bug to me and tell me the game id I can find your stack trace. The stack trace itself should not contain any identifying information.

The menu no longer pops down at startup.

Also, I had recently introduced a battle calculator bug where if a star changed hands the new defenders would get the old defenders’ weapon strength. Fixed it to recalculate weapons at the star based on the new owner and their allies.

Added a notifications key to API key recording to enable server-side notifications. If you are interested in pre-alpha testing notifications, send me a PM.

commit a6df2f1a9f26f87266fe7a1ae6237156244c4c88

Add server-side logging of stack traces.

Log stack traces for unhandled exceptions so that it's possible
to follow up on failures in production. The stack traces contain
the game id but no other identifying information.

commit d28912feeada1529b380ffe436fb6ece282ac242

Add a test for patching fleet orders.

commit 07142abe407592bc680edf52bc5bbc38eb70d78f

Fix a star's weapons level to change when it changes hands.

In the previous commit to handle allied fleet weapons, the star
held on to weapons state even if it was taken over by an incoming
alliance. Fix it so that if the star changes hands, its weapons
level is computed as the max of the new owner and their allied
fleets in attendance.

commit f16c5baa1d87cceb2efb40816640e7242886944d

Move 'onPopDown()' bug fix so that npaMenu is defined.

commit 21bf007bd3a127697260eb632f635cd2318214ee

Correct patch type to include 'null'.

commit 2132a1227500481b3143529b56303b3c88b0419a

Two small bug fixes.

First one is to avoid dereferencing the menu if it isn't
initialized yet which avoids some race condition I've
forgotten the details of.

The second is to never report needing only 0 ships to flip
the outcome of battle for the autoruler HUD.

commit 1b1ae7dcd5a4191033d91c97ef6434239681f80a

Pop down the side menu at initialization time.

It looks like in the main code the onRefreshInterface puts the
menu in the right state perhaps; while the NPA side menu starts
open when created the same way. Pop it down so that it isn't
open on every page reload.


Unmoved carrier warning: in turn-based games It would be interesting to have this or a button to cycle on carriers without orders to move
(I forgot a bunch of carriers in a friendly star of a player that I have formal alliance with)

It isn’t technically a button, but it is fairly easily accessible in the game. If you go to galaxy → carriers, and then sort by number of waypoints, you can bring all carriers with 0 waypoints to the top of the list, and from there give them orders. Not sure what an extension would be able to do that that can’t?

Unless you are talking about a warning that comes up when submitting: WARNING! YOU STILL HAVE CARRIERS WITHOUT SUFFICIENT ORDERS! In that case, maybe the warning should come up if you have any carriers with a total ETA less than the turn jump, so that no carriers are ever idle? But still, it’s easy enough to tell this by going to the carrier list and sorting by total ETA.

And if that warning was implemented, I’d like to see an option to remove the warning for looping carriers with total ETA less than the turn jump. Because oftentimes I’d already have them set, and the loop means it won’t stop doing what it’s doing at the end of the order list.

You can also use the hotkey ‘f’ to bring up the same page.

@BelSon @AStonedApe I overlooked that screen, that totally helps, thank you both.

It’s been a while since I posted an update because I’ve been trying to focus on just fixing errors since v2.2.24 with the intention of taking the time machine to stable channel. I just love being able to use the time machine to determine what happened when, who is trading with who, and so on and I believe the current version has become quite stable.

But recently on discord someone asked for configurable alliances and this has been on my TODO list for a long time. So now you can type ctrl+a to bring up the “Colours and Shapes” screen:

On this screen, you can configure every single player’s colour and shape to whatever you like so that you can easily distinguish particular players or group players according to who you think is allied. These changes appear on the map instantly and affect the empires report, which will now show you separate summaries for each alliance so that you can more easily compare aggregate stats like ships/h, science, and star count across the factions in your game.

The settings are persisted on a per game basis.

Another feature in this version is the ability to capture screenshots directly to IBB if you want to send someone a message with what’s currently on your screen. Pressing the screenshot button will do it right from message compose, or will take you to the settings screen if your IBB API key is unknown. Generate an API key on and put it in the field in settings for quick and easy screenshots right to messaging.

Also, the x hotkey now creates a fake enemy fleet for you to route and displays who you are acting as in the lower right of the map near the version number. Select an enemy star, press x to give yourself a fleet there, and then control as if you were the other player setting up an attack on your own systems to see the battle calc’s predictions and plan for invasions.

Aside from those things, this version mainly contains a variety of bug fixes.The biggest of these is due to @Skilly146 reporting inaccurate economists – the report was no longer correctly computing the impact of terraforming! So Banking was always looking better. Banking is good for much longer than most people think, but certainly not forever :open_mouth:

commit 45a369c895132e30d5c94f6f9b8d592024f35de4

Include an all surviving empires leaderboard.

commit ba2c772ccade399fe17b49361d662cb13eec645b

Make the empires report use color or shape to group allies.

Now that you can set the colours and shapes of every player in the
game, make the empires report respect the way you want to determine
who is allied and break up the tables into sub-tables by alliance.

commit c7e70fb45f03d35d7295a439b6b6f58fe6e2fa41

Fix the reset button to work in both cases.

Reset would only reset the colour/shape if the colour had been
modified; make it work if either one is modified.

commit 5101dc82882c65931ea39abf6adfd08c98dae1b3

Move recoloring to a spot that isn't an infinite loop.

Oops :)

commit 23673708b9ff3e51820ea53230f9d8829b11c581

Rework the UI and persist the state changes.

Change the UI to use the icon font for shapes, which looks
nicer, and persist shape and colour changes.

commit 6ccba17ca2580dd229f1b8a884d6c5ebf7f1b0de

A first cut of shape & colour setting UI.

This version doesn't persist anything but does barely work to
let the user reset the colours and shapes of every player.
Committing it so that I can take a second pass at the shape
selection UI without losing a working example.

commit 30cb029fc8481c71cb1010ff8b78c761fd79afcd

Move custom colours into a setting, fix route enemy help.

Move the custom colours into their own setting to prepare for
allowing the user to configure colours for every player in the
game. While I was at it, noticed the help being broken for
route enemy (as well as the control button) and fixed it to
have a better help string and a reasonable button name.

commit ac46c0186f8ad3065115f4cfc082113673e3f124

Change approach for alliance definition/coloring.

Instead of deciding what colour someone is based on what alliance
they are in, set it up so that the user will be able to configure
colours and shapes for every player as an orthogonal feature.

Then, we can provide alliance modes that decide who's allied based
on them sharing either a common symbol or a common colour at the
user's option, and the user doesn't have to use alliance inferences
at all if they don't want to. So the alliance mode will be "group
by colour", "group by symbol", or "don't assume alliances", and the
default will be "group by colour". Setting two players to the same
colour will then make them allied as far as the rest of the reports
are concerned, starting first and foremost with the empires report.

commit b4bc314f5df6d36e15a43be0f3bd5c3987874d91

The beginnings of manual alliance grouping/coloring.

commit 00a1d9e1d54380c35576911654b4995625f94bc2


commit b0f430438e9f972973910af35fe0512267ddcb04

Hack around typescript errors in the generic settings.

commit 115ed8350710c32764ec5a23b6d2951ae4e24166


commit 13ccac21901b367e723152365a3e26d4fb854076

Fix economists report based on @Skilly146's bug report.

Most embarrassingly, it looks like when I refactored the code
to include @BelSon's FR for the buy vs trade for terra I broke
the output table and didn't include terra in the analysis of
what you can buy after production, making banking always look

Banking is still better a surprising amount of the time, but not

commit 95a0ecbd251e0e21fd7ba7ea9f34814961593627

Couldn't remember why I changed clipboard setting.

Originally, if you ever viewed a report using the UI, it would
be set as the 'lastClip' and put on the clipboard. I couldn't
remember why I changed this to not copy by default, and it
wreaks havoc with async report generation. For now, make things
go to both places again so that I can see what the problem was.

Also gut the example test for hotkey.ts because I couldn't be
bothered how to deal with the navigator call and there are now
better (real) test examples in the codebase, for example patch.ts
and patch.spec.ts.

commit 9eaf6f289d7b1206408fe27b4858803be891aeee

player.colourBox is spelled differently in proteus.

commit 6257a0e364ccf01c3ac86c334b982bfc238bb8c4

Add screenshot functionality for users of

You can create an account to host screenshots and get
an API key from them. Putting your API key into NPA's settings
allows the extension to upload your current map view as a screenshot
for sharing with your allies.

This involved a fairly big overhaul of the settings to have types
and allowed values and a generic form for setting all of them. It
mostly works; it struggles with editing the text fields but
otherwise seems OK. It's good enough to be getting on with even if
not ideal.

commit fe597a2494b92d4a73b1bb4b51cead5fb3062327

On firefox, reportSelector is sometimes not initialized.

When this check executes, don't try to dereference reportSelector
if it is null.

commit 25bbb87a722c0c2caef66c411622808b06b37566

Finally get all cases for war and peace.

In the formal alliances report, capture agreed peace, observed
peace, declared war, and war, so that the battle calc will respect
the war state when returned to after a period of peace. This gets
all the cases: there is no need to 'observe war' because war is
the default and must be formally declared after peace.

The only edge case is if two players are at peace and you never
observe it: you cannot then know when they were at peace if they
first declare war.

commit 395d22a4a3ee0b44beb912074fc1ff9eeea731cb

Setting ouid is required for proteus fleets.

commit 5f2ad682a57046bb7ee6ab57542edfae21a9e00f

Make a distinction between who you're controlling and you.

When using 'x' to control enemy fleets, note that in the lower
right of the HUD with the text 'controlling <alias>'; and if
you're viewing as someone else, don't lose that info. So you can
view as player a and control player b and see A controlling B as
the indication of the unreal state you are in.

commit be6a78d09c8a6d50e2bef1bab283ed1c81cb762c

Fix research figures for Proteus.

In triton the research is brr*level, but in Proteus it's brr*level^3.
Redo calculations for Proteus so that correct numbers are shown for
ETA and science upgrade impact.

commit 1aedc5e53acc48f1c54c6e2b32bef6449bcb9441

Add an x hotkey for fake fleet orders.

If you select an enemy fleet you can now press 'x' to give it
new orders in order to explore scenarios in the battle calculator.

If you select an enemy star, a fake fleet will be created there
for you to direct.

Reload when you're done to reset the game data.

commit 52a86212953ac5e97d5d0d9e1ba4fe88d5fd71c4

Omit star report sections where no stars are visible.

Change visibility rules to work well for proteus, and while I
was at it make the star report not show empty headings for players
where you can't see any of their stars.

commit 49883a06fcae72069619d56ad263679ec5ece46a

Avoid a null pointer exception when the table can't be found.

If we're trying to sort a table that is no longer in the markup,
bail out instead.

commit d534346563d4e4dd4e83e1213534779cd9f6cc86

Partial fix for declaring war.

When you are one of the parties who was involved in the allied fleet
detection, you can use the warmap to be sure you're at war or not
without having to review the event log to know. Make the allied
fleet detection take this into account so that if you're at war,
that is correctly noted before the faReport data are used to decide
you're allied because you once shared a star.

Really the alliance detection also needs to watch the event log to
fix this properly.

commit cd50b511e73f9cd5651c775764310049d2053b22

Modify event overlap to account for ordering problem.

Frustratingly it turns out that if the timestamps on events are
identical, they aren't _always_ returned in the same order from
indexedDB and so they don't _always_ overlap in exactly the same

Two possible fixes: either make the writes accept the idea that
duplicate records can happen (which would be harmless) or detect
out of order records with identical timestamps. For now I went with
the second as I like the tight constraint that exactly the correct
records are written to the db. This might be wrong, though, as we've
also seen cases of missing records rarely which could possibly be
caused by a similar ordering problem if the server isn't guaranteed
to send us all the events with the identical timestamp at the same
time. So in fact a fix that favours robustness might be better.
Something to worry about.

commit fe22bc59437a776b6a285b72f4d3d0560b329a3b

Modify the star report to be easier to filter.

Put the empire's shape icon on every star line so that you can
type the owner's name in the filter and generate a report of just
their stars trivially.

commit 5348dc84c6e17816c3376e3a314fd17cd731ac09

Hopefully make scan key iterators more robust.

commit ca83d408763cfd41b1bc9ef6ab9e1d81f473bd6d

When the bubbles context is missing, don't draw them.

For reasons that are unclear, it is possible to fail to get the
correct graphics context for territory bubbles sometimes. Don't
attempt to draw them when that happens.

commit f74b7634cc3c6a37e4a83402cef0b4d5454b0bdf

For a fleet whose destination is unknown, don't throw.

It is possible for the user to select a fleet for which a battle
outcome couldn't be calculated, and this would throw a harmless
exception trying to read the eta string. Don't throw it but avoid
it instead, to clean up the server side logging of same.

commit 0cde139a840ba4c95c42a8df03e0384515f8f160

Defend against null pointer in scan iterators.

commit 600fd67c68d99590f4eaaa1430de4050a9e51136

Record source map as part of the build process.

To make it easy to map production stack traces back to source,
record the source map each time a production build is done and
put it next to the zip files as intel.{version}.map.

Then you can

npm install -g source-map-cli

and get convenient output like:

$ source-map resolve 2 257317
Maps to webpack://neptunes-pride-agent/src/scans.ts:73:24 (getScanData)

        return h.peek().getScanData();

commit 774e2a63688dc27cd7c913fb16f21ea98cf77116

Defend against a race condition initializing proteus colours.

The colorMap could sometimes still be uninitialized when loading
proteus for the first time, leading to an uncaught exception in
recordTrueTick. Defend against this and ensure the colorMap is
initialized correctly when these events happen out of the usual

commit 8af2e3222173b154c7d967d88ad7f6d5a30e5005

Defend against a star not being a star.

The base game code has a bug when using the ruler that when the
user selects a fleet it sets universe.selectedStar to the fleet
instead of setting universe.selectedFleet, most likely because
using the ruler from fleets was a feature added in after the code
was initially written.

The autoruler assumed that the selectedStar was really a star and
was throwing (harmless) uncaught exceptions in this case. Fix it
to detect this case and avoid it.

commit 8ecda6190647e32301f0898fe09bf291436f6b92

Fix the map of undefined keys stacktrace in faReport.

Since I always seem to have some API keys I have seldom personally
seen one of the most commonly occurring stack traces in the wild: an
attempt to map over all API keys for the faReport.

Fix it so that the code doesn't execute if there are no API keys to
look at, as well as don't bother to execute it if FAs aren't even
enabled for the game.

commit b71374a07255567b32d1ded097fc283c3fa4e106

Make range bubbles accurate for proteus again.

In a previous change where I refactored the range bubbles I had
hardcoded the lyToMap ratio which is different in proteus. Range
tech itself also seems different; change the computation to be
robust for proteus (at least the territory display and the in-game
sprite match up).

commit 661786ecc9b16ac352bf365753463e24b54ecdf3

Add version, timestamp, and promise rejection info to logs.

Promise rejections had no info in them, and lacking timestamps
it was difficult to sort through the thousands of logs to figure
out the most recent ones. Add version and timestamp to make the
data significantly more usable.

commit fadd60907e53f7f907b9063074450ceacf2c4e68

Defend against a rare stacktrace.

commit aac0b49577d39272b7da9acf25c49ee8dccdce62

Hopefully fix the second most common stack trace.

Defend against the scan cache being empty for a given API key.

commit 717bd63d8d3b1921603d2369f39a645a941db225

Suppress the most common uncaught exception.

The autoruler code would compute defenderWS for unoccupied stars,
triggering an error trying to look up tech for a non-existent

commit 31e0da0c2bdea2c2be8b233e6b4b0424c4cbedef

Defend against undefined player object.

When joining a game, your player object is not yet initialized.
Avoid dereferencing undefined and causing stack traces each time a
user joins a game.

Previous impact: harmless, but HUD text might not fully render.


1 Like

v2.2.43 is now live everywhere.

On Feb 16th or so, I launched v2.2.8 to the αλφα channel which was able to index all your diplomacy messages in order to make finding and merging API keys easier. Diplomacy messages and game events have a similar interface on the game side, and I re-used the code for game events, which are used by the accounting screen in order to display debts for quick payment. Unfortunately this introduced a subtle bug which I still haven’t understood and caused traffic to the game to skyrocket, affecting Jay’s billing. In v2.2.43 the code is reverted to how it was in v2.2.7 so that the bug is gone. To find API keys you need to merge them from the message where they were sent to you once, and thereafter they will appear in the key report.

Also in v2.2.43 (and other versions since I last posted about v2.2.34):

The code is now capable of counting and logging to a server various non-identifying client side events for debugging purposes (e.g. how often an exception is thrown, how often an API call is made, etc).

Custom colours and recolour to white weren’t working at all in proteus; make them work better. In addition, make recolour to white not affect alliance determination so that you can easily pick out your own stars, but still see correct alliance v alliance summaries in the empires report.

The combat calculator was not noticing that industry would get wiped out by conquests in proteus; change it to assume 0 industry if the star has just changed hands. This assumption too is wrong, since the conqueror may build industry, but you can’t know what they might build in advance.

Finally, in proteus it is always trade scanned so make the trading report aware of that.

In the bulk trading screen, one of the two footer rows was sometimes out of order making it hard to do a bulk send of all tech to the right person. Make sure both footer rows are always correct.

The activity report contained an egregious bug where all upgrades were seen as human driven activity. Fix it so that only those upgrades which are surely the user taking action are used. Also, the activity report has been reworked to show info on every player by default, and automatically highlight players who look AFK since the start of the game. This is most useful after the first production cycle has passed because often players won’t upgrade during the first day of play:

The home planets report is no longer put on your clipboard on reload, so you can copy diplomacy messages and reload the whole page if you want. It is more efficient to just click the production countdown to refresh the game, but not everyone knows that.

Fixed notifications configuration so that it is written for only your own keys and not lost, making notifications reliable and not notifying you about your allies’ woes.

commit 94aa5370b1aa859c2b6ac4aff86ae2f57873c870

Revert event fetch code to something like v2.2.7.

Without understanding why this might be the problem, revert the
event fetch code to how it was in v2.2.7 to stop the bleeding on
the server, where events are now being repeatedly and constantly
fetched by some client.

commit 43a05861fab22f412ccf594fee53bd6ae27d8782

Log initialization paths and abbreviate version.

For counts it feels like the full version info is a lot, so
abbreviate it down. Also log initialization paths to get a
sense of how the code loads, and avoid duplicate versions
on exception counts for exceptions with no stack trace.

commit 69d050cda55112cc4bb62ac4ad2352e90140d2b4

Attempt to catch and log document not focused.

commit e9029a10e19b1f5b5adf4b7e3a9d60954f76f97e

Use correct request path for proteus.

commit 4c38a07b4fd1882bea5b54cea2c9bfd53e7e76ba


commit 5ac0fdbd8c1d84239bb299acde27cba0abb7aced

Remove reading/indexing game_diplomacy messages.

In an attempt to narrow down where all the fetch game event traffic
is coming from, remove reading game diplomacy to find API keys. You
can add API keys by merging them as before.

commit 92c0aca3a188e85782c96cee88727af23b8fbd31

Fix custom colors and recolor to white for proteus.

commit 9178c62d412befd33d157c449d72c642e08ba78e

Make caching of scan data more conservative.

In the original code, it didn't wait for the API data to be written
to the cache before returning it, opening up the possibility that
repeated calls would hit the real API endpoint multiple times
needlessly. Though it introduces latency in the client, wait for
this to get written to the database to make that scenario impossible.

Also, refreshScanData was willing to refresh multiple times as it is
async and could be called repeatedly triggering multiple API calls
for the same scan. The actual effect of this was two API calls per
key at load time, one of which was needless. Change it to refuse to
refresh again if it has been called in the last five minutes.

Also, don't hook on_full_universe for refreshScanData as it is
already wired to refresh_interface, so only one was needed.

All of this in the hope of reducing API calls to the server, but
none of these fixes look high impact to me. Still better than it
was even if it doesn't fix the real problem.

commit d347a6f877e437aee09d3b273df01afc860eff59

Fix up footer to use order!

Somehow when I wrote 62da53f7 I only fixed one of the two footers,
so the send all numbers were still in the wrong spots. Fix that
up too.

commit d8e57ef4774e2cc924b39e0c3dbc1119bb8199d7

Log type of message downloaded.

commit d06a791592ab7ef32f31f6e6dbf2c4f98e0bf1a1

Add counters to track API calls.

Suspicious that v2.2.8 started unduly hammering Jay's np servers
with requests, I have added the ability to log arbitrary counts
and am now logging counts of all post requests coming from the
extension so that if there is something spinning out of control
it can be seen in the counters. Counters are per version number.

commit 6bddaa1d5d7b069a1a3fcdf3e59562edf1142f95

Fix an egregious bug in the activity report.

Though the code purportedly checked for tick changes for industry
and science based activity, in fact the dereferenced field was
always undefined so all star captures were showing up as manual
activity on behalf of the player.

Fix it to use the actual tick number and report activity
conservatively as it should.

commit 2cb67ac98466b70dcbe337dfd5e5b1a53a115b5f

Passing undefined in is not allowed for firebase.

When making objects with optional parameters, passing in the name
sets name: undefined and in this case causes new key watches to
fail because firebase won't store undefined. Defend against that.

commit e8b97cbb79381fdaff754b205e5d0d2245dbb288

Defend against people passing undefined as the callback.

Somehow someone is passing undefined as the callback to window.setTimeout
and this is logging uncaught exceptions. Just pass it through when
it happens to avoid the failure.

commit a58594d708c228e687911b7d513827a0bc2e9e04

Redo the activity report.

Redo the activity report to make it easier to spot AFK players and
easier to consume in a tabular format. This doesn't give quite all
the data that are there, only the last 5 actions the player took,
but I think this is 90% of the utility of this form of the report.
Separately an activity histogram per player might be really nice,
but I am not sure if that should be in this report or a new report
of its own.

commit 5e643efc35e6d7b5ee0446868df17b99e07cd145

Remove home planets report at startup.

In order to avoid always clobbering the user's clipboard with a
report they are unlikely to need now that the UI has autocomplete,
don't put the home planets on the clipboard at startup anymore.

This also might have been the source of the zillions of "Document
is not focused" errors.

commit cc4de3b4b3cfecf3957122c559342cf94678d826

Remove server side logging of no stack trace.

For now, remove logging of no stack trace as this seems to be
causing spikes of tens of thousands of "Document is not focused"
with no helpful debugging info.

commit e7bdf5675bfc16f839866d29dfb579e4c9691702

Fix tradeScanned for proteus.

In proteus the game is always "tradeScanned" so the gameConfig
doesn't reflect the setting as it can't be unset, but the extension
was relying on the setting to know the case. Isolate this into
a helper function that checks both conditions so that the trading
report is accurate.

commit f45f578c7079b587ec8371b0fb0a02b874180642

Modify empires report to use a new 'footer' feature.

Add [[footer:label]] so that tables can still sort and format
properly when emailed, and use it in the empires report.

commit 933e9d210ebc1e1710255cae7f7d0e4e68ae2bdd

Make alliance matching play well with recolor to white.

If the current player has temporarily set their colour to white,
use their configured colour for alliance matching so that they
still show up in their own alliance.

commit b5b996080aaa74928964f9ffe0979c2e2c777ac1

Write notifications configuration only on key creation.

Previously the code would associate the user with all the keys
they might be watching in preparation for notifications from API
data changes. Make it set this up only for keys you generate, which
makes more sense I think (rather than getting notified for every
user whose key you have).

The server side is currently discarding this information, too.

commit d17ea6150818f41fc761ede772b33d277e3daacf

Make sure the store is initialized before init.

In the common outcome of the load race condition in production,
the store is not yet initialized when init gets called, making
the recolour feature inoperable in production. Initialize store
earlier so that no matter what the outcome of the race it is
ready when init is called.


v2.2.50 is now live for firefox and iOS, and in review for Chrome (should auto update in about 24-48h).

Since v2.2.43 the highlights are a new alliance summary in the empires screen, a new alliance research table, a new communal economy report, and the ability to share colour schemes with other players. Many thanks to Rob for contributing the new alliance research table which makes it easy to see at a glance if your alliance is researching the right techs and who rolled what with exp.


commit e32936a8e5e7f10445286e50864a26bbf7cf4f84

Add the ability to share colour schemes.

If you visit the colors & shapes screen, put a button on the
clipboard that can be mailed to other players to let them
import your colour scheme.

commit c740675631e1b61cfcdd505fff25c0868d41b3d8

Show both research priorities if they are the same.

commit 8f05afeb0a4bb872324ce89296df14aca09549b8

Simplify all alliance research report.

Show best tech level in table headers. Only show empire level if it's
not at the best level. Also show first and second research priority.

commit b14224a323eb9ac8a911f747b6e714a392b179ba

Add the new communal economy report.

The economists would like to convince your alliance that since money
transfers are free, it's better to build the cheapest economy
communally across the alliance and split the cash after production
rather than have each member ramp their economy individually. In
this way, the exponential growth will ensure the alliance is rolling
in it sooner.

Of course, this just requires a little trust.

The new economists report tells you how to rebalance cash for econ
buys and outputs a table of who buys econ on what stars.

It adds three new [[ ]] expansions, one to show a player's cash,
one to enabling transferring them the right amount of cash, and one
to enable a bulk upgrade button for upgrading stars.

It adds a new feature to merging scan data where player data are
now merged into the main view and so it is easier to get information
about the other player's research and cash based on what is currently

It adds a new feature to combatOutcomes where the caller can pass
in an object to get back the star states after combat, so that the
economists will decline to propose that you buy economy on a star
that you can already see you will lose before the cycle. If you
lose it and gain it in the combat sequence, they will still wrongly
recommend it.

Written in a sequence of pair programming sessions with Rob! Thanks!

commit 1e5b9dad08ee4e802fa74bff5fa65ccc89b3d45b

Change sorting strategy for tables.

If a field begins with a digit or minus sign, treat it as starting
with a number that should be used to sort the column.

commit df238a7a913007b15c941ec2e9cde3a88c0a143e

Make distance map robust to dark galaxies.

commit c0b82fd8dfdd351cbf6721aebafcbf1569bea83c

Skip colorMap iteration in early initialization races.

commit 9681291572557aed9051eac46dd60cdbaf942a68

Make rebuildColorMap reset all the player colours.

In a somewhat hacky fix, ensure that the player colours are up
to date any time rebuildColorMap is called and be sure to call
it when refreshing scan data. This eliminates a bunch of corner
cases where the colors get mixed with original colours on data

commit 3e8a1f77b8f59b4e1ba7134d829dadcb9ece2b2c

Show tick savings on research report.

As a small subscript on how much science you need to complete
a research activity faster, show how many ticks will be saved
if you pay for the upgrade. Especially useful in early game
where the tick savings are often more than a single tick.

commit 005d66b5a2781d7386ff6f31029a9052cc49a836

Add all alliances summary to empires screen.

To make it easier to compare across alliances in big games,
add a separate summary table with one row per alliance so
that you can see where your alliance stands relative to
the others in aggregate.

commit f3dbb406c5bda4546f70693fee451d001d1aa7a0

Change max finding to be level sensitive.

In the research report, the coloring was sometimes wrong if
a player had lots of research at the prior level. Ensure that
the player who is furthest ahead level+points wise is colored

commit bf0b2ee1e11357228bb320b31ae6d0d2f3ce5ce2

Refresh interface when adjusting combat handicap.

Especially when viewing the filtered combat report, it's nice
to see the report update as soon as you adjust the enemy's
weapons level.

commit cac448d69decd993f609cdd28eef2fa03c5806ae

Fix activity report to include the end tick.

commit 502fc1805d6f8f52819f63e91a19f887b8934384

Change ownership report to show only the last cycle.

Make the ownership report show the last 24h (or 20h, or whatever
depending on cycle length) so you can scroll through it with the
time machine and just see current changes when you pull it up.

Unsure of the goodness of this change as it works worse with
filtering but better for interactive exploring. Might make it
show full history if you apply a filter for the best of both

commit 564e7c564d5196bb5ef3911441df49f17056ca04

Modify activity report to not consider tick 0 updates.

A player will go AFK if they didn't make any updates after
the start of the game, but activity was crediting pre-game
activity to tick #1 if the player was active multiple times
in the pre-game interval. Squish all that together so that
they show up as possibly AFK instead.

Also, make the activity report only run up to the current
tick on display, rather than the current real tick, so that
you can scroll back through activity with the time machine.

commit 3225ce63915b3b944575c52172a3495a7523782b

Add in more logging and code from v2.2.41.

Version v2.2.48 doesn't reproduce the request messages bug after
a week of waiting, yet seems to contain all the code that was in
the original faulty diff between v2.2.7 and v2.2.8. It was missing
one block from v2.2.41, the last version where the bug was observed.

Deploy this with the safety in place so that it shouldn't actually
hammer the real server, to see if the bug is still reproducing in
the wild.

commit e3b4020903811d09586c913c75f93cc8d83e3d81

Change autocomplete to prefer players over stars.

commit 3484ab6440db5ddfae8f1cc87a2523c857aba15d

More debug info for event cache.

commit 4bc63863d91965baabb8c925b1612b494ee592c5

Update techs for proteus in Rob's new table.

commit a4c3522a47dc07d008bdd91cec0aa430a467cb7a

Complete player and star names when square bracket is typed.

Subsequent presses of the key cycle through matches.

commit 7df2e3f2b4c8a5d1efc0ae9e4b478aad971e612c

Fix column descriptions.

commit 7db37f2d1b55db9f7d985da89e6087f687b1a39d

Add asterisk next to current research.

commit f485fe63e6384085f2809b8e4d2c35c5d2f946e1

Colour code research progress.

Green = max ally level and max ally progress
White = max ally level but not max progress
Red = not max ally level

commit 02da11b9fe3a7ab7900995ae00abb213981e0621

Show all alliance research progress.

Updates the alliance research screen to show progress for all research
areas regardless of the one currently being researched. This is useful
for coordinating research to quickly figure out who is closest to the
next level.

commit da6d6b2134b815bf9d88c32cb7339e0b48bc5da0
Merge: 451d206 1b0ad2c
Author: anicolao
Date: Mon May 22 13:29:46 2023 -0400

Merge pull request #5 from flackr/autocomplete-cursor

Separate autocompete logic and fix bug.

commit 1b0ad2ce77beff116c6acb8b4296c61f8407e7c5

Separate autocompete logic and fix bug.

This fixes a bug when completing a player name or api key before another
player name or key that it doesn't consider the insertion position.

Tests are also added for autocompletion logic by separating it out into
its own file and callable function to set up.

commit 0dee86a22796f415e5ac80a4bb8a9cc8a5b0ecfc

Attempt to fix screenshots for iPadOS.

commit d3fe81d5b633a86dea014b85418bfb836c6241eb

Merge pull request #4 from flackr/mkdir

Create dist dir if it doesn't exist.

commit 735571413f9686644b4852bac3e9210752e89b18

Create dist dir if it doesn't exist.

During the initial setup the dist dir doesn't yet exist and bin/version
fails to write the manifest due to this. Create the dir so the first run
just works.

commit 320863ac25fe89404f4c0018c0b177df58b48c27

Handle undefined response to game messages.

It looks like occasionally the response that comes back doesn't
contain game messages - perhaps there's an auth problem or an
error in the underlying game - so check for and handle this.

Also make another attempt to find a message in unhandled promise
rejections which often have no message and no stack trace.

commit 348780d7c5c78195e8a05193e26c40140ce60500

Fix that type error again.

commit b1b9b129b7fd77e1957826fce3fe49e20bd88ece

Experimenting with request bug.

I was unable to reproduce the request bug locally, so add
a variety of logCount calls on the broken codepaths, but
make the code behave as the current production version in
an effort to pinpoint the bug while not actually reproducing

Hopefully these new counts provide good insight.

D’oh! I missed describing one of my favourite new features! Rob added the ability to autocomplete with strings as well as numbers!

As before if you type [[0] it will autocomplete to the 0th player, but you have to know the player numbers. Now you can type [[Osr] and that will complete to the first player whose alias starts “Osr”; if you press ] again, it will advance to the next match. If no player matches, it’ll find the first star that matches, and pressing ] advances through star matches. It makes typing star names and player names so much faster and easier!


@Osric What is the proper API key formatting to send via message? I have tried to use this feature for partnerships and I can’t get it to work :confused:

** found a post that says “When you type [[api:APIKEY]] into a message it will convert it into a button that allows you (or other users of this extension in your message) to either see their scans or merge both scans.” it worked, is there somewhere these commands are clearly written out?