Repository navigation
Releases: gwaihirf22/loom_AOE
Release list
Loom 1.0.9
Twenty-nine commits since 1.0.8. macOS gains global hotkeys, the step
checklist gains a third witness, and the statistics window puts what Loom
read beside what the game was actually told to do.
Downloads
Windows — Loom-1.0.9-windows.zip. Not attached yet; this release was
cut from the Linux machine. Until it appears, v1.0.8's
zip is the
current Windows build.
Linux — Loom-1.0.9-x86_64.flatpak, and it is still EXPERIMENTAL.
(sha256 149e2d2b9a8376e71064de390cfa8f2a3b2d31fea725b36d92e97535bd30ed4e)
flatpak install --user ./Loom-1.0.9-x86_64.flatpak
flatpak run io.github.gwaihirf22.loom_AOE
It needs the KDE 6.11 runtime (org.kde.Platform//6.11), which Flatpak
pulls from Flathub if you do not already have it. It builds, installs and
has been verified running in its sandbox, but it has had nothing like the
testing the Windows build has. Treat it as open for testing rather than as
a stable download, and please report what breaks.
macOS keeps its promises
Global hotkeys work, on Carbon's RegisterEventHotKey — nothing to
install and no permission to grant, the same shape as the Windows backend:
the OS does the matching, so Loom cannot learn a key it did not register.
Two Mac facts are handled rather than suffered. Qt swaps Control and Meta
there, so a captured binding names the key you actually pressed ("Ctrl" is
⌃, "Win" is ⌘). And a five-second hold fires once, because macOS does not
auto-repeat hotkey events — so the next-step key cannot race through a
build order.
A match's recorded game is found automatically on the native port, which
keeps a Windows-shaped user tree inside its own VFS.
A third witness for the checklist
A technology the production queue watched produce for at least its listed
research time crosses its build item off, green, whether or not the game's
message feed ever printed the line. That is a reading and not an
assumption, so it earns the same tick the age crest already does — and it
is reconciled rather than added, because a technology completes at most
once in a game.
Research does not divide among villagers the way a building does, so its
listed time is a hard floor. That is the one thing that turns the queue's
queued into the feed's complete, and nothing weaker would do.
Two lines on one chart
The statistics window draws what Loom read beside what the game was
actually told to do, with a row of averages along each — each row at the
end its own line occupies, so the two cannot overwrite one another. Two
witnesses agreeing is now its own colour and its own fact.
The overlay's centre note gets out of the way
It was centred on the whole panel with no regard for what sat either side,
which is invisible while the note is short and wrong the moment it is not:
"BUILD DONE · Ctrl+Shift+W for the report" was drawn straight through the
villager count and the pace, and all three became unreadable together.
A note that fits is now centred in the gap between them, so the usual panel
is untouched. One too long scrolls within that gap, holding still at each
end so the beginning and the end are each motionless when you read them,
and its cut edges dissolve rather than being sliced mid-letter.
Also fixed
- The release snapshot published 162
.pycfiles its own test run had left
behind — 5.4MB of another machine's bytecode, in 1.0.8 and no earlier
version. - Three statistics tests had been red on Linux and macOS since 30 August
while Windows passed, and the chart was correct the whole time: they were
counting pixels of an exact colour, which is a property of the font
rasteriser rather than of the drawing. - Loom could never read its own namesake. The list of lines the reader
would consider was every icon crossed with every phrasing, so it included
impossible ones like--Wood Research Complete--— and a rival within the
margin refuses a real line.--Loom Research Complete--sits two edits
from that, so it was refused even from a perfect read: the one research
line in the whole table that no repair could ever recover. The candidate
list is derived from what the game's own object table says a subject is
now, rather than curated.
The full list is in CHANGELOG.md.
Loom 1.0.8
Loom reads the villager count and game clock off the AoE2:DE HUD and shows
the current build-order step in an overlay. It never touches the game
process — pixels in, overlay out.
Downloads
Windows — Loom-1.0.8-windows.zip. Unzip and run Loom.exe. No Python
install needed. This is the solid one.
Linux — Loom-1.0.8-x86_64.flatpak, and it is EXPERIMENTAL.
flatpak install --user ./Loom-1.0.8-x86_64.flatpak
flatpak run io.github.gwaihirf22.loom_AOE
It needs the KDE 6.11 runtime (org.kde.Platform//6.11), which Flatpak
pulls from Flathub if you do not already have it. It builds, installs and
has been verified running in its sandbox, but it has had nothing like the
testing the Windows build has. Treat it as open for testing rather than as
a stable download, and please report what breaks.
Linux arrives
Loom is packaged for Linux for the first time — installed from source
rather than frozen, because the Flatpak runtime brings a real Python. That
deletes three problems at once: no hiddenimports for the importlib-loaded
capture backends, the APM child process actually runs, and there is no
second copy of Qt because the PyQt base app provides one built against the
runtime's own.
Hotkeys, capture, APM and click-through all work again on Linux, and a
match's recorded game is found in any Steam library — including when Steam
is itself a Flatpak and its home is somewhere else entirely.
Post-game Data, in two columns
What Loom read sits beside what the game was actually told to do. The
recorded game is the only ruler in the project that is not one of Loom's
own readers, so putting them side by side is the difference between "the
reader says nine archers" and "the reader says nine and the game was
ordered nine".
The queue reader now decides an item once, by vote, from every poll
that watched it produce — rather than believing the first glance. A phantom
that flickers for one poll is no longer a permanent row. On one real game
that took the "nothing in the record matches these" list from 45 entries to
three.
A recorded game also attaches itself when a match ends, and again when the
statistics window opens — because stopping Loom is not the same as the
match ending, and the game may still be writing its record.
macOS
There is a working route again: the Windows build of the game under
CrossOver. It ran on first launch, overlay included. The native Feral port
remains paused in a known-degraded state.
Full detail in CHANGELOG.md.
Loom is GPL-3.0.
Nightly 2026-08-28 (1.0.8-dev)
This is a nightly, not a release. It is the development tree as it stood
on 28 August 2026, published so it can be tried — it has not been through a
release's testing and some of it has not been run at all. If you want
something stable, take v1.0.7.
Windows only. See the caveats at the bottom before installing.
What is in it
Linux packaging, as a Flatpak. Everything the build needs is in
packaging/linux/. Loom is installed from source on Linux where Windows is
frozen, which is deliberate: a Flatpak's runtime brings a real Python, and
that is what lets APM work at all — on Linux the counter is a child process
and a frozen build has no mode to start it with. Not yet built or tested;
see below.
Holding Shift no longer stops a hotkey being captured. Qt reports the
character a key produces rather than the key struck, so Ctrl+Shift+9
arrived as ParenLeft and was refused. That was 21 of the 86 bindable keys —
the whole digit row, all eleven punctuation keys, and Tab. Letters were
unaffected, which is why it looked like a digit-only fault.
The key that hides the panel is now Ctrl+Shift+Minus. Windows consumes
Ctrl+Shift+0 before any program can see it: measured in one run, Shift+0
and Ctrl+Shift+1 both arrive normally while Ctrl+Shift+0 produces no key
event at all. It still registers, which is why it worked as a binding and
could never be typed back in once cleared. If you have it bound already it
keeps working; only the shipped default changed.
Statistics and readers. Pace no longer staircases — lag is the gap
between two forward-only curves, so it can move at most a second per second
(over 164 games the mean worst jump fell from 31.6s to 12.1s while the peak
was unchanged). Post-game Data is two columns, Loom's readers beside what the
game was actually ordered to do. A technology that had been filed under a
unit's name — 25 identities — now carries its own.
Which build is this
It reports itself as 1.0.8-dev in the title bar: a tree on its way to
1.0.8, not 1.0.8 itself. Every statistics file it writes records the exact
commit (2e260be), so a bug report with one attached identifies the build
precisely.
Caveats, which are the point of calling it a nightly
- The Flatpak has never been built. The manifest is complete but
python3-deps.ymlmust be generated on Linux first. Nothing on the Linux
path has been verified live, and the X11 hotkey backend still carries an
UNVERIFIED note. - This build has not been through the checks a release gets. The test suite
passes (1793 tests), which is not the same thing.
Re-cut on the same day. The first build of this nightly shipped a test suite that could not be collected on the public tree — two test files import a module the publisher deliberately strips, so CI ran nothing at all rather than failing a test. The application itself was unaffected. Fixed, and the publisher now runs the exported suite before it will push anything.
Loom 1.0.7
Fixed
-
Loom could invent a Town Centre and then bill you for it being idle.
When production is blocked — housed, most often — the game washes the
queued item red. Loom could not reliably see that wash, and a wash it
could not name looked exactly like a freshly-placed item, which is
evidence that another Town Centre is working. The believed count only
ever grows, so one such frame stuck for the rest of the game: a 47-minute
game with a single Town Centre reported 1907 seconds of idle Town
Centre time, 517 of them unbroken, and TC IDLE sat on screen through an
age-up. Older versions were worse, not better — one 1.0.4 game believed
in thirteen Town Centres.No threshold could fix it, and four were measured: the busiest artwork
the game draws in a queue cell reaches 0.245 on the most selective test,
and the faintest real wash begins at 0.248. A wash multiplies the icon
underneath it, so the wash is now judged against that icon — Loom already
had the picture on disk and was throwing the colour away. Across four
recordings on two HUD skins at two resolutions it now finds nearly twice
as many washes and gets zero wrong on cells that were already read
correctly. -
The launcher's output pane was never fixed-width on Windows. It asked
for a font called "Monospace", which does not exist there; Qt satisfied
the family lookup with the UI font and then had no reason to consult the
Monospace style hint, so the pane resolved to Tahoma and every column of
pytest's aligned output has been out of line for every Windows user. The
same wrong font is what printed those intermittent
DirectWrite: CreateFontFaceFromHDC() failedlines in the terminal:
Windows offers8514oem, a legacy raster face, as the Monospace
substitute and DirectWrite cannot load it. It resolves to Consolas now. -
"What you ordered (recorded game)" on the build chart drew nothing.
The checkbox had been offering the recorded game and plotting no line at
all for several versions. It draws now. -
The recorded game and APM were the same colour. Two violets a single
digit apart, which is one colour to anyone looking at a chart, and they
landed on the same axes the moment replay-derived APM arrived. Loom's own
readings are green throughout and the recorded game is violet, on every
chart and in the tables. -
Hovering the Society chart quoted one line out of the four drawn.
Population and house room had no entry in the readout at all, so two
series were silently dropped, and the recorded game's line was never
wired to it.
Changed
- The statistics window says which numbers came from the recorded game,
per row rather than per heading. A violet heading over a mixed table told
you the section involved the record without telling you which figures did. - Villagers, population and house room now sit nested under "Loom read"
rather than beside it, because they are subdivisions of that witness and
not peers of it.
Loom 1.0.6
Loom reads the villager count and the game clock off the HUD and shows the
current build-order step in an overlay. This release is mostly about the
reading being right.
Download Loom-1.0.6-windows.zip below. No Python needed — unzip and run
Loom.exe.
Fixed
Loom could mistake another window for the game. With Age of Empires
closed, it picked a browser tab whose title happened to mention the game and
reported it as the game window — every coordinate after that described a
browser on a second monitor, with no error and no warning. What you would
have seen is the overlay quietly forgetting where you put it.
The overlay could reopen somewhere other than where you left it, for a
second and unrelated reason: placement measured the offset from the game
window, and startup applied it from the primary screen. Those are the same
point for a full-screen game on the primary monitor, which is how it lasted
this long.
The clock was unreadable through the Transparent UI mod. That mod removes
the HUD backdrop, so the clock is drawn straight onto the map and the
background changes every frame while the digits do not. On four recordings of
one game the clock read 284/284 and 284/285 without the mod, and 210/284 and
102/287 with it. It now reads 287/287 and 284/284 on the same recordings.
The same building or technology could be reported several times over.
Three separate causes, each hiding the next — including one research coming
back as --Hand Can--, --Hand Cart--, --Hand Car-- and --Hand Caet--
across four looks, each counted as a new event. Measured against a whole
match's own recording, Loom went from reporting 16 more events than were ever
ordered to reporting none.
Six unit names were refused outright, including --Hei Guang Cavalry Created-- — fifty of which had already been fought in recorded games.
The clock lost ten minutes of every 1080p game to one digit, and a
lingering notification could be counted eleven times over. You no longer need
to change the game's notification-duration setting.
Added
A Reader accuracy tab. Loom can attach a match's own recorded game and
show where the two disagree — separating what it counted too much of, which
cannot happen, from what it never saw, which proves nothing.
The recorded game is read only after a match ends, never during one. It
contains both players' orders including everything the fog of war hid, so
reading it while playing would not be a better reader — it would be cheating.
Loom refuses to open the file the game is still writing.
How long buildings and technologies actually took, army losses beside
villager deaths, and a warning on any game whose clock misread — the
numbers are left exactly as recorded and the warning sits above them, because
everything below is derived from the clock.
Place overlay now shows the panel you will actually play with, and saves
on a button rather than when the window closes.
Known
Statistics files written by 1.0.6 will not open in 1.0.5. Installing from
source now needs git and GitHub reachable; the .exe is unaffected.
Full notes: CHANGELOG.md
1.0.5 — the panel says when it has stopped reading (pre-release)
This is a pre-release. It is a large round of changes on top of 1.0.4 and none of it has been played by me for a full session yet. I believe it is better than 1.0.4 in every way, but "believe" is the honest word — if you want the version with the most hours on it, stay on 1.0.4. Bug reports are genuinely welcome and are the fastest route to a stable 1.0.6.
Download Loom-1.0.5-windows.zip below, unzip anywhere, run Loom.exe. Windows may object to a brand-new unsigned file — the README's If Windows objects section covers SmartScreen and Defender.
If you play at 1920x1080
Loom reads everything smaller at 1080p, and its reference images were originally cut at 1440p. The numbers are sorted in this build — the clock, villager count and population read 99–100% on recorded games at that size, where before a right answer was regularly thrown away for lack of confidence.
The game's own message feed is much better but still patchy. That feed is what ticks items off your build and counts your Town Centres, so at 1080p expect some items not to tick and the odd Town Centre to go uncounted. What it does report is sound — a line Loom cannot read is skipped, never guessed.
What's left is one specific thing, and it's written up in full: at 1080p a capital H loses its crossbar entirely, so "House Built" can read as "llouse Built" and that event is missed. It's a segmentation problem rather than missing letters, and the three obvious fixes were each measured and refused. 2560x1440 remains the fully-verified resolution.
The theme: Loom says when it does not know
- The panel tells you when it has stopped reading. If the clock keeps ticking but the villager count goes quiet, the header now says
VILLAGERS UNREAD · 24sand counts up, instead of wearing a stale number as though it were fresh. This came from a real game where the count sat frozen at 6 for the whole match and nothing anywhere admitted it. - Losing sight of the game is a band, not a takeover. A soft
LOST SIGHT OF THE GAMEbar sits above the panel until the game comes back. The panel keeps working the whole time — your step and your hotkeys are still there. It just stops pretending. - Every session now writes a log (in your Loom data folder, newest 20 kept) with the raw readings printed beside what Loom believed. The app has no console, so a problem used to leave nothing behind to look at. If something goes wrong, that file is what makes it fixable — please attach it to an issue.
Three build items that could never tick
All three were found in real games, and each had a different cause:
- A health bar refused a whole line.
--Barracks Built--was on screen and perfectly drawn, but a unit's health bar out in the world sat level with the text and got read as if it were a letter — which refuses the entire line. Your barracks never ticked. Fixed, and it recovered a line in the test corpus too. - Farms were being watched for, and the game never announces them. Checked against 900 recorded message lines from eight games: every one of the 22 building types the game does announce is in there, and there are zero farms. An item waiting on a line that never comes can never finish — and it drags whatever shares that item down with it. Eight items across the shipped builds were stuck on this.
- "Use Market to build 2nd Town Center" wanted a second market. The Market is the tool there, not the thing to build — so the real second Town Centre could not tick the item it belonged to.
Also: +1 VILL now appears when the age is the limit, not only during a build's stop-training window. Overbuild in Dark Age and you will see it.
Defaults changed
Loom now ships with my own settings rather than the designed starting point: a slightly more solid panel, brighter text, and the preview showing alert bands.
Hotkeys now ship switched OFF. A key Loom registers is taken away from the game while it runs, so that should be your choice rather than a surprise. All the bindings are set up and waiting — tick Use hotkeys in the launcher to turn the set on. (Start/stop the overlay is Ctrl+Shift+F1.) When hotkeys are off, the end-of-build panel tells you to enable them to reach the report, instead of quietly hiding it.
Also in this build (rebuilt 23 Aug)
A night's work on 1920x1080, folded in before more than a handful of people had the first build:
- Digit templates cut at 1080p. They had all been cut at 1440p, so a 1080p digit was stretched into a box nearly twice its size and compared against a shape the screen never draws. The failing
8of00:08:03was being classified correctly — by a mile — and thrown away for scoring 0.503 against a 0.55 gate. Clock reading went 92% → 99% on a full game with all three mods on. - A half-eaten digit can no longer pass as a whole one. At a strict mask pass the
2of00:02:41loses its bottom bar and genuinely looks like a7— it scored 0.674 as one and the clock came back00:07:41. A digit has to stand as tall as its neighbours now, whatever its width. - The notification font had 33 mislabelled letters. Nothing had ever checked it against itself, the way the digit templates always have been. 18 of them were pixel-identical to a variant of a different letter — one picture, two labels — and they were the commonest letters, so nearly every line paid. Removing them, plus letters newly cut at 1080p, took the labelled 1080p run from 74 events read to 137 of 275.
Known and not fixed
- At 1080p the message feed still misses lines — the capital-H problem above.
--Double-Bit Axe Research Complete--does not read even at 1440p, so that technology never ticks off. It is the letters, not the logic — same harvesting job.- The full list, with the reasoning, is in CHANGELOG.md.
Full changelog: https://github.com/gwaihirf22/loom_AOE/blob/main/CHANGELOG.md
Loom 1.0.4
The release where the build preview became somewhere you can play from, and
where the windows started remembering things properly. It also closes the
rest of dfinchau's report - #1 through #9 bar one - and two Town Centre bugs
that had been quietly telling players their TCs were idle while they worked.
The larger threads, in the order they matter:
- the overlay appears when you start it rather than when the game does, and
can be hidden - or kept off the game permanently - the build preview carries the overlay's alerts, so a second monitor can hold
Loom and the game can hold none of it - neither window scrolls sideways any more, and both reopen where you left
them, including on a second monitor - two separate causes of a false TC IDLE, both found in one captured game
The overlay comes up when you start it, not when the game does. It used to
stay invisible until a match was on screen, so starting Loom first showed you
nothing at all — indistinguishable from a program that had failed to launch.
The panel now appears straight away with your build on it, its numbers at
zero, and a banner saying what it is waiting for: WAITING FOR THE GAME
until Age of Empires is running, then WAITING FOR A MATCH until one
starts.
The zeros are the delicate part, and the banner is what makes them honest — a
panel showing numbers it did not read is the one failure the rest of Loom is
built to avoid. It shares the header slot the MANUAL note uses, so it costs no
panel height, and the first real reading clears it.
- Waiting had to move inside the event loop to make this possible. Finding
the game window and then a match were two open-ended blocking loops that ran
beforeapp.exec(). Showing the window earlier would not have been
enough: with no event loop turning, a mapped window never receives a paint
event, so it would have been a white ghost over the menus. Acquisition now
happens one step per timer tick, like everything else. - Stop works during that wait now, which it did not before. The stop line
queuesapp.quit()onto the event loop, and there was no event loop yet, so
stopping fell through toterminate()and thenkill()— withaboutToQuit
never running, which is the final statistics write.
And it never stops watching for one. Waiting is the feature, so nothing in
that loop is allowed to give up.
- An unreadable screen used to quit the overlay. A minimised window, a
game mid-restart, a loading screen with no frame yet — any of them ended
the program, and the player had to start it again. That behaviour was carried
over from when the wait was a blocking loop in front of the event loop,
where an unreadable screen could only mean a startup that had failed. It
now says so once and carries on looking. - The game window is looked for again while waiting, roughly every six
seconds, instead of being latched once byconnect(). Start the overlay at
the main menu, sit there a minute, then begin a match and the HUD could
never be found — the frames being searched were coming from a window that
was no longer the game's, and restarting the overlay was what really fixed
it. The same call also rebuilds a capture stream that has quietly stopped
delivering, which restarting was probably fixing too. - A note after about thirty seconds of finding nothing, naming the likely
causes — the in-game HUD scale, the resolution, or a UI mod Loom has no
templates for — and saying plainly that it is still watching. It complements
the existing note, which only fires for a HUD Loom nearly recognised and
stays silent when it recognised nothing at all.
Ctrl+Shift+0 hides the panel, and a Hide overlay button does the same. The
button turns green while the panel is hidden and the launcher says
overlay: hidden.
- Hiding is not stopping. Loom keeps reading the game, recording the match
and counting APM the whole time; only the window goes away. Stopping would
throw away the game being tracked, which is why this is a separate thing
from the Stop button. - The overlay owns the state and reports it upward, so the button and the
hotkey cannot drift apart: both ask for a toggle, and what the button
displays comes back on the statefeed as its own line. It has to be its own
line rather than a field on the per-poll payload, because that payload is
not emitted at all while the reading is unusable — which includes the whole
pre-game wait, one of the times hiding is most likely. - The key is rebindable and can be emptied like every other one, and it is the
one worth a second thought before keeping:Ctrl+Shift+0sits in the same
family as the game's control groups. The launcher's button needs no key at
all. - Click-through is re-checked the first time the panel comes back, because the
X11 input region that provides it is applied when a window is mapped — and
losing it quietly costs the player their cursor mid-match.
Loom no longer invents Town Centres at 1920x1080. A match where three Town
Centres produced almost constantly was told "2 TCs IDLE" for 149 unbroken
game-seconds, and its saved statistics charge 674 of 1675 seconds as idle
TC time against a believed count of five.
The count came from the game's own "--Town Center Built--" line, which is meant
to be the one exact source there is. Two of its four sightings were the same
line, read again.
Fixed
- The phrase template was a 1440p rendering stretched to 1080p. The game
does not draw its notification feed by scaling one master - at 1920x1080 it
lays the text out at a smaller point size - so resizing the harvested
template down compared it against a shape the screen never drew.ink_agree- mentalso thresholds the template absolutely and the matched region
relatively, so shrinking a template thins its own ink and the score decays
with size:town_center_builtscored 0.598 against itself at 0.735,
under its own 0.6 gate. At 1080p a perfect, noise-free match could not pass.
Measured over 336 frames, the line was recognised on 23 looks out of 46.
Phrases now carry one template per rendering, named with the scale they were
cut at, andtools/cut_phrase_template.pycuts the next one. Recognition on
that run went to 44 of 48, and the new template separates better from
other text (0.38 against 0.58) rather than worse. - A missed look was being read as a line leaving the screen. Every
anti-echo guard in the watcher rests on "was this phrase sighted last look",
so at half detection they were not weakened, they were absent. The rearm was
the one that bit: three unrecognised looks cleared the phrase's cooldown, and
the next sighting of the same lingering line counted as another Town Centre.
Traced frame by frame - the line arrives and fires correctly, is missed four
looks running while plainly still on screen, and fires again five seconds
later. Absence now needs its own evidence. A blank feed is proof and rearms
at once, as before; a phrase merely unrecognised among other lines must also
have been gone for ten game seconds, which is about how long a notification
lingers and more than twice the worst detection flicker measured. - Counting looks was the deeper mistake, and it made the bug depend on the
poll rate. "Three looks is about a second of real time" stopped being true
under load shedding. Replayed at one, two, three and four looks per captured
frame, the same pixels now yield the same two Town Centres every time; before
this the answer changed with the cadence. - A second Town Centre inside the cooldown was being lost, not delayed.
Found while checking that the fixes above had not made close-together Town
Centres worse - and they had, but so had the original code, in a way nobody
had looked for. The cooldown is refreshed by every sighting, so when a second
Town Centre's line arrives inside the window its own sightings keep pushing
the window forward and the fifteen seconds never elapse. Measured on two
lines 16 game-seconds apart - well outside any cooldown - the second was
never counted. A sighting after the previous line has provably left the
screen is now a new event in its own right, which is the game's own rule:
it does not reprint a phrase whose line is still up. This is purely
additive, so nothing that counted before stops counting. - A Town Centre that is built and never produced from is invisible to the
queue, which only sees a building once it makes something. The
notification is the only evidence such a TC exists - and that is exactly the
one the idle alert is for - so undercounting here is not a cheap failure.
The setting none of this was written against
-
AoE2 lets you choose how long notifications stay on screen, and every
timing in this module was measured with it at the shortest. That was never
recorded anywhere, which made a pile of game-second constants quietly
conditional on a setting no player was told about. The README, all three
install guides and the launcher's How-to-use page now ask for the shortest
setting, under Options → Interface, alongside HUD scale 100%.It is not a footnote. The duration decides how the feed behaves, not just
how long a line sits there: the game will not reprint a message that is
still on screen, so longer messages mean more real Town Centres go
unannounced - and the feed redisplays recent history whenever it has faded,
so longer messages also mean fewer fades and fewer echoes. Both failure
directions move at once, in opposite directions. Measured at the shortest
setting on the game that started all this: the Town Centre phrase's pixels
appear in 16 separate spans for **2 real Town Centres...
Loom 1.0.3
Loom runs on Windows 10. It did not, and the reason was a cosmetic
preference. Reported against 1.0.1 as issue #5 on the public repo, along with
seven others; three of those were already fixed by 1.0.2 and this closes three
more. Two remain open — the build preview's scrolling (#8) and the placement
window's transparency (#4) — both reproduced, both with a cause found.
Fixed
- The capture stream starts on Windows 10. Loom asked for the capture
without the yellow "this window is being captured" border, which is
GraphicsCaptureSession.IsBorderRequired- an API Windows 11 has and
Windows 10 does not. The request did not degrade: it raised out of
start_free_threadedbefore the first frame, so Loom died on a preference
about how the capture looks. The borderless request is now an attempt rather
than a requirement, retried without it if it is refused, and Windows 10 gets
a line saying the yellow border will appear and that the reading is
unaffected. Retried rather than gated on a build number deliberately: which
servicing build first carried that API is not something I am confident about
from documentation, and this backend was written by measuring rather than by
reading. Verified against the real library on Windows 11 - the machine that
can hide the border still does, in one attempt, with no retry. - A child process that crashes says what happened.
loom_app.main
dispatches--modewith areturn, and the crash reporter 1.0.2 added sat
below that line - so the launcher had it and the overlay, coach and readout,
the only three that ever run unattended over a game, did not. The Windows 10
capture failure above therefore arrived as PyInstaller's raw "Unhandled
exception in script" dialog thrown over the match. A test pins the ordering
with the AST, because a comment saying "before" is what was there while it
was wrong. - A capture failure is a sentence, not a traceback.
loom_overlaynow
catchesCaptureErroraround the two open-ended waits the way it already
caughtKeyboardInterrupt. Not being able to see the screen is a condition
Loom understands - the game may be in exclusive fullscreen, the machine may
refuse an option - and it belongs in the output pane as one line. - The transparency labels say "Text & icons", not "Text && icons". A
doubled ampersand is how a mnemonic is escaped in a button or a menu item;
a QLabel with no buddy does no mnemonic handling at all and renders both
characters. about.py and the README had always spelled it with one, so the
launcher was the only place that got it wrong - and the only place a player
ever sees it. - "Ctrl+C to quit" is only printed where there is a Ctrl+C. Under the
launcher every program is a windowed child on a pipe with no console at all,
and Loom told players to press a key that could not reach it. One of them
pressed it, watched nothing happen, and filed a broken hotkey - which was
fair, because the program had said so.stopline.quit_hint()now names the
Stop button when stdout is not a terminal, and lives instoplinebecause
the Stop button is the stop line: the mechanism and the sentence describing
it belong together.
Loom 1.0.2
Loom can read a 1920×1080 screen. Until now it could not — and it failed in the worst way available, by reading the HUD wrongly rather than not at all.
Windows: download Loom-1.0.2-windows.zip, unzip anywhere, run Loom.exe. No Python needed. If Defender quarantines it, that is a false positive on a brand-new unsigned file — the Windows guide has the two clicks that restore it.
Reading the HUD at 1080p
Four faults, each hiding the next, found by replaying recorded games — eleven capture runs, both HUD skins, both resolutions, around 2,000 frames.
- The clock read nothing at all — 0 frames out of 185 — because at this size its digits are about 6×12 pixels. Now 184 of 185, none going backwards.
- The villager count was confidently wrong. A 3-pixel "1" was being skipped as though it were a colon, so 18 read as 8 and 21 as 2 — on 189 frames out of 300, consistently enough to look like flakiness rather than the silent wrong number it was.
- The stock villager band was reading the banner art above the number, which squashed each digit into half its box and matched it in a shape the screen never drew. Counts of 10, 11, 14 and 15 now appear for the first time, and a ten-minute game reaches 37 villagers instead of stopping at 17.
- The population band had all but stopped answering — the band the housing alerts run on. Across every capture: 1,795 readings against 1,299 before.
2560×1440 is untouched, on both skins, verified run by run.
The launcher, from the first outside tester
Windows 10 at 1080p, running the packaged zip. The launcher had outgrown the screen, so its settings now live in tabs and the whole column scrolls; it remembers its size and position, clamped back onto the screen. Three developer buttons that silently killed the app are disabled in a bundle with the reason in their tooltip, an unhandled exception now says so instead of vanishing, and How to use shows its pages again on a plain Windows theme.
Known problems
- The housed alert can still fire when you are not housed — seen once in a 1080p game after these fixes. A residual digit confusion on the stock bar; not yet pinned down.
- The overlay can shimmer at a non-native resolution. Measured out of Loom: the window does not move at all. It is the display scaling 1080p onto a 1440p panel — play at your monitor's own resolution or in windowed mode.
Full detail in CHANGELOG.md.
Loom 1.0.1
Adding a build order used to be an instruction rather than a feature: find a folder Loom had never created, make it yourself, drop a file in, restart. This release makes it a button.
Windows: download Loom-1.0.1-windows.zip, unzip anywhere, run Loom.exe. No Python needed. If Defender quarantines it, that is a false positive on a brand-new unsigned file — the Windows guide has the two clicks that restore it.
Added
- Import build — pick a build-order JSON from anywhere; Loom checks it, copies it into your builds folder and selects it, with no restart.
- The check behind it — a build Loom genuinely cannot use is refused with the reason. Anything merely odd (steps out of order, missing times, icons it has no picture for) is said plainly and left to you. It caught a real one the day it was written: a published build with 25 villagers on resources at a step with 21.
- Search and a civilization filter — the picker is now a list that stays open, so every keystroke shows its own answer and Enter takes the top result. Filtering to a civilization includes the Generic builds, since those play as any civ. Whatever you have selected stays in the list whatever the filter says.
- Open builds folder, and two How-to-use pages covering all of it.
Fixed
- Icon tokens match forgivingly — a build exported as
.pngnow finds the.webpLoom ships, instead of falling back to words on every instruction. - The builds folder is created, rather than being a path you were told to make.
- Loom's own two hand-written builds draw icons like every other build.
- A packaged copy no longer writes into itself — captures go to your data directory beside your statistics.
Full detail in CHANGELOG.md.