This project is written by Claude and Codex and directed by Jeroen.
WARNING: This software is experimental and under active development. Always back up your save files before using this tool. Saves are located in
%APPDATA%/HelloGames/NMS/(Windows) or~/.local/share/Steam/steamapps/compatdata/275850/(Linux/Proton). The authors are not responsible for corrupted or lost save data.
No Man's Sky save editor and toolkit.
The project uses compact tags in docs/changelog entries to make review scope clear:
[DOC]Documentation behavior or wording update
- Full inventory editing (exosuit, ships, multitools, freighter, vehicles, exocraft) with unsigned 32-bit Units support
- Companion/pet editing with gene modification (dynamic trait list, add/remove genes)
- Squadron management with pilot ship selection from player's owned ships
- Frigate fleet management
- 3D corvette builder with game mesh rendering (PyOpenGL)
- 3D entity preview with randomized part selection from game descriptors
- Settlement editing with seed-based ownership, stat write-back, production output, perks, race/address/buildings
- Base part budget table with per-base part counts, wire counts, and sortable columns
- Base library — save, browse, and swap bases from a persistent local library
- Base sorting (move up/down) for teleport menu order
- Base export/import as portable JSON files
- Fossil tracker — pieces across inventories and assembled displays in bases
- Expedition progress, reward filter by expedition, unlock all rewards, offline replay, Twitch/Platform rewards
- Account data editing (account-wide settings)
- Recipe finder with refiner recipe unlock
- Fish finder reference guide
- Milestone and reputation tracking (Gek, Vy'keen, Korvax, guilds)
- Discovery browser with undiscovered-only filter and decoded galactic addresses
- Cross-save vault — store and transfer ships, multitools, and companions between save files
- Discovery backup/restore — save and restore discovery data
- Constellation editor — optimize, reset, backup/restore star map travel lines (NN + 2-opt path optimizer)
- Galaxy atlas HTML export (self-contained single file with portal glyphs and game icons)
- Raw JSON editor for direct save data manipulation
- Game icon extraction and corvette model extraction from PAK files
- Drag-and-drop inventory slot management with adjacency optimization
No seed-accurate rendering. 3D previews use randomized part selection, not seed-based. The NMS modding community deliberately keeps the seed-to-parts mapping private to protect the seed-hunting community. This project follows the same approach — see nms.center.
pip install -e ".[dev]"sudo apt install python3-pyside6.qtcore python3-pyside6.qtgui \
python3-pyside6.qtwidgets python3-pyside6.qtopenglwidgetsFor development/testing, also install:
sudo apt install python3-hypothesis python3-pytestnmstoolkitOr run directly:
python3 -m nmstoolkit.app# Run tests
python3 -m pytest tests/ -q
# Run with coverage
python3 -m pytest tests/ --cov=nmstoolkit- No save data is transmitted by the app.
- Machine-specific absolute paths must never be hardcoded in source, docs, tests, or examples.
- Use user-selected paths, runtime detection, or environment-variable placeholders in documentation.
This section documents how No Man's Sky stores its data and how this toolkit reads and writes it. If you're building your own NMS tools, this is the reference you need.
Save files live in:
- Windows:
%APPDATA%/HelloGames/NMS/st_<steamid>/ - Linux/Proton:
~/.local/share/Steam/steamapps/compatdata/275850/pfx/drive_c/users/steamuser/AppData/Roaming/HelloGames/NMS/st_<steamid>/
Each profile directory contains:
save.hg,save2.hg...save15.hg— save slots (slot 1 =save.hg, slot N =saveN.hg)mf_save.hg,mf_save2.hg... — corresponding metadata filesaccountdata.hg— account-level data (plain JSON, not compressed)
Save files (except accountdata.hg) use a custom LZ4 block compression format:
[Block 1][Block 2]...[Block N]
Each block:
Magic number 4 bytes little-endian 0xFEEDA1E5
Compressed size 4 bytes little-endian
Uncompressed sz 4 bytes little-endian (512KB = 0x80000, except last block)
Padding 4 bytes (zeros)
LZ4 data <compressed_size> bytes
Decompressed content is JSON with a trailing null byte. The JSON keys are obfuscated (3-character codes). A mapping file (jsonmap.txt) translates between obfuscated and readable keys:
F2P → Version
6f= → PlayerStateData
;l5 → Inventory
:No → Slots
b2n → Id
1o9 → Amount
{
"Version": 46002,
"Platform": "PC",
"ActiveContext": "Main",
"BaseContext": {
"PlayerStateData": {
"Inventory": { ... }, // Exosuit general
"Inventory_TechOnly": { ... }, // Exosuit technology
"Inventory_Cargo": { ... }, // Exosuit cargo
"ShipInventory": { ... },
"WeaponInventory": { ... },
"FreighterInventory": { ... },
...
"ShipOwnership": [ ... ], // Array of owned ships
"WeaponOwnership": [ ... ], // Array of owned multitools
...
}
},
"ExpeditionContext": { ... } // Same structure, expedition save
}
Every inventory (exosuit, ship, multitool, freighter, vehicle) follows the same structure:
{
"Slots": [
{
"Type": { "InventoryType": "Substance" },
"Id": "FUEL1",
"Amount": 250,
"MaxAmount": 250,
"DamageFactor": 0,
"Index": { "X": 0, "Y": 0 }
}
],
"ValidSlotIndices": [
{ "X": 0, "Y": 0 },
{ "X": 1, "Y": 0 }
],
"SpecialSlots": [
{
"Type": { "InventorySpecialSlotType": "TechBonus" },
"Index": { "X": 0, "Y": 0 }
}
],
"Width": 6,
"Height": 4
}Inventory types: Substance, Product, Technology
Special slots (supercharged): positions in SpecialSlots with type TechBonus receive an adjacency bonus multiplier. Exosuit tech inventories typically have 3, ships have 4.
Item ID prefixes in saves:
^prefix: marks installed (non-removable) technologies (e.g.,^LASER,^YOURSHIP_LAUNCH)YOURSHIP_*,YOURSUIT_*,YOURMULTI_*,YOURFREIG_*,YOURVEHIC_*: installed base technologies. These are inventory-specific aliases that don't appear in the technology table. Map them to catalogue IDs by stripping the prefix (e.g.,YOURSHIP_LASER→LASER,YOURSHIP_PULSEDRIVE→SHIPJUMP1)UP_*,UA_*,U_*: upgrade modules with tier digits (e.g.,UP_LASER1,UA_HYP3). Map to base tech by prefix (e.g.,UP_LASER→LASER,UA_HYP→HYPERDRIVE)#nnnnnsuffix: procedural generation seed (e.g.,^UP_BOLT4#52847). Strip for icon/catalogue lookup
NMS stores game data in PSARC archives (.pak files) in the GAMEDATA/PCBANKS/ directory. The relevant PAK files:
| PAK File | Contents |
|---|---|
NMSARC.Precache.pak |
Game tables: products, substances, technologies, recipes, seasons, proc tech |
NMSARC.MetadataEtc.pak |
Language/locale files |
NMSARC.TexUI.pak |
UI textures including all item/technology icons (DDS format) |
Standard PSARC archives — no encryption, no custom format. Use any PSARC reader (we use hgpaktool).
Game tables inside PAK files are in .mbin format (compiled binary). Convert to .exml (XML) using MBINCompiler:
MBINCompiler.exe input.mbin # Produces input.MXML (EXML format)On Linux, run MBINCompiler through Wine — the adapter handles this automatically.
EXML files use a flat Property tree with name/value attributes:
<Data template="cGcProductTable">
<Property name="Table">
<Property value="GcProductData.xml">
<Property name="ID" value="FUEL1" />
<Property name="Name" value="UI_FUEL1_NAME" />
<Property name="BaseValue" value="6" />
<Property name="Icon" value="GcResource.xml">
<Property name="Filename" value="TEXTURES/UI/FRONTEND/ICONS/SUBSTANCES/SUBSTANCE.FUEL.1.DDS" />
</Property>
<Property name="Category" value="GcRealitySubstanceCategory.xml">
<Property name="SubstanceCategory" value="Fuel" />
</Property>
<Property name="Type" value="GcProductCategory.xml">
<Property name="ProductCategory" value="Consumable" />
</Property>
<Property name="Requirements">
<Property value="GcTechnologyRequirement.xml">
<Property name="ID" value="CARBON" />
<Property name="Amount" value="50" />
</Property>
</Property>
</Property>
</Property>
</Data>Key patterns:
- Simple fields:
<Property name="ID" value="FUEL1" /> - Nested typed objects:
<Property name="Icon" value="GcResource.xml">with children - Lists: Parent
<Property name="Table">containing entries withvalue="GcTypeName"or_indexattributes - Locale references: Name/description fields contain locale keys (e.g.,
UI_FUEL1_NAME) resolved from language files
The tables extracted and their MBIN paths within NMSARC.Precache.pak:
| Table | MBIN Path | Template |
|---|---|---|
| Products | metadata/reality/tables/nms_reality_gcproducttable.mbin |
cGcProductTable |
| Substances | metadata/reality/tables/nms_reality_gcsubstancetable.mbin |
cGcSubstanceTable |
| Technologies | metadata/reality/tables/nms_reality_gctechnologytable.mbin |
cGcTechnologyTable |
| Proc Tech | metadata/reality/tables/nms_reality_gcproceduraltechnologytable.mbin |
cGcProceduralTechnologyTable |
| Recipes | metadata/reality/tables/nms_reality_gcrecipetable.mbin |
cGcRecipeTable |
| Seasons | metadata/reality/tables/historicalseasondatatable.mbin |
cGcHistoricalSeasonDataTable |
Procedural technology entries reference a base technology Template field. Their icons come from the base tech (e.g., proc tech UP_LASER1 has template LASER, so use LASER's icon).
Locale strings are split across multiple files in NMSARC.MetadataEtc.pak:
language/nms_loc1_english.mbin
language/nms_loc4_english.mbin
language/nms_loc5_english.mbin
language/nms_loc6_english.mbin
language/nms_loc7_english.mbin
language/nms_loc8_english.mbin
language/nms_loc9_english.mbin
language/nms_update3_english.mbin
Each is a cTkLocalisationTable with Id/English pairs. Merge all files to get complete coverage. Replace english with your target language code for localization.
UI language switching is independent of installed game locale files and uses the toolkit's bundled data/i18n catalogues. Game-string localization (item/tech names from game data) still depends on matching language MBINs in NMSARC.MetadataEtc.pak; if unavailable, game strings fall back to English.
Icons are DDS textures stored in NMSARC.TexUI.pak under TEXTURES/UI/FRONTEND/ICONS/. The full pipeline:
NMSARC.TexUI.pak
→ Extract all DDS files under TEXTURES/UI/FRONTEND/ICONS/
→ Convert DDS → PNG thumbnails (64x64, via Pillow)
→ Cache PNGs to disk (flat filenames, e.g. textures_ui_frontend_icons_substances_substance.fuel.1.png)
→ Build icon_map.json: { "FUEL1": "textures/ui/frontend/icons/substances/substance.fuel.1.dds", ... }
Icon map building: Match catalogue items to DDS files by normalizing the icon field from the catalogue entry (strip path separators and extension, lowercase) against DDS basenames. Both exact and fuzzy matching are used.
Icon resolution at runtime (priority order):
- Exact match in
icon_map.json - Strip
#nnnnnprocedural suffix, retry icon_map - Catalogue lookup (exact item ID)
- Catalogue lookup with stripped procedural suffix
YOUR*prefix resolution → lookup resolved IDUP_/UA_/U_upgrade prefix resolution → lookup resolved ID
NMS Install
├── GAMEDATA/PCBANKS/
│ ├── NMSARC.Precache.pak ──→ Extract MBINs ──→ MBINCompiler ──→ EXML ──→ Parse tables
│ │ ├── Products
│ │ ├── Substances
│ │ ├── Technologies
│ │ ├── Proc Tech
│ │ ├── Recipes
│ │ └── Seasons
│ │
│ ├── NMSARC.MetadataEtc.pak ──→ Extract MBINs ──→ MBINCompiler ──→ Locale strings
│ │
│ └── NMSARC.TexUI.pak ──→ Extract DDS ──→ Pillow DDS→PNG ──→ Icon cache
│
└── Merged result: GameCatalogue (JSON) + icon_map.json + cached PNGs
Save Directory
├── st_<steamid>/
│ ├── save.hg ──→ LZ4 decompress ──→ Key unmap ──→ JSON with readable keys
│ ├── save2.hg
│ └── accountdata.hg ──→ Plain JSON (no compression)
| Dependency | Purpose | Required? |
|---|---|---|
| hgpaktool | PSARC/PAK archive reading | Yes, for game data extraction |
| MBINCompiler | MBIN → EXML conversion | Yes, for game data extraction |
| Pillow | DDS → PNG icon conversion | Yes, for icon extraction |
| lz4 | .hg save file compression | Yes, for save read/write |
| PySide6 | GUI framework | Yes, for the editor GUI |
src/nmstoolkit/
├── core/ # Domain layer (pure logic, stdlib + lz4 only)
│ ├── codec.py # .hg LZ4 compress/decompress + key mapping
│ ├── save_file.py # SaveFile model (load/save with key unmapping)
│ ├── save_scanner.py # Find save profiles and slots on disk
│ ├── exml_parser.py # EXML → Python dicts (products, substances, tech, recipes, seasons, locale)
│ ├── game_catalogue.py # GameCatalogue: immutable container for all parsed game data
│ ├── game_data_pipeline.py # Orchestrates PAK → MBIN → EXML → GameCatalogue extraction
│ ├── icon_cache.py # DDS → PNG conversion and disk caching
│ ├── icon_extractor.py # PAK icon extraction + item-to-DDS mapping
│ ├── mesh_data.py # Domain model: Mesh, SceneNode, Transform
│ ├── geometry_parser.py # Binary GEOMETRY.MBIN parser (half-float, packed normals)
│ ├── scene_parser.py # SCENE EXML → SceneNode tree
│ └── corvette_mesh_pipeline.py # Mesh extraction + caching orchestration
│
├── adapters/ # External integrations
│ ├── hgpak_adapter.py # PAK reading via hgpaktool
│ └── mbin_compiler_adapter.py # MBIN→EXML via MBINCompiler (supports Wine on Linux)
│
├── gui/
│ ├── main_window.py # Main application window
│ ├── tabs/ # One tab per editor section
│ │ ├── exosuit_tab.py
│ │ ├── ships_tab.py
│ │ ├── corvette_tab.py # Corvette builder with 2D/3D toggle
│ │ ├── companions_tab.py # Pet editing with gene trait modification
│ │ ├── settlements_tab.py # Settlement stats, production, race/address/buildings
│ │ ├── bases_tab.py # Base storage, budget table, library, export/import
│ │ ├── fossils_tab.py # Fossil pieces and base displays
│ │ ├── expedition_tab.py # Expedition progress, rewards, Twitch/Platform, replay
│ │ ├── discoveries_tab.py # Discovery browser, constellation optimizer
│ │ ├── recipe_finder_tab.py
│ │ ├── milestones_tab.py
│ │ ├── account_tab.py
│ │ ├── freighter_tab.py
│ │ ├── frigates_tab.py
│ │ ├── vehicles_tab.py
│ │ ├── multitools_tab.py
│ │ ├── squadron_tab.py
│ │ ├── fish_finder_tab.py
│ │ └── json_editor_tab.py # 20 tabs total
│ └── widgets/
│ ├── inventory_grid.py # Reusable inventory grid with drag-and-drop
│ ├── slot_editor.py # Single-slot detail editor
│ ├── slot_optimizer.py # Adjacency bonus optimizer
│ ├── icon_provider.py # Item ID → icon resolution with prefix fallbacks
│ ├── corvette_3d_view.py # OpenGL 3D corvette viewport
│ ├── stat_editor.py # Numeric stat spin box
│ ├── enum_selector.py # Enum combo box selector
│ └── seed_editor.py # Hex seed editor
│
├── data/ # Static data files
│ ├── jsonmap.txt # Obfuscated → readable key mapping
│ ├── jsonmapac.txt # Account data key mapping
│ ├── items.json # Static item database (fallback)
│ ├── frigates.json # Frigate trait reference data
│ ├── inventory.json # Inventory structure reference
│ ├── rewards.json # Reward ID reference
│ ├── settlements.json # Settlement reference data
│ ├── words.json # Alien word reference
│ └── templates/ # JSON templates (ship, companion, multitool, slot)
│
└── app.py # Entry point
MIT License - see LICENSE for details.




