9 Commits
Author SHA1 Message Date
Valiantsin DzerakhandClaude Sonnet 5.5 d3f403ecf6 Delete read-only folders and cloud placeholders of an old save working copy, retry for 2 s, and name the failing path in the fatal
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 22:54:20 +03:00
Valiantsin DzerakhandClaude Opus 5.5 d7266301d2 Skip the save and backup of a Commit that changed no byte, and retry the swap briefly
At start the game rewrites its save files with the same bytes and commits
twice; each of those commits made a new committed save and a backup, so one
start pushed every older backup out of save-backup. A Commit whose copy is
the newest save file for file (all hard links, same names) now only retries
a waiting swap.

Renaming the committed save away is retried for 200 ms instead of 2 s: a
failure no longer loses the commit, the next Commit or start retries, and the
game's next change to its save data waits for the commit thread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 21:00:01 +03:00
Valiantsin DzerakhandClaude Opus 5.5 65fd631fea Keep a save commit that cannot replace the committed save instead of dropping it
Windows refuses to rename a directory while any file under it is open, so a
virus scanner, Explorer's preview or a sync tool holding a file of
save/<uid> made every Commit of a session fail after its 2 s of retries.
The game had its Commit return 0 and showed the new slots from the working
copy, and the next start deleted that copy: hours of play were gone (#260,
#263, log line "cannot move the committed save (error 5)").

A Commit now renames its finished staging copy to save-tx/ready-<n> before it
touches the committed save. That rename is the commit point. When the swap
into save/<uid> fails, ready-<n> stays the newest save: later working copies
and the next start are made from it, and the next Commit or start retries the
swap. The failure log names the programs holding files in the committed save
(Restart Manager) or says the folder refuses the rename (no DELETE access).
--probe-fs holds a committed file open across two Commits and restarts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 20:20:50 +03:00
Wellington Dias e45eb07c6f Name each save backup so it sorts after every existing one, so a second commit in the same millisecond no longer gets a name the pruning deletes at once. 2026-10-31 02:05:21 -03:00
Wellington Dias 1d51343ac1 Build and run the runtime natively on Linux.
Shared runtime code now goes through runtime/platform/platform.h, implemented by platform/win32.c and a new
platform/linux.c: futex locks, a userfaultfd and PAGEMAP_SCAN write watch, signal-based async preemption, our own
fiber switch, and a SIGSEGV handler for the thaw and crash hooks. The window, input, menu and software keyboard get
SDL3 back ends beside the Win32 ones, with the swapchain (gfx_present.c) and input merging (input.c) shared. SHA-256
replaces BCrypt, ELF builds get their own override sections, and the build tools gain Linux branches.

On Linux the selftest and the gfx-abi, astc, nvn and window probes pass. probe-vkmem still fails: imported guest
memory cannot be write-watched on Linux, which the shadow buffers in vk_memory.c will address.
2026-10-29 16:56:56 -03:00
Valiantsin DzerakhandClaude Opus 5.5 6fca957670 Run the save Commit on a background thread: the copy, flushes and renames held the game thread 95-135 ms at every game save in the 1.4.3 fight save
The game's Commit returns at once. Every later change to the working copy, Unmount and the next Commit wait for the thread, so no write lands in the snapshot, and the window close, guest ExitProcess and --frames exits wait through fs_save_flush. A crash during the commit loses that commit only; the transaction and save_recover are unchanged. probe-fs waits for each commit and checks a write and an Unmount right after Commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 11:01:54 +03:00
Valiantsin DzerakhandClaude Opus 5.5 138a7d3a99 Commit a save by writing only the files that changed and hard-linking the unchanged ones to the committed save: the game rewrites 3-4 of 82 files per save, and flushing all 82 held the game thread for 300-380 ms
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 08:55:21 +03:00
Valiantsin DzerakhandClaude Opus 5.5 51567ac32a Freeze idle pool regions read-only so write-watch queries skip them
The mirror and the texture checks queried about 930 MiB of write-watched memory per frame (0.96 ms on the RX 9070
machine, about 3 ms on an 8th-gen i7), at about 1 us per MiB, and 770 MiB of it lay in 2 MiB regions nothing had
written for two seconds. In mirror mode a region left unwritten for TOTK_FREEZE_IDLE submissions (300; 0 turns it off)
and lying wholly in imported pools is now made read-only (memory.c mem_freeze), and the snapshot and change queries
skip it. The first write faults and a vectored handler thaws the region before the write retries; file reads into
guest memory, which the kernel would refuse on a read-only page, thaw their buffer first and log a refusal, as do pool
init and finalize, and commits, decommits and protection changes thaw under the same lock. A region stays thawed for
5 s after a file read. Field: 66 queries over 380 MiB, 0.56 ms per frame; 0.38 ms of it are the queries that find
writes. The perf line `mem: write-watch` gives queries, bytes, time, frozen MiB, freezes and thaws. The gfx-abi probe
covers freeze, thaw by a write and the hold after mem_thaw. TOTK_MEMORY, TOTK_MIRROR_GAP and TOTK_FREEZE_IDLE are known
settings now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 08:39:47 +03:00
Valiantsin DzerakhandClaude Opus 5.5 19c9b648d1 Add the recompiler, Windows runtime, tools and docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:27:54 +03:00