Skip to content

Repository files navigation

Everwind Save Editor

A point-and-click Tk GUI for inspecting and editing Everwind save files (Player_Local.sav, WorldInfo.sav, and per-island world .sav files).

Inventory view

Warning

Always back up your save folder before using. This tool writes directly to live save files. Bad edits can crash the game on its very next load (see Safety notes). The editor keeps its own per-file .bak rotation, but a manual full-folder copy is the only thing that protects you from your own undo-stack mistakes.


Features

Browsing

  • Combined view of Player_Local.sav plus every island .sav (toggle off with the Combine player + island saves checkbox).
  • Three tabs: Inventory, World & Islands, Character & World.
  • Filter / search across item names, item ids, categories, locations, chest labels, and enchantment names.
  • Toolbar toggles: Empty Items Only, Include Empty Items, User Only Items, Non-User Only, Include (loose) items.
  • Group by None / Category / Location / Chest. Right-click a chest header → Flag chest as mine ★ to keep an unanchored chest in the "User Only" filter. Select multiple chest headers (Ctrl-click / Shift-click) and right-click to flag or unflag them in one batch. Flags are persisted across launches in editor_settings.json.
  • Player-placed Flag Markers (map waypoints / stash flags) are auto-detected from their FlagMarkerData payload and labeled #N · Marker. They are always treated as player content (no manual ★ needed) so the User Only filter shows them by default.
  • Right-click any column header to hide it, then right-click any remaining header to bring hidden columns back. Hidden-column selection persists.
  • Up to nine enchantment columns per row (Ench 1Ench 9). The full list of ECharacterStat::… modifiers attached to that physical slot is shown.

Grouped by Location

Editing

  • Double-click any scalar cell to edit it in place (SlotsWithItems, MaxStackCount, Durability, Energy, Fuel, Level, SpecialEffectLevel, Amount, or any enchantment ModifyValue).
  • Right-click an enchantment cell → Change enchantment type to swap the stat. Only same-byte-length stat names are offered, because the underlying FString body needs to drop into the existing hole exactly (see How edits are safe).

Bulk actions

Button What it does
Bulk apply Write <field> = <value> on every selected row. The combo box lists every scalar field plus Ench 1–9.
Split stacks… Redistribute the total quantity of an item across every slot that holds it.
Delete (Del) Zero out SlotsWithItems on every selected row.
Repair & Top Off selected Restore selected rows to category-appropriate defaults (full durability, max levels for gear, sane stack max for the rest). Weapons & armor (Boots / Gloves / Chestplate / Helmet) with fewer than 3 enchantments get Level 0 / SpecialEffectLevel 2 instead of 10/10. Jewelry and Tools always get 10/10. Player_Local.sav only.
Repair & Top Off ALL Same rules across every populated, non-skipped slot in the loaded saves. Still scoped to Player_Local.sav by default.
Top Off SELECTED (incl. world) DANGER. Bypasses the player-file scope guard. Use only on a small, hand-picked selection in a world / island save.
Make Max Level Sets Level and SpecialEffectLevel = 10 on every selected weapon / tool / wearable.
Make Max Stacks Sets Qty = Stack Max (and bumps Stack Max to a category-appropriate maximum) on every selected row.
Max Ench (25) Sets ModifyValue = 25 on every enchantment modifier of every selected enchanted row. Skips items with no enchantments.
Compact empty slots… Zeroes every scalar on slots whose SlotsWithItems is already 0, so empty slots stop showing leftover durability / level numbers from earlier items.
Delete all Drops Zeros SlotsWithItems on every entry inside an unanchored "Drop · …" container (creature loot bags). Leaves chests, stations, anchored Block actors, "Loot · …" containers, and the player's own Inventory / Equipment alone.

Requirements

  • Python 3.10+ with Tk (the default Windows installer bundles it).
  • The core editor uses standard-library only.
  • The docs/redact_path.py screenshot helper needs pillow (pip install pillow).

Quick start

Option 1 — Download the standalone .exe (no Python required)

Grab EverwindSaveEditor.exe from the Releases page and double-click. Settings (editor_settings.json) are written next to the .exe, so put it somewhere you have write access (a folder under your user profile is fine — avoid Program Files).

Option 2 — Run from source

git clone https://github.com/matziq/EverwindSaveEditor.git
cd EverwindSaveEditor
pythonw .\everwind_save_gui.py
# or just double-click run.bat

The editor auto-detects the most-recent save folder under %LOCALAPPDATA%\Everwind\Saved\SaveGames\. Use Browse Player / Browse World to point it at a different slot.

Option 3 — Build your own .exe

pwsh -NoProfile -ExecutionPolicy Bypass -File .\build_exe.ps1
# -Clean wipes build/ and dist/ first

PyInstaller is installed on demand. The resulting one-file binary lands at dist\EverwindSaveEditor.exe (~10–15 MB) and bundles item_dict.json and item_asset_paths.json so the editor works on machines without Python.

Project layout

Path What it is
everwind_save_gui.py The Tk GUI. The entry point.
everwind_save_edit.py Parser + write-back library. CLI for dump / apply / set / update_meta.
enchantments.py CustomModificators array decoder and per-slot grouping.
extract_game_data.py One-shot generator for item_dict.json from the game's .utoc.
harvest_save_paths.py Walks every loaded .sav and records the full /Game/Data/Items/... asset path for every item it sees.
item_dict.json Item-id → name / category / tier lookup. Pre-generated; can be regenerated against a new game build.
item_asset_paths.json item_id/Game/Data/Items/... path map (built by harvest_save_paths.py).
run.bat pythonw everwind_save_gui.py. Double-click launcher.
build_exe.ps1 / EverwindSaveEditor.spec PyInstaller wrapper + spec to produce dist\EverwindSaveEditor.exe.
tools/ Recovery / diagnostic helpers — see tools/README.md.
docs/ README screenshots + the redaction helper used to create them.
editor_settings.json Per-user runtime state. Not committed.

How edits are safe (in-place bytes only)

The Everwind save format is a UE5 tagged-property stream with no GVAS header. Each property is preceded by a Size field, and arrays / structs have their own Size headers — changing a string or enum value would ripple every enclosing size by Δlen bytes.

This editor refuses to do that. It only patches:

  • Fixed-width 4-byte scalars (IntProperty, FloatProperty) at their on-disk byte offsets.
  • Same-byte-length FString swaps for enchantment stat names (handled by apply_raw_writes in everwind_save_edit.py).

After every write, the sibling .meta CRC is rewritten — see The .meta CRC.

Backups & file naming

Every write goes through apply_patches() / apply_raw_writes() in everwind_save_edit.py. Before the first edit of a save file in a session, the original is copied to a baseline backup. Every subsequent edit creates a timestamped rotating backup. The full set you'll see in your save folder after a few edits looks like this:

Player_Local.sav                            ← live (the game and the editor both write this)
Player_Local.sav.meta                       ← decimal-ASCII CRC32 of the live file
Player_Local.sav.backup                     ← game-written previous state
Player_Local.sav.backup.meta                ← CRC for .backup

Player_Local.sav.bak                        ← editor baseline (first .bak in this session)
Player_Local.sav.bak.meta                   ← matching CRC, so .bak + .bak.meta is a clean restore pair
Player_Local.sav.20260608-141902.bak        ← editor rotation, named <stem>.<YYYYMMDD-HHMMSS>.bak
Player_Local.sav.20260608-141955.bak
Player_Local.sav.20260608-142013.bak
…

Naming rules:

Pattern Created by Cleaned up by
<stem>.sav the game (and the editor on save) never
<stem>.sav.meta the editor on every write never
<stem>.sav.backup / .backup.meta the game on save the game
<stem>.sav.bak / .bak.meta the editor on the first edit of a session never — always preserved
<stem>.sav.<YYYYMMDD-HHMMSS>.bak the editor on each subsequent edit prune_backups() when retention is set
<stem>.sav.broken-<stamp> the recovery scripts in tools/, just before overwriting never (manual cleanup)

Retention. The toolbar Backups field (default 5) is passed as max_backups to every write. The unstamped <stem>.sav.bak baseline always counts toward the budget and is never deleted. The remaining max_backups − 1 slots are filled with the newest timestamped backups (by mtime); older timestamped backups are deleted. Set the field to blank for unlimited rotation.

Why .bak + .bak.meta together? The game silently reverts to <stem>.sav.backup if a .sav body's CRC doesn't match its .meta. A .bak without a paired .bak.meta is therefore not directly restorable — you'd have to recompute the CRC. The editor pairs them automatically; the recovery scripts in tools/ do the same.

Safety notes

Player vs. world scope

"Repair & Top Off" by default touches only Player_Local.sav. Writing MaxStackCount > 1 to a non-stacking item (most tools / weapons / wearables) in a world chest has caused crashes on the very next load (EXCEPTION_STACK_OVERFLOW from the engine's pickup-spill recursion). The escape-hatch button Top Off SELECTED (incl. world) disables the scope guard; use it on a tiny hand-picked selection only.

The .meta CRC — Everwind's quiet fallback

Every .sav has a sibling .meta containing the decimal-ASCII CRC32 of the .sav body (no trailing newline). The game checks this on load and silently reverts to .backup on mismatch — your edits just vanish without any error. The editor rewrites .meta on every save; if you patch a .sav outside the editor, call everwind_save_edit.update_meta(path) immediately afterwards.

Coherent rollback set

If you ever need to roll back, do every related file (Player_Local.sav, WorldInfo.sav, and every island .sav) to the same point in time. A mixed-time recovery throws Failed to find object 'CharacterSaveData_<num>' warnings followed by an access violation seconds after clicking Continue. The helper scripts in tools/ (notably _rollback_proper.py and _restore_from_backup.py) handle the bookkeeping for you and keep .broken-<timestamp> copies of anything they overwrite.

Save-format limits

  • WorldInfo.sav cargo records use an Amount IntProperty instead of SlotsWithItems / MaxStackCount. They're view + manual cell-edit only; the bulk Repair / Make Max actions skip them by design.
  • Unanchored chests in world saves (containers placed without a BlockActor_… anchor in the file bytes) cannot be reliably distinguished from creature loot bags by the parser alone. The User Only filter therefore hides them by default. Right-click the chest header and pick Flag chest as mine ★ to keep a specific one visible — the flag persists in editor_settings.json.
  • Adding brand-new item slots (rather than editing existing ones) is not implemented. It would require a custom tree walker that updates six nested Size headers and the front-matter type schema. The current GUI only shows the asset path and lets you copy it.

Compatibility

Game version Status
v0.4.658 Verified compatible (2026-06-10). Save format unchanged — same property types, same INV_FIELDS, same container markers. Bundled item_dict.json (from v2026.06.01) still resolves ~95% of item ids; regenerate with extract_game_data.py for full coverage of any new items added since v2026.06.01.
v2026.06.01 Verified compatible. Format unchanged; WorldInfo.sav cargo (Amount field) is read-only by design.
v0.4.515 Worked. The matching item_dict.json for that version is preserved out-of-tree as a .bak.

To regenerate item_dict.json against a new game install, run:

python .\extract_game_data.py "C:\Path\To\Everwind\skyverse\Content\Paks\skyverse-Windows.utoc"

Screenshots

The two screenshots referenced above live in docs/. They are committed after running docs/redact_path.py, which paints over the Save-file Path: field so no real local username or save slot is revealed. See docs/README.md for the workflow.

Contributing

This is a personal save editor; PRs are welcome but priority is given to correctness (don't crash the game) over feature breadth. Please:

  • Keep edits to same-width scalar patches unless you are also rewriting every enclosing Size header.
  • Re-run on a backup save folder, launch the game, click Continue past the main menu, and verify the world loads. The game's worst failure mode is a quiet .backup fallback or a crash on the next Continue click, not an obvious error in the editor.

License

MIT

About

Point-and-click Tk GUI for inspecting and editing Everwind save files (Player_Local.sav, WorldInfo.sav, island .sav).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages