A small, self-contained editor for DragonSword Awakening (2026) save files. It decrypts the game's SQLCipher save database, lets you browse and edit any table in a local browser UI, and writes it back in a format the game reads unchanged.
Pure Go, no CGO — a single static binary that cross-compiles to Windows and Linux.
# from a dev shell (Nix): nix develop
go run ./cmd/dsa-save-editor /path/to/<accountId>_Slot<N>.dbor with Nix, no checkout of toolchains needed:
nix run .#default -- /path/to/6144_Slot1.db # Linux
nix build .#windows # produces a Windows .exeThe editor opens http://127.0.0.1:<port>/ in your browser with two tabs:
-
Editor — a friendly, game-oriented view:
- Currency and Consumables with quantity steppers. Consumables are grouped into curated functional categories (Ingredients, Breakthrough, Awakening, Skill, Crafting, Runes, Gear XP, Exchange, Potions, Cooked food, and an Unsorted catch-all) shown in a category sidebar; each category lists every item — owned or not — so any can be set from 0 to X, with a per-category fill.
- Characters and Team — read-only reference views (levels, squads).
- Equipment and Gems — edit enchant level, item XP and lock; stat references are shown read-only.
- Cooking — a recipe book: a grid of dish cards (known / locked) and a detail panel with the dish's eat-effect, its required ingredients (icons + owned/required counts), and a per-recipe known/lock toggle — plus a key-accurate "unlock all".
- Costumes and Familiers — unlock cosmetics and mounts and assign them to characters: costumes (outfits + weapon skins) are non-exclusive per character; mounts are one per character. Each screen lists what's owned plus a catalog of the not-yet-owned to unlock.
- Titles — a checklist of the 108 account titles (
tb_titlebitmask): each row shows a colour dot, name and stat bonus, with a per-title checkbox and an unlock-all button (the displayed title is left untouched).
Item, character and equipment names and icons come from a bundled catalog datamined by th.gl — names in French & English, switchable with the FR/EN toggle in the header — plus category inference and your own labels (✎).
-
Database (advanced) — the raw
tb_*table browser: double-click any non-key cell to edit it.
Make changes in either tab, then Write to save file.
Close the game before writing. The running game keeps the database open and would overwrite your changes. A timestamped backup of the original (
<save>.<timestamp>.bak) is created automatically the first time you write.
Save files live at:
.../DragonSword Awakening/DS/Saved/SaveGames/<accountId>/<accountId>_Slot<N>.db
A full, community-oriented reference of the save format — file layout, encryption, the
database schema, the content-ID scheme, and the switch/recipe encoding — lives under
docs/.
The .db is an SQLCipher v4 encrypted SQLite database
(PRAGMA cipher_compatibility = 4):
| parameter | value |
|---|---|
| cipher | AES-256-CBC |
| page size | 4096 (first 16 bytes = salt) |
| KDF | PBKDF2-HMAC-SHA512, 256000 iterations |
| page integrity | HMAC-SHA512 (16-byte IV + 64-byte MAC per page) |
The passphrase is a hardcoded constant, identical for every save:
13314374259236352028
The client embeds the string
x'1f86483d109b44e81d31181f14b2bba014cf8a174b4fa7f3fe666f075c2ae6c0', hashes its
UTF-16 code units with FNV-1a-64 (offset basis 0xcbf29ce484222325, prime
0x100000001b3), and renders the result as a decimal string via %llu — the game
then calls PRAGMA key = '<that number>'. internal/sqlcipher/key.go reproduces
this derivation, so the key is documented rather than merely pasted.
internal/sqlcipher/ pure-Go SQLCipher v4 decrypt/encrypt + key derivation
internal/save/ decrypt → edit via modernc.org/sqlite → re-encrypt (+ backup)
internal/domain/ typed game view (currencies, consumables) + item catalog
internal/web/ embedded browser UI + JSON API (/api/*, /api/game/*)
cmd/dsa-save-editor/ CLI entry point (opens the save, serves the UI)
The crypto layer only depends on the Go standard library; editing uses the pure-Go
modernc.org/sqlite driver. No component
requires CGO.
nix develop # dev shell: go, staticcheck, just, nixfmt, pre-commit…
just # list recipes
just ci # gofmt + vet + staticcheck + go test + go build
just check # nix flake check (build + go test + gofmt)
pre-commit install # run the gates automatically before each commitjust is the single source of truth for the gates; pre-commit, nix flake check
and the release workflow reuse them. There is no build/PR CI by choice — the only
GitHub workflow is the release below.
Ready-made binaries are attached to every
release:
dsa-save-editor-<version>-linux-amd64,
dsa-save-editor-<version>-windows-amd64.exe and a SHA256SUMS to check them.
Pushing a v* tag runs .github/workflows/release.yml, which — inside the Nix dev
shell, with the same just recipes used locally — runs the gates, builds both
binaries stamped with the tag, and publishes the release using that version's
CHANGELOG.md section as the notes. So the changelog (just changelog) is
regenerated and committed before tagging.
go test ./... # unit tests
DSA_SAVE=/path/to/6144_Slot1.db go test ./... # also exercises a real saveThe DSA_SAVE-gated tests decrypt a real file, verify the plaintext is valid
SQLite, and confirm an edit round-trips back through the encrypted format.
Item, character and equipment names and icons are datamined by
The Hidden Gaming Lair (th.gl) and bundled as
internal/domain/data/items.json (names + icon positions) and
internal/web/static/sprite.webp (the icon sprite sheet). Regenerate both with
just gen-catalog (cmd/gen-catalog).
Item names/categories/grades and the cooking recipes (recipes.json) are also
datamined from the game's own data XML inside the paks: cmd/pak-dump extracts the XML
in pure Go, cmd/pak-catalog converts it. The extracted XML is game-copyright and lives
under tmp/ (never committed); only the derived data is bundled. All names, icons and
recipe data are © their respective owners.
For personal, offline single-player use. Editing saves can corrupt progress and may violate the game's terms of service; keep the automatic backups.