- Обновлён evolve под патч Dota 2 7.41f (сборка 26139613)
- Updated evolve for the Dota 2 7.41f patch (build 26139613)
- Made for patch
- 7.41f
- Dota client build
- 26139613
- Size
- 523 KB
What changed in every version of evolve and the loader.
the client reaches the site again after its move to a new server
since the afternoon of 2026-09-26 the site answers from a new server with a certificate from another authority, and the client refused it: the store tab showed an error and a paid session could not start. the client now accepts the new server's certificate chain as well as the old route's, so both ways to the site work, and a routine renewal of either certificate does not need a client update.
evolve spends about half as much of each frame, and a client freeze is fixed
the dll and the shared script layer now cost less per frame: on the heaviest combo the frame share fell from about 4.8 ms to 2.7 ms and the worst 1% of frames from about 48 ms to 10 ms; idle in a crowded fight went from about 3.0 ms to 2.0 ms. orders and drawing are unchanged. the client could freeze when a script created, moved or removed a particle while the game thread was busy; particle calls are now made where the engine expects them, and scripts see no difference.
the menu is rebuilt around a named rail, a group column and cards
The rail on the left names its tabs and adds Home and Keys. The group column lists a tab's groups with their icons and a search of its own, keeps the hero you are playing at the top, and turns a group's children into tabs on its page. Options sit in cards: a switch that owns other options heads its own card with its spell icon and folds away while it is off. A bar under the page says what the option under the pointer does and what its default is, a changed option is marked and resets in one click, sliders with named values are drawn as words, and hotkeys as keycaps with hold or toggle beside them. The menu speaks Russian or English (switch in the header), scales itself from the screen height (100% at 1080p), and has a new look: a blue-black palette, lit switches, smooth scrolling, and a short motion on every icon when the pointer reaches it.
Home shows the first-run steps, the hero you are playing with its switch and key, and what is switched on right now. Keys lists every bind of every script and settles a key that two actions share in place.
Scripts get notifications (notify.show: cards the client draws, with buttons and progress, and a status pill for toggle keys) and movable panels (ui.panel): with the menu open, every panel and the notification slot can be dragged, snaps to the screen's middle and edges and to other panels, and stays where it was put. New in the lua api: ui.group_meta, ui.menu_lang, ui.menu_search, and hint, section, names, reset and is_default on controls. renderer.blur_behind no longer hides everything drawn after it in the same frame.
icons load on the first frame, and the menu keeps its sections through a reload
icons are read straight out of the game's own files instead of waiting for dota to have shown them. before, an icon the client had not drawn yet this session came back blank, often for the rest of the session, and even the ones it had drawn took several seconds after inject. every panorama image now resolves on the first request; 120 hero portraits load in about 40 ms, once.
the menu lost sections after a script reload: Misc could show only one script's groups, a search result for a camera setting opened a page without it, and Theme came back empty. a lowercase "misc" was being kept as a second tab beside Misc; it is one tab now, and settings saved under the old spelling still load. the theme registers its settings again on every reload, and a change made just before a reload is saved first instead of lost.
order timing: orders one script hands over leave in the order it gave them, and a script's own queued orders no longer use up the burst allowance of the orders behind them, so a sequence is not split or reordered on the way out. the release event now names the ability each order was for.
Pack models that come with a metadata file load again on ordinary accounts. Outside developer accounts they had been refused at startup, so motion prediction and several planners never started.
The order-timing model and its tick table load as soon as the session is ready. Before, if they were first asked for before that, they stayed off until the next launch.
In-game store: if a listing's price changed after the page loaded, the click no longer charges the new price. The card shows the new price and asks again.
Lua api: http.host_status(url) returns whether a host is allowed, denied, or will be asked about. The compat HTTP.IsHostWhitelisted answers from it instead of always saying yes.
paid content switches off cleanly when a subscription lapses; a dropped connection no longer leaves a paid script unloaded for the session; free listings can be taken from the in-game store again; unloading can no longer hang on the store worker
models and the inference runtime load from the installed folder again on a launcher install, where they had been falling back to defaults since early september; a windows profile with a non-latin name finds its install; a few more ways for a script to reach outside its own folders are closed; a stray file in the scripts folder can no longer crash the game
closed api holes so a script can't read, write or reach past its own jail; the client now checks for a real session before it runs
updates download only what changed
The launcher used to fetch about 49 MB after every release, whatever the release touched. Now a release costs the files it changed: an update that fixes one script is a few hundred kilobytes instead of the whole download. The first update after this release still downloads everything once.
A republish: the client and its offsets are unchanged from the previous build. What moved is the script payload it carries, and each pack's own page says what changed in it.
the menu's search field no longer stands out as a lighter plate: it sits flat on the header and shows its well under the pointer.
the in-game menu plays its brand once per session instead of on every open, slider tracks hold still while you drag, every control in a row answers a click at full row height, long groups scroll without measuring what is off screen, and a reduce-motion switch lands every transition at once. the launcher's toggles are named for screen readers, honour reduced motion, and the rail's six glyphs move on the same clock as the menu's.
the menu's rail glyphs now move when the pointer arrives, the way the launcher's do: the bag swings, the gear turns a tooth, the tiles settle. the motion shipped in the previous build but its clock was never fed, so every hover sat on the still glyph.
launcher: the setup countdown no longer swings between seconds and half an hour. it reads the line rate and the per-request cost separately, fetches the large files first so the rate is known at once, and moves the figure the way a browser's download manager does: down quickly, up slowly, never in jumps.
the store now has three steps, each its own thing: you get a script (or buy it), you install it onto your account's list, and you switch it on in the client. uninstall takes it off the list and keeps what you bought. the same three verbs are on the site, in the launcher and in the in-game store, and a change made in one place reaches the other two.
in the menu the Store tab is a shop, scripts and configs. the Config tab is gone: Settings now leads with your installed scripts and configs, then appearance, input and the danger zone. the scripts list shows one row per script with its version.
script authors: a row that exists both as a file in your tree and as a published copy shows a local | market switch, so the shipped copy can be run and tested without renaming anything. while the market copy is selected, edits to the file do not apply and the row says so. lua gains scripts.owned, scripts.source, scripts.install, ui.menu_open and ui.menu_navigate.
launcher: the store follows the same three steps, and the setup screen's time remaining is now measured from the recent download rate against the whole payload instead of an average that started at fifteen seconds and grew.
the rail glyphs move when the pointer arrives
each tab glyph plays one motion of its own the moment the pointer reaches its cell: the blades cross, the radar sweeps once, the eye blinks, the bell swings from its hook, the gear turns a tooth, the cursor presses, the layers fan, the list rows step in, the bag swings on its handle. once per arrival and not while the pointer sits, since a looping glyph asks for attention and a tab does not.
the rail draws from the baked icon font, and a font glyph is one shape that cannot open or turn. so for the 420ms a motion runs the glyph is drawn as strokes instead, from the same lucide paths the font was built from, element by element, with the moving element transformed; at rest it is the font again, and the two sit on the same pixels. the path flattener in ui2_icons.cpp covers the svg grammar lucide uses, arcs included. the loader's rail plays the same way from its next release.
the client no longer dies when a script loads a font mid-session, and every player's rank is on screen
The 2026-09-19 game build crashes inside the graphics driver when the font atlas is replaced and the old texture is released in the same frame. The atlas is now rebuilt on its own and the old texture is held for three hundred frames before it goes.
players.profile(pid) reads a slot's name, team, steam id, rank tier and leaderboard rank out of the player resource. A new script draws every player's medal as a list per team during the draft and under the top bar portraits during the game; it ships enabled and has its own switches under Misc.
The replay harvest and training tools now use the v5 extractor with a download loop that survives dead and trickling connections, merged datasets address their shards by position, the calibration step keeps a map only when it beats the raw output out of sample, and both shipped models were retrained on 18,884 of our own matches.
The hero-motion model now predicts 0.3 to 4.5 seconds ahead and is ahead of the plain constant-velocity lead at every horizon; a switch under Misc returns every script to the plain lead. Scripts gain a per-script cloud store through cloud.*: a private key/value space per user with a quota, and an opt-in dataset channel that sends nothing unless switched on.
rebuilt for dota build 25196390, the 7.41e point update that landed this morning; the previous build crashed on it after loading scripts. also in this build: a presets api for scripts (config.get, set, save, load, list), and the release itself now stops when a saved setting does not survive a reload or a pack's combo key lands nothing.
It filtered every candidate through the unit's name, and the compat layer answered that name
with the entity's class instead — npc_dota_creep_lane for every lane creep, where the
whitelist holds npc_dota_creep_goodguys_melee. So the test was false for every creep in the
game: measured in the lab, eight enemy creeps died within reach over 45 seconds with the key
held and not one attack order went out. The same gate sat on the incoming-damage tracker and
on the ranged-creep priority, so those were dead too. With the name fixed: 32 of 34 last hits
and 2 of 3 denies across five waves, melee and ranged.
The api returns increased attack speed as a fraction and the compat layer handed it over unchanged, while every caller divides by 100 — so a hero at +115 was read as +1.15. The last-hit timing came out at 1.253 s per attack where the engine said 0.495, and a ranged hero's attack point carried 286 ms of phantom lead. Dodger, Batrider, Chen, Clockwerk and Naga read the same number. The attack point also assumed a base attack speed of 100; it is 110 on some heroes, and it now uses the base the engine reports.
Eight neutrals that exist in the current patch — the ancient frog camp and the split doom golem — were missing from the whitelist and are back.
A maxed Dagon reports itself as item_dagon_upgraded, a name the item dump does not carry,
so the shared item layer never found it: the family lookup missed, and the item chain that
fires from the combo key skipped it. Every hero holding a finished Dagon was carrying an item
nothing would press. It now resolves, and casts — 598 damage from the combo key in the lab.
The self-item batch fired on any combo target within 900 with the buff absent, so holding the combo key near one passive enemy spent a 95-second BKB. Every item in that batch is a save, none is an opener. It now needs actual threat — the module's own danger predicate, or two enemy heroes inside the same radius. Measured: full health beside one passive enemy no longer spends it, two heroes in range does, and being hurt with an enemy in attack range does.
Sonic Wave refused anything past 700, which is its cast range, not its reach: the wave travels 900 and widens to 450 as it stops. Reach is now derived from the live ability rather than either published number, the aim is clamped onto the cast circle instead of the shot being refused, and the hit test no longer discards the last 450 units. A target at 1000 went from "out of range" to 625 pure damage.
A Lotus Orb also vetoed spells it cannot reflect — the check had two arms that both said "blocked", so the argument distinguishing a targeted spell from an untargeted one did nothing. Scream of Pain and a Scepter's ground-cast Shadow Strike now go out into a live Echo Shell; a genuinely targeted spell is still held, and Blade Mail still blocks either, because it reflects damage rather than the spell.
Her combo over eight seconds against the same target: 1265 damage at the start of this audit, 2022 now.
Aghanim's Scepter rewrites Shadow Strike from unit-target to point-target — the engine clears the UNIT_TARGET bit — and the combo went on issuing a unit-target order for it. An invalid order is discarded in silence: no cast, no cooldown, no error. Measured in the lab, 24 orders over eight seconds landed nothing, while the ability's cast phase never once became true across 256 samples. Scepter is her second-most-bought item, so this was most of her combo for anyone playing her that way.
It now ground-casts at a lead point when the live ability reports an area — the same marker the pack already read for its detonate branch. Re-tested: two orders, two landings, the slow on the target, damage over the same eight seconds up from 1265 to 1608–1860.
The right-click fallback also cancelled the casts it was meant to follow: a suppressed cast step fell through to an attack order issued 25 ms later, and the guard that should have held it covered 68 ms against a 300 ms cast point. The hold now covers the ability's own cast point and refuses an attack while a cast is still inside it.
Turning a spell off in the icon grid now takes its own settings off the page — Axe's panel drops from 48 rows to 36 the moment Berserker's Call is excluded, instead of leaving twelve rows describing a spell that is no longer in the combo. Hidden rather than greyed on purpose: grey is this menu's word for "you cannot set this yet", which is a different statement.
The outline numbers are gone from the screen. Indentation carries the hierarchy instead. The labels the config is keyed on are untouched, so nothing you had saved moved, and search still matches both what you see and what is stored.
Also fixed in the same pass: a hero panel was drawing the icon grid AND the parent rows it replaces, because the grid was attached before the pass that hides a group's controls. Auto Pick had the same fault over its 260 rows. And three heroes whose ability switches hang on a sub-panel — Lycan among them — were getting no grid at all.
A hero panel in uTEA now opens with a strip of that hero's spell icons. Click one to include
it in the combo — the tile lights up, an excluded one is dimmed. The numbered sub-options
under each spell stay where they were, and every switch keeps its existing config key, so
nothing you had set is lost. It can be turned off in .uTEA → 6. Ability icon grid, which
puts the plain rows back.
Auto Pick and Auto Ban become grids of hero portraits instead of 130 captioned checkboxes each, and the priority slider now appears only for the heroes you actually picked.
The control behind it is ui.icon_grid, a general one any script can use: N cells, each with
an icon, a label and either its own value or a link to a control that already exists. It
knows nothing about dota — the icon is a path the script hands it. A spell whose art the
client has never drawn falls back to the label's initials and stays clickable.
96 of 118 hero panels get a grid. The other 22 caption their switches by behaviour rather than by the spell, and keep plain checkboxes.
Also: 31 hero panels carried no unit name, so the menu could not follow you onto them — Axe, Lion, Rubick, Techies and the rest left the hero dropdown wherever it was and hid the panel belonging to the hero you were playing.
A script the build does not own — one you dropped in yourself, or one an older version left behind — now has a Delete beside it in the scripts panel, two-step like the preset delete because the file does not come back. A script that ships with the build has no button: the next update would fetch it back, and switching it off is what that case wants.
This exists because an old version wrote plain scripts into the install and they shadow the marketplace copy of the same pack — the client keeps running last version's code while the switch in the menu appears to do nothing.
The payload ships the owner's packs and the marketplace lists the same ones, so an account that owns both had two copies of a pack and two rows to switch it with — and turning one off in the menu changed nothing, because the other copy went on loading. The session now says which file a listing is, and where the install already carries that file the installed copy is the only one that runs and the only one the menu lists. Its switch is the switch. A listing that is not a file anyone installs keeps its own row, as before.
The payload ships the owner's packs and the marketplace lists the same packs, so an account that owns them ran each one twice per frame — two sets of handlers, two menu registrations and double the cost, which is what made a 120 ms hold on the combo key unhittable. A bundle whose entry file the install already carries is now skipped in favour of the installed copy: that is the build that shipped with this dll, and every member already resolved to it.
The saved preset was applied before the marketplace packs registered their controls, so those controls kept their registration defaults — and the autosave then wrote the defaults back over the saved values. It went unnoticed while the marketplace carried only small packs. The day uTEA arrived through it too, one launch was enough to lose the combo key, the hero the menu was pointed at and every panel switch, which reads as a pack that ignores its own settings.
Both the boot and the reload now register every control, from both sources, before the
preset is applied. Boot also honours the preset you were last on instead of always loading
default.
A combo started from the shared combo key was started on the key going down and aborted on the key not being held, so any press shorter than the whole sequence killed it two orbs in — every press measured in a real session was between 13 and 117 ms. A preset now runs to completion the way the code already said it should; hold-to-run stays with the dynamic plan, which is started the same way it is aborted.
Invoker's spell and combo panels were registered with the three-argument option form, which defaults a checkbox off, so a fresh install showed no HUD at all.
"Invoker ML" and "Pudge ML" appeared as heroes of their own next to Invoker and Pudge: the menu built its hero list from the path of a registry entry and ignored the entry's own menu override. Their switches were always in the right place; only the node was wrong.
And the hero dropdown no longer strands you on someone else's panels. It followed "has the hero changed", with the answer kept in a global that survives a script reload — while the dropdown itself is rebuilt at its default, which is the first hero in the registry. After a reload it pointed at Arc Warden and stayed there, hiding every panel belonging to the hero actually being played.
The bundle work shipped in the previous build was refused one step earlier than it ran: the blob reader rejected any kind above 5, so every bundled pack came back "unknown kind" and uTEA, Visual Script and Draft Helper still did not load. All three now open, register and run — 349, 18 and 6 files.
Two rules behind it are now explicit. Where an install already carries a file, the installed
copy is what runs and a bundle fills in only what is missing. And a path written
scripts/... means the script directory rather than the game's working directory — every
pack writes its paths that way, and until now that only resolved in a packaged tree, so a
pack could find its own files and then miss the shared compat shims sitting beside them.
A pack that is a tree used to ship as a zip, which the delivery route tried to compile as
lua; the archive went out labelled "lua source" and the client refused it. uTEA, Visual
Script and Draft Helper all died that way. A tree now travels as an EVB1 bundle — one record
per file, lua members already compiled — that the client opens in memory and requires out of.
Nothing is written to disk. require, fs.exists, fs.read, loadfile and dofile all
reach a bundled member, so a pack written against a directory needs no changes.
The client also ignored the kind byte and loaded every marketplace body as bytecode. It now
loads what the server says it sent, which is what a server without luac has been sending
all along.
A text field kept the keyboard after the menu was closed, so typing went on filling the search box of a menu that was not on screen. Closing the menu now drops focus.
The group you were reading is where you come back to; the menu used to reset to the first group of the tab every time it opened.
The active config is remembered across restarts. It lived in memory only, so a client that
came back up always loaded default — and then autosaved your edits into a preset you were
no longer on.
A sealed file used to get a random nonce and a random blob name on every packaging run, so its bytes changed even when its content had not — and the loader decides what to fetch by sha256. Between the two previous builds, 4 of 780 files matched; everything else came down again, models included.
The nonce is now derived from the file key and the content, and a blob's name is a keyed hash of its logical path. Identical content seals to identical bytes under the same key, so an update moves the dll and the files that actually changed. This build is the switchover and still arrives in full; the ones after it do not.
Every script in an install that carries both loose files and a sealed .pak was loaded
twice — two sets of handlers, two menu groups, double the frame cost. The directory pass
now claims a name and the pack-index pass skips it, so a script runs once whichever layer
it comes from.
The panel splits its rows into local (a file this install carries) and from the marketplace (bytecode the session holds for the account). The two switch through different ledgers, and until now only local files were listed here at all. Rows are sorted and each one keeps its own hover state — two rows with the same name used to share one, so pointing at one lit the other and its checkbox drove both.
the in-game store tab (browse with previews, listing detail, library, config install, wallet purchase with the browser fallback), the ringless mark, the session heartbeat carrying store_rev so a purchase lands in a running game, marketplace scripts reloaded instead of re-registered on refresh, and the worker-thread exit fix
the launcher looks like the new in-game menu
the window, the side rail, switches, dropdowns, buttons and cards are the ones the new in-game menu uses, and the screens are laid out like the site: sign-in reads like the site's sign-in page, the store like the market, with the same filters, cards and listing page. a RU/EN switch sits in the header. the pick is saved on your account, so the site and the launcher open in the same language, and a language you choose on the site carries over to the launcher. the build card shows what a player needs, with the technical rows kept for developers, and the store's hint names the menu key (Home by default) instead of a fixed key.
telegram sign-in works without a vpn
"sign in with telegram" no longer opens a site window that needed telegram's own login page. the launcher shows a QR code: scan it with your phone, or press "open telegram" on this computer, then confirm in @evolvescripts_bot. a telegram with no evolve account picks a nick right in the launcher, and an account with an authenticator app asks for its code the same way as after a password. the code lasts 10 minutes, and a new one is one click away.
every screen follows the launcher's language
setup, the status bar, settings, updates, account, and every install and launch line now use the language the launcher is set to, not only the sign-in screen. the page your browser shows after signing in looks like the site and uses the same language. the "built for this dota" row tells the two cases apart: if your installed build is just older than the one already published, it says the new build is out and install gets it; it only says a new build is being made when the published build is behind your dota too. the install button shows the real download size instead of stopping short of it.
sign in with a mailed code, a passkey or telegram
the sign-in screen asks for your email first and sends a six-digit code; the password is one link below it. a new address picks its nick after the code, the same way the site does. a passkey (windows hello) or telegram opens the site's own sign-in in a small window of the launcher and comes back signed in, and "through the browser" still opens your default browser, now in the launcher's language. an account with an authenticator app finishes that step in the launcher instead of being sent to the browser.
The icons in the launcher's rail move once when the pointer reaches them, with the same motions as the icons in the client menu: the tiles fold in turn, the braces open, the bag swings from its handle, the arrow drops onto the tray, the head nods, the gear winds back and turns.
the launcher installs only what we signed
updates, the files it downloads and the client it starts now have to carry our signature. something that does not verify is not installed and not started, and the launcher says so in its status line instead of looking as if the server were unreachable. the build already on your machine keeps working, and so do sign-in and settings.
sign-in always binds this machine, and a buy carries the price it showed
the "bind this machine" box is gone. a sign-in without it could not download anything, so unticking it only produced a sign-in that failed later; the launcher now always binds.
get and buy send the price on the button that was clicked. if the listing's price changed after the store page loaded, nothing is charged and the store shows the new price and waits for another click.
evolve-loader --cli no longer crashes when its output goes to a command that stops reading early, and leftover files from older installs are cleaned out of the models folder too.
the launcher keeps its sign-in to its own server and cleans up after every launch
a store image from another address no longer gets the launcher's sign-in, and no request carries it through a redirect. when the server ends a sign-in, the launcher notices it on any screen, says so on the sign-in page and stops showing the old account. the server address has to be https now (plain http only for a site on this computer); an older setting that is not is replaced with the default, and the launcher says so once. the temporary files a launch writes are removed on every outcome, including after the game is closed later. the address field saves when you leave it rather than on every keystroke, and a launch that stops early no longer leaves the button stuck on working.
launch keeps waiting while steam starts dota
Right after dota was closed, steam could hold the next launch for half a minute. The launcher read that as a refusal, stopped waiting, and dota then started without evolve. It now waits for as long as steam is working, and stops only when a steam dialog is closed and nothing follows it. Updating also removes script files an older version left behind, which kept some packs from loading after the last update.
Fixed a hang when Steam refuses to start the game with a message like "the game is already running". The launcher now catches that, returns to the front and makes Launch ready again within a few seconds instead of waiting on a game that never starts.
the marketplace shows scripts and configs as two tabs above the filters instead of one list with configs as a category, on the site and in the launcher.
the in-game menu plays its brand once per session instead of on every open, slider tracks hold still while you drag, every control in a row answers a click at full row height, long groups scroll without measuring what is off screen, and a reduce-motion switch lands every transition at once. the launcher's toggles are named for screen readers, honour reduced motion, and the rail's six glyphs move on the same clock as the menu's.
the menu's rail glyphs now move when the pointer arrives, the way the launcher's do: the bag swings, the gear turns a tooth, the tiles settle. the motion shipped in the previous build but its clock was never fed, so every hover sat on the still glyph.
launcher: the setup countdown no longer swings between seconds and half an hour. it reads the line rate and the per-request cost separately, fetches the large files first so the rate is known at once, and moves the figure the way a browser's download manager does: down quickly, up slowly, never in jumps.
the store now has three steps, each its own thing: you get a script (or buy it), you install it onto your account's list, and you switch it on in the client. uninstall takes it off the list and keeps what you bought. the same three verbs are on the site, in the launcher and in the in-game store, and a change made in one place reaches the other two.
in the menu the Store tab is a shop, scripts and configs. the Config tab is gone: Settings now leads with your installed scripts and configs, then appearance, input and the danger zone. the scripts list shows one row per script with its version.
script authors: a row that exists both as a file in your tree and as a published copy shows a local | market switch, so the shipped copy can be run and tested without renaming anything. while the market copy is selected, edits to the file do not apply and the row says so. lua gains scripts.owned, scripts.source, scripts.install, ui.menu_open and ui.menu_navigate.
launcher: the store follows the same three steps, and the setup screen's time remaining is now measured from the recent download rate against the whole payload instead of an average that started at fifteen seconds and grew.
the pack count is real, update scripts updates, the rail glyphs move
the dota card and the scripts tab said 0 packs over a full install: a release delivers every pack sealed under scripts/.pak, so nothing on disk carries a pack's name and a scan for *.lua found none. the list now comes from the .scripts_state ledger, which the launcher writes from the account and the dll reads at load, so what it names is what will load. a file still sitting under its own name is listed as before.
update scripts used to re-read the account and leave the payload alone. it is the payload pull now, the same call boot and --cli update make, followed by the ledger sync, and the installer's last line shows under the button. on the dota card it is a ghost button, so launch is the one thing on that screen that breathes.
the six rail glyphs each move once when the pointer arrives, the way the thing they show moves: tiles settle, braces open, the bag swings, the arrow drops onto its tray, the head nods, the gear turns a tooth. the client menu's rail plays the same way from this release.
the install progress is readable
every button caption took the page's ink: the kit's !text-inherit beat the colour each kind asked for, so the primary button drew light grey on its blue face and the install line on it was near invisible. the caption colour is set inline now, dark on the accent as designed, which also covers the launch button while a launch runs.
during an install the setup screen no longer writes the count and bytes on the button at all. the slot becomes a readout: a percentage in the numeral face, the file count, bytes and time left in mono on the panel's own ground, and a bar under them. re-check leaves with the button, since it is disabled for the whole install and the line needs the width.
An older version wrote plain scripts into the payload, and they shadow the marketplace copy
of the same pack — the client keeps running that version's code while the switch in the menu
appears to do nothing. The installer already removed a plain file whose sealed twin it had
just installed; it now also removes a file it recorded installing that this release no longer
ships. Only files the loader itself put there are candidates, and configs/ is never touched.
The launcher also answers --cli update, and --cli launch now pulls the payload first —
the same order the window uses, so a launch cannot inject the previous release.
An install that had been through the older payload layout kept a plain copy of every script next to the sealed one this release ships — and the runtime prefers the plain half of that pair. So the client went on running scripts from the day that layout was replaced, while every release since landed beside them and was never read. The installer now removes a plain file whose sealed twin it just installed, and says how many it took. A script the user put there themselves has no sealed twin and is never touched.
A successful injection was reported as a failure. The module list gives a loaded image its extended-length path, and the check that recognises our own staged image compared it against a plain one — so the launcher said "evolve never appeared" about a dll that was already running, and the same mismatch made the status line claim no image was loaded.
The launcher also answers from a terminal now: evolve-loader.exe --cli status | launch | modules runs the same launch path the button runs, printing its steps instead of showing
them, and waits for the client to take the device token before it returns.
The launcher now stamps the client it is about to inject into. The wiring file it leaves in
%LOCALAPPDATA%\evolve\session outlives the launch that wrote it, and a client started
afterwards read it and came up as the installed copy — packaged tree, sandboxed vm, none of
its own scripts. A runtime that finds a handoff addressed to another process ignores it.
the loaded-module check retries while the client's module list is being mutated; one failed snapshot used to read as not loaded and let a second image be injected
the launch step recognises the sealed client image by where it was staged, not by its file name; a loaded, running client no longer reports as never appeared in the module list, and the token pipe and the staged image are cleaned up on that path
launch no longer injects a leftover plain evolve.dll on an install whose manifest delivers the dll sealed per device; the install step removes such leftovers and says so
a launcher started from a download on a machine that is already set up now hands over to the installed copy at once, or replaces it first when the download is newer; the setup screen is only for a first run or a check only the user can fix
the icon set is rasterised from the vector mark at 2048px and the swoosh is centred by its bounding box, so the launcher, its shortcuts and the taskbar wear the same sharp, ringless badge
the launcher updates itself: it checks the published version on start, downloads through the fixed route, verifies the sha256 and swaps the installed copy. the store tab: browse with previews, listing detail, library, config install, wallet purchase with the browser fallback. store cards clamp their summary and the grid drops to two columns on a narrow window.