This script converts a .world
file into a .shipworld
file, which will (mostly) be accepted by
the game, meaning that you can now have a planet as your entire ship. You will still have to use
cheats to add in the necessary ship equipement (SAIL console, fuel tank, captain's chair), but they
will all work after placing them down in the world.
The script needs the library py-starbound and
sbutils to be installed. Version 1.0.0 of py-starbound has been
confirmed to work, but the deal with sbutils is a little bit complicated. I got it to work on the
commit https://github.com/xhebox/sbutils/commit/c5d83b0247cacb0789d1e818af74f3c41dc4bbc2 (the latest
commit on the master
branch as of writing), but it needed the following patch:
diff --git a/lib/packet/connect_failure.go b/lib/packet/connect_failure.go
index 8253a3f..d5117d0 100644
--- a/lib/packet/connect_failure.go
+++ b/lib/packet/connect_failure.go
@@ -2,7 +2,7 @@ package packet
import (
"github.com/xhebox/bstruct/byteorder"
- . "github.com/xhebox/sbutils/lib/common"
+ // . "github.com/xhebox/sbutils/lib/common"
)
type ConnectFailurePacket struct {
diff --git a/makebtreedb/main.go b/makebtreedb/main.go
index 229444b..5fc6d78 100644
--- a/makebtreedb/main.go
+++ b/makebtreedb/main.go
@@ -86,6 +86,7 @@ func main() {
keys = append(keys, key)
+ fmt.Println("add:", key)
e = h.Insert(key, buf.Bytes())
if e != nil {
log.Fatalf("%+v\n", e)
@@ -94,14 +95,14 @@ func main() {
h.Commit()
}
- le := len(keys) - 1
- for k := range keys {
- fmt.Println("remove:", keys[le-k])
- e = h.Remove(keys[le-k])
- if e != nil {
- log.Fatalf("%+v\n", e)
- }
-
- h.Commit()
- }
+ // le := len(keys) - 1
+ // for k := range keys {
+ // fmt.Println("remove:", keys[le-k])
+ // e = h.Remove(keys[le-k])
+ // if e != nil {
+ // log.Fatalf("%+v\n", e)
+ // }
+ //
+ // h.Commit()
+ // }
}
Installing py-starbound is easy, pip install --user py-starbound
is enough, with sbutils the
process is as follows:
git clone https://github.com/xhebox/sbutils.git
cd sbutils
git checkout c5d83b0247cacb0789d1e818af74f3c41dc4bbc2 # The known working commit
git apply ../my.patch # Save it to a file or do the changes by hand
go mod init github.com/xhebox/sbutils # The repository uses old Go modules
go mod tidy
(cd dumpbtreedb && go build .)
(cd makebtreedb && go build .)
After that, you may now use the script. Before we start, the commands are for bash on a Linux
system, Starbound is assumed to be installed in ~/starbound
, this script is saved to
~/patch_map_metadata.py
and sbutils
has been cloned in ~/sbutils
. The procedure is as follows:
- Create a new empty directory called
dump
somewhere, let's say in~/starbound/dump
. - Next, locate the file of your chosen donor world. Planets are found in
~/starbound/storage/universe
, their filenames star with the X and Y coordinates of the star system, then comes some ID which I assume to be the ID of the star system, then goes a number which specifies the planet's location in the system. I recommend to check the access and modification timestamps withstat
after teleporting down to the planet to see if the file is what you were looking for. - Now,
cd
into thedump
directory and run~/sbutils/dumpbtreedb/dumpbtreedb -i path/to/the/planet.world
. - This will unpack the world's database into nodes, which contain data in a format which can be
described as simply "binary JSON". We only need to change a single node, whose file is named
data_0000000000
, it contains the metadata block of the world file (world properties, dungeon location, weather parameters etc). - Now the Python script comes into play: run
python ~/patch_map_metadata.py < data_0000000000 > data_0000000000.tmp
and thenmv data_0000000000.tmp data_0000000000
. - The patched metadata node can now be transplanted back into the world file with
~/sbutils/makebtreedb/makebtreedb -d . -i path/to/the/planet.world
. - And, finally, the world file can be set as the player's ship world by doing
mv ~/starbound/storage/universe/x_y_id_n.world ~/starbound/storage/player/xxxxxxxxxxxxxxxx.shipworld
. The operation is a success if the game doesn't segfault upon starting.