Extract data from a .CivBeyondSwordSave file
Project description
Civ4Save
Parse the data in a .CivBeyondSwordSave
file.
Currenly only vanilla BTS saves are supported (No mods). Once the remaining parsing bugs are ironed out I will work to support the most popular mods (BAT, BUG).
Thanks to this repo for hosting the Civ4 BTS source. Wouldn't have been possible to make this without it.
Usage
Install
- Requires >= python3.7
python -m pip install civ4save
Command line Tool
$ civ4save --help
Usage: civ4save [OPTIONS] COMMAND [ARGS]...
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
civs Show details for a Civ or list all Civs.
gamefiles Find and print relevant game files paths.
leaders Show Leader or list Leaders optionally sorted by attribute.
parse Parse a .CivBeyondSwordSave file.
xml Generate python code or JSON from the XML files.
$ civ4save parse --help
Usage: civ4save parse [OPTIONS] FILE
Parse a .CivBeyondSwordSave file.
FILE is a save file or directory of save files
Options:
--settings Basic settings only. Nothing that would be unknown to the
human player
--spoilers Extra info that could give an advantage to human player
--player INTEGER Only show data for a specific player idx. Defaults to the
human player
--list-players List all player (idx, name, leader, civ) in the game
--json Format output as JSON. Default is text
--help Show this message and exit.
gamefiles
command works on both Linux and Windows.
$ civ4save gamefiles
Game Folder
-----------
/home/dan/.local/share/Steam/steamapps/common/Sid Meier's Civilization IV Beyond the Sword
Saves Folder
------------
/home/dan/.local/share/Steam/steamapps/compatdata/8800/pfx/drive_c/users/steamuser/My Documents/My Games/Beyond the Sword/Saves/single
XML Folder
----------
/home/dan/.local/share/Steam/steamapps/common/Sid Meier's Civilization IV Beyond the Sword/Beyond the Sword/Assets/XML
The xml
command can transform the XML files into other datatypes.
It does not make any changes to your XML files, just reads them.
$ civ4save xml --help
Usage: civ4save xml [OPTIONS]
Generate python code or JSON from the XML files.
Options:
--enums Transform XML files into Python Enums.
--text-map Create JSON mapping TEXT_KEY to LANG. Default is English.
--lang [English|French|German|Italian|Spanish]
Language to map TEXT_KEY's to
--help Show this message and exit.
--enums
could be useful for developers/modders, I used it to make this project.
It locates the XML files (Vanilla, Warlords, BTS), reads each file, and transforms
it into a python enum. BTS takes precendence over Warlords and Warlords over Vanilla
if 2 XML files have the same name.
The enums are written to stdout. Ex. civ4save xml --enums > enums.py
to save them to a file.
--text-map
creates a simple JSON object mapping each TEXT_KEY*
human presentable text
in the given --lang
. I use this in the contrib
package to make some of the Civ and Leader
attributes more readable.
As a Libray
from civ4save import SaveFile
# SaveFile takes 2 args:
# file: str | Path (required)
# debug: bool (default False, prints hidden fields)
save = SaveFile('Rome.CivBeyondSwordSave')
save.raw # raw construct.Struct, use to create your own wrapper objects
save.settings # civ4save.objects.Settings
save.players # dict[int, civ4save.objects.Player]
save.game_state # civ4save.objects.GameState
save.get_player(0) # Returns civ4save.objects.Player
# The plots take a few seconds to parse as there are thousands of them so they
# only get parsed when accessed. Afterwards they are cached so access is fast again
save.get_plot(x=20, y=20) # Returns civ4save.objects.Plot
for plot in save.plots:
print(plot.owner, plot.improvement_type)
Development / Contributing
python -m pip install ".[dev]"
to install in editable mode along with all dev deps.
python -m pytest tests/
to run the tests.
Or you can use the ./run.sh
script if you use bash.
./run.sh install dev
./run.sh tests
./run.sh c4 --help
./run.sh clean
./run.sh build
How it Works
Games are saved in a what's basically a memory dump that kind of looks like a sandwich.
| uncompressed data | zlib compressed data | uncompressed data + checksum |
The SaveFile
class handles all of the decompression stuff as well as the parsing using the
construct library.
If you want to see the actual binary structure of the save file see src/civ4save/vanilla/structure.py
.
Write Order
The game calls its ::write
functions in this order when saving:
- CvInitCore (done)
- CvGame (done)
- CvMap (done)
- CvPlot (buggy/inconsistent)
- CvArea (under construction)
- CvTeam (not implemented)
- CvPlayer (not implemented)
Plots Bug
For some unknown reason save files larger than 136KB (largest I have that doesn't encounter the bug)
parsing fails about half through the plots array. pass debug=True
to SaveFile
to see details when parsing
a large save file and you'll get detailed debugging output.
TODO
- Click mutually exclusive group plugin for more robust cli arg handling
- Better docs
SaveFile
needs a loggersrc/civ4save/objects/*
all need testsxml_files.py
needs tests- Caching of parsed saves (probably using dataclasses_json)
- Textual UI for browsing saves in a directory
- maybe a
send to trash
button to make it easy to clean out unwanted saves
- maybe a
- Diffing tools to tell what changed between 2 saves/autosaves
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file civ4save-0.7.0.tar.gz
.
File metadata
- Download URL: civ4save-0.7.0.tar.gz
- Upload date:
- Size: 181.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 72bb10a83078bd3ecdea6562c24d7fbf64a801128c9a341536417f3be14b4e7e |
|
MD5 | 197086afef3c943170e4ce9e8559460a |
|
BLAKE2b-256 | 04702287647e41f45de2a88a8515173b8d763169c8600a1d55f50686d29f979a |
File details
Details for the file civ4save-0.7.0-py3-none-any.whl
.
File metadata
- Download URL: civ4save-0.7.0-py3-none-any.whl
- Upload date:
- Size: 160.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ce14c2f55dbe834a7742cf659204f5e49428289cb22e0488fc0b3ed15aed3b6b |
|
MD5 | 40b47a6f3dbef34efa1937bad11e84c5 |
|
BLAKE2b-256 | b80de8c58b91043f538d007def9aea25cc47cb8b88d3a94b1e5210bf0841efa2 |