Skip to content

Add a cross-platform web-based editor (Linux/macOS/Windows)#88

Open
VasilyPolyuhovich wants to merge 3 commits into
FINDarkside:masterfrom
VasilyPolyuhovich:linux-web-port
Open

Add a cross-platform web-based editor (Linux/macOS/Windows)#88
VasilyPolyuhovich wants to merge 3 commits into
FINDarkside:masterfrom
VasilyPolyuhovich:linux-web-port

Conversation

@VasilyPolyuhovich
Copy link
Copy Markdown

Thanks for this tool — it's been genuinely useful.

Since the editor is Windows-only (WPF / .NET Framework), I put together a cross-platform version that runs in the browser, so it works on Linux and macOS too. It lives under a new src/ folder and is almost entirely additive — the existing WPF app behaves the same. Totally fine to take it or leave it.

What's in it

  • src/TldSaveEditor.Core — the existing save logic moved into a small .NET 10 class library (serialization, game-data model, item/map dictionaries). Most files here are your code unchanged; the only genuinely new pieces are Services/SaveEditorService.cs and Services/Dtos.cs (a thin UI-agnostic facade).
  • src/TldSaveEditor.Server — a tiny local-only ASP.NET app that serves a plain HTML/JS UI (no front-end build step) over a localhost API.
  • Util.GetLocalPath() now resolves the save folder on Windows, macOS and Linux (Steam/Proton prefix) instead of the Windows-only shell call.

The only change to the existing app: the shared JsonConvert.DefaultSettings (float/byte handling) moved from MainWindow into GameSave so the app and the server use one definition.

Running it

Needs the .NET 10 SDK.

  • Linux/macOS: ./run.sh
  • Windows: run.cmd
  • any OS: dotnet run --project src/TldSaveEditor.Server -c Release

Serves http://127.0.0.1:5173 (loopback only) and covers the Player, Skills, Inventory, Afflictions, Map and Profile tabs. Every save still writes a timestamped backup, and the UI can restore one.

Two fixes carried into the core

I tested load → edit → save → reload across a range of my own sandbox saves and it round-trips cleanly. Happy to adjust or split this up if that makes review easier.

The original tool is a Windows-only WPF/.NET Framework 4.8 app. This adds a
cross-platform port that builds and runs on Linux/macOS/Windows.

- TldSaveEditor.Core (net10.0): portable save logic extracted from the WPF
  project (serialization, game-data model, CLZF, item/map dictionaries) plus a
  UI-agnostic SaveEditorService facade and DTOs. GetLocalPath now resolves the
  save folder on Windows, macOS and Linux (Steam Proton prefix, libraryfolders).
- TldSaveEditor.Server (net10.0): local-only ASP.NET minimal API over the
  service, serving a zero-build web UI from wwwroot.
- Web UI tabs: Player, Skills, Inventory, Afflictions, Map (with player-position
  marker), Profile. Per-item condition/quantity/litres/rounds editing,
  experience mode, custom mode, carry-weight limit, backups + restore.
- run.sh launcher (builds, runs, opens the browser).

Save-integrity fixes carried into Core:
- Liquid fixed-point bug (issues FINDarkside#85/FINDarkside#87/FINDarkside#74): water/fuel/volume are Int64
  (1 L = 1e9), not float; added long fields + Liters helpers + fixed item
  dictionary defaults.
- JsonConvert.DefaultSettings (FloatFormatHandling.Symbol + ByteArrayConverter)
  is required on write, otherwise Infinity/NaN and byte arrays corrupt the save.

Verified: all real saves load/edit/save round-trip cleanly on Linux.
- Single-source JsonConvert.DefaultSettings in GameSave's static ctor (was
  duplicated in MainWindow and SaveEditorService); load-bearing for save
  integrity, now defined once for both the WPF app and the web server.
- Reuse GameSave.Backup() (made public) for the restore snapshot instead of a
  private copy in the service — restores now also prune to MAX_BACKUPS.
- Serialize all SaveEditorService methods behind a lock: it is registered as a
  singleton and the parser's static caches / the in-memory graph are not
  thread-safe under concurrent requests.
- Map server errors to status codes (404 not-found, 409 no-save-loaded, 400
  bad-arg) and stop echoing raw exception text for unexpected errors.
- Validate /load and /restore paths resolve under SavesFolder (defence-in-depth
  on top of loopback-only binding).
- UpdateItem takes UpdateItemRequest instead of five positional args.
- Batch inventory rows via DocumentFragment; align launchSettings to the real
  port; remove dead Util.IsDebug field.

Verified: all 15 real saves still round-trip cleanly; restore/item-edit/path
rejection behave as expected.
The server is plain cross-platform ASP.NET (net10.0) and already handles
Windows specifics (LOCALAPPDATA save path, browser auto-open), so it runs on
Windows as-is — it just lacked a convenience launcher. run.cmd mirrors run.sh.
README now documents the .NET 10 requirement and how to run on each OS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant