A Python toolkit for editing mount save data in Icarus.
Features:
- Transform mount types (Horse to Tusker, etc.)
- Clone mounts with unique IDs
- Reset talent points
Why I Made This My woolly mammoth refused to fight in the desert. Just stood there, overheated and passive, while enemies swarmed our base. In-game solutions failed, and I couldn't install mods on my friends' server. So I asked Claude to help me hack the save files instead. One day later: a working toolkit and a new Ubi mount that fights in the desert.
Note: Renaming mounts can be done in-game, so this tool focuses on operations the game doesn't support.
- Windows (Icarus is a Windows game; Linux users with Proton can use
--fileflag) - Python 3.8+
- No external dependencies
# Clone or download this folder
cd icarus-mount-editor
# No external dependencies required - uses Python 3.8+ standard library onlyThe easiest way to use the editor is via the command-line interface:
# List all your mounts
python mount_cli.py list
# Show detailed info for a mount
python mount_cli.py info 0
# Clone a mount
python mount_cli.py clone 0 "Shadow II"
# Set mount to max level
python mount_cli.py level 0 50
# Transform mount type
python mount_cli.py type 0 Tusker
# Change horse color (A1=brown, A2=black, A3=white)
python mount_cli.py variant 0 A3
# See all available commands
python mount_cli.py --helpThe CLI auto-detects your Steam ID if you only have one Icarus account.
| Command | Description |
|---|---|
list |
List all mounts with type and level |
info <mount> |
Show detailed mount properties |
types |
List available mount types |
validate |
Check mount data integrity |
| Command | Description |
|---|---|
rename <mount> <name> |
Rename a mount |
level <mount> <level> |
Set mount level (1-50) |
type <mount> <type> |
Change mount type |
clone <mount> <name> |
Clone a mount |
delete <mount> |
Delete a mount |
variant <mount> <A1|A2|A3> |
Change horse color variant |
skin <mount> <index> |
Set cosmetic skin index |
reset-talents <mount> |
Reset talents (refund points) |
| Command | Description |
|---|---|
backup |
Create a manual backup |
restore |
List or restore from backup |
config |
Show configuration |
For scripting or advanced usage:
from mount_editor import MountEditor
# Load your mounts (find your Steam ID in your profile URL)
editor = MountEditor(steam_id='YOUR_STEAM_ID')
editor.load()
# List all mounts
for mount in editor.list_mounts():
print(f"[{mount.index}] {mount.name} ({mount.mount_type})")
# Transform to a different type (optionally with a new name)
editor.change_mount_type(0, "Tusker", new_name="Oliphaunt")
# Clone a mount as a different type
editor.clone_mount(0, "Shadowfax Jr", new_type="WoollyMammoth")
# Save changes (creates backup automatically)
editor.save(backup=True)| Type | Key | Description |
|---|---|---|
| Terrenus | Terrenus |
Wild alien creature. Fast, balanced. Tamed from the wild. |
| Horse | Horse |
Actual Earth horse from Workshop. 3 color variants (A1/A2/A3). |
| Moa | Moa |
Fastest mount. Small inventory, two slots. |
| Arctic Moa | ArcticMoa |
Cold-resistant arctic variant of Moa. |
| Buffalo | Buffalo |
Strong, slow mount. Large carrying capacity. |
| Tusker | Tusker |
Slowest but strongest. Found in arctic Styx regions. |
| Zebra | Zebra |
Fast mount similar to Terrenus. |
| Wooly Zebra | WoolyZebra |
Cold-resistant woolly variant of Zebra. |
| Ubi | SwampBird |
Swamp-dwelling bird mount. |
| Woolly Mammoth | WoollyMammoth |
Massive arctic mount with huge carrying capacity. |
Workshop horses are unlocked via talents and come in 3 color variants (all with identical stats):
Workshop_Creature_Horse_A1- Brown horseWorkshop_Creature_Horse_A2- Black horseWorkshop_Creature_Horse_A3- White horse
The color is determined by the AISetupRowName property (e.g., Mount_Horse_Standard_A3).
Stats: HP 1440, Stamina 373, Speed 805, Sprint 1518, Carry 220kg.
| Type | Key | Notes |
|---|---|---|
| Blueback Daisy | BluebackDaisy |
Has skill tree. Summons as follower only. |
| Mini Hippo | MiniHippo |
No skill tree. Quest reward creature. |
| Type | Status |
|---|---|
BP_Mount_Raptor_C |
Blueprint doesn't exist yet |
BP_Mount_Slinker_C |
Blueprint doesn't exist yet |
class MountEditor:
def __init__(self, steam_id: Optional[str] = None)
def load(self) -> None
def save(self, backup: bool = True) -> Path
def list_mounts(self) -> List[MountInfo]
def get_mount(self, index: int) -> MountData
def change_mount_type(self, index: int, new_type: str, new_name: str = None) -> None
def clone_mount(self, source_index: int, new_name: str, new_type: str = None) -> int
def delete_mount(self, index: int) -> None
def set_mount_level(self, index: int, level: int) -> None
def reset_mount_talents(self, index: int) -> int # Returns count reset
def set_horse_variant(self, index: int, variant: str) -> None # A1/A2/A3
def set_cosmetic_skin(self, index: int, skin_index: int) -> None
def validate_mount(self, index: int) -> List[str]from mount_editor import MountEditor, find_property
editor = MountEditor(steam_id='YOUR_STEAM_ID')
editor.load()
mount = editor.get_mount(0)
# Access specific properties
experience = find_property(mount.properties, 'Experience')
# Reset talents using the editor method
reset_count = editor.reset_mount_talents(0)
print(f"Reset {reset_count} talents")
# Set horse variant (Workshop horses only)
editor.set_horse_variant(0, 'A3') # A1=Brown, A2=Black, A3=White
editor.save()All Icarus save data is stored in:
%LocalAppData%\Icarus\Saved\
On Windows, this expands to:
C:\Users\{Username}\AppData\Local\Icarus\Saved\
PlayerData\{SteamID}\
├── Mounts.json # Global mount storage (this tool edits this)
├── Characters\ # Character profiles
├── Prospects\ # Per-session world saves
│ ├── {ProspectName}.json
│ └── ...
└── MetaInventory\ # Workshop/outpost items
Finding your Steam ID:
- Visit steamid.io and enter your profile URL
- Or check the folder names in
PlayerData\- there's usually only one
Mounts.json structure:
{
"SavedMounts": [
{
"DatabaseGUID": "unique-guid",
"MountName": "Horse",
"MountLevel": 25,
"MountType": "Horse",
"MountIconName": "12345",
"RecorderBlob": {
"BinaryData": [/* base64-decoded byte array */]
}
}
]
}The RecorderBlob.BinaryData contains UE4 serialized properties including:
MountName,AISetupRowName,ActorClassNameExperience,Talents,CharacterRecordObjectFName,ActorPathName,IcarusActorGUIDCosmeticSkinIndex(appearance variant)bIsWildTame(wild vs bred flag)
For complete property documentation, see SCHEMA.md.
Mount blueprints are defined in the game's PAK files:
{Steam Library}\steamapps\common\Icarus\Icarus\Content\Paks\
├── pakchunk0-WindowsNoEditor.pak
├── pakchunk0_s1-WindowsNoEditor.pak
├── ...
└── pakchunk0_s28-WindowsNoEditor.pak
Key PAK file: pakchunk0_s18-WindowsNoEditor.pak contains ~80% of mount references.
Valid mount blueprints were identified by scanning game PAK files for BP_Mount_* references.
The test suite includes PAK verification that scans your game installation:
# Run tests including PAK verification
python test_cli.py
# Skip PAK scan for faster testing
python test_cli.py --quick- PAK Scan: Extract all
BP_Mount_*references from game files - AI Setup Check: Verify corresponding
Mount_*AI setup entries exist - In-Game Test: Create test mount with blueprint, load game, verify it appears
- Functionality Test: Confirm mount can be summoned, ridden (if applicable), has correct stats
| Blueprint | AI Setup | In-Game Name | Status |
|---|---|---|---|
| BP_Mount_Horse_C | Mount_Horse | Terrenus | ✅ Rideable (wild tame) |
| BP_Mount_Horse_Standard_C | Mount_Horse_Standard_A* | Horse | ✅ Rideable (workshop) |
| BP_Mount_Moa_C | Mount_Moa | Moa | ✅ Rideable |
| BP_Mount_Arctic_Moa_C | Mount_Arctic_Moa | Arctic Moa | ✅ Rideable |
| BP_Mount_Buffalo_C | Mount_Buffalo | Buffalo | ✅ Rideable |
| BP_Mount_Tusker_C | Mount_Tusker | Tusker | ✅ Rideable |
| BP_Mount_Zebra_C | Mount_Zebra | Zebra | ✅ Rideable |
| BP_Mount_Wooly_Zebra_C | Mount_Zebra_Shaggy | Wooly Zebra | ✅ Rideable |
| BP_Mount_SwampBird_C | Mount_SwampBird | Ubi | ✅ Rideable |
| BP_Mount_WoollyMammoth_C | Mount_WoollyMammoth | Woolly Mammoth | ✅ Rideable |
| BP_Mount_Blueback_Daisy_C | Mount_Blueback_Daisy | Blueback Daisy | |
| BP_Mount_MiniHippo_Quest_C | Mount_MiniHippo | Mini Hippo | |
| BP_Mount_Blueback_C | Mount_Blueback | - | ❌ 1 HP |
| BP_Mount_Raptor_C | Mount_Raptor | - | ❌ No blueprint yet |
| BP_Mount_Slinker_C | Mount_Slinker | - | ❌ No blueprint yet |
- Load
Mounts.jsonand extractRecorderBlob.BinaryData - Parse UE4 binary format into property tree (
FPropertyTagobjects) - Each property has: name, type, size, value (and nested properties for structs)
- Find target property using
find_property() - Modify
prop.valuedirectly - For type changes, update multiple related properties
- Serialize each property to temporary buffer
- Calculate actual byte size from buffer length
- Write size header, then buffer contents
- Encode back to JSON format
- Backups: The editor creates timestamped backups before every save
- Validation: Use
validate_mount()to check data integrity - Game must be closed: Always close Icarus before editing saves
- The mount type may be invalid. Use only types from the "Available Mount Types" table.
- Check for duplicate ObjectFName IDs (clone_mount handles this automatically).
- Stats are inherited from the mount type, not stored in the save.
- Changing type will give you that type's base stats.
- Ensure the game is fully closed before editing.
- Restore from backup if needed (
.backup_YYYYMMDD_HHMMSS.jsonfiles).
- CrystalFerrai/UeSaveGame - The UE4 property serialization in this toolkit was based on concepts from this C# library for reading/writing Unreal Engine save files.
MIT License - See LICENSE
This tool modifies game save files. Use at your own risk. Not affiliated with RocketWerkz or the Icarus development team.
