Buy now
Get Version 1.1!
When saving a match or map in Castle Story, it creates or overwrites a "savefile", which is actually a folder containing various kinds of data. Editing this data outside of the game allows for interesting results.
Changing save data can cause unexpected issues and possibly corrupt/delete your save file. You modify the data at your own risk.
In order to find your savefile, go to your Castle Story installation directory. On Steam, you can use Castle Story -> Properties -> Browse Local Files. When you're there, go to "Castle Story / Info / Saves".
Before editing a savefile, it is a good idea to make a back-up of it. Just copy the entire folder to a different location, from where you can copy it back into the game if necessary.
When accessing a savefile while using it in-game, it is important to close the savefile entirely before trying to save over it. If the game tries to overwrite a savefile, but the folder is opened in any way (including Windows File Explorer), then it will fail and instead delete the entire file.
Most data is saved as JavaScript Object Notation (json). Editing json requires any text editor. Some data is saved as PNG images. Editing png requires any image editor, preferably one that understands transparency.
This json file contains information regarding the savefile
The heightmap is used not only as a preview of the terrain, it actually is the terrain data. As such, it is possible to change the terrain by changing the heightmap (e.g. copy an island).
Terrain data is encoded using the four PNG channels: Red, Green, Blue and Alpha (Transparency).
Considering the above, higher terrain appears brighter, lower terrain appear darker. The edge of an island appears almost brown, but the inner area of an island has less "red" and more green. The blue is practically not noticable when looking at a heightmap.
In order to edit the individual channels, an advanced image editor is needed. Additive and subtractive layer blend modes might help.
Resources have separate files with similiar formats. Locations (X,Z) are usually measured in pixels from the bottom-left of the heightmap, except for heights (Y), which are measured in 0-255 like the R and G of the heightmap.
Every tree is a separate table with four values: X,Y and Z for location and S for size. The size is a whole number between 1 and 15.
Every plant/grass/herb is a separate table with (up to) five values: X,Y and Z for location, S for size and T for type. The size is a percent value between 0 and 1. The type is assumed to be normal plants. If T is given, the type will instead respond to the whole number of T.
Every voxel/block of ore is a separate table with a "position" sub-table and a "growth" value. The position table contains X, Y and Z. The growth is a percent value between 0 and 1, with 1.0 being a fully-grown chunk of ore.
Every boulder is a separate table with a "positions" array, a "displayPosition" table, a "offset" table and "growth" and "variation" values. "positions" contains empty tables, four if it's a small (2x2) boulder or nine if it's a big (3x3) boulder. "displayPos" contains X,Y and Z of the center-point (float value, because 2x2 boulders have their center inbetween voxels). "offset" contains small X and Z modifiers (float values) between -0.5 and 0.5 voxels. The growth is a percent value between 0 and 1, with 1.0 being a full-sized boulder (not related to whether it's 2x2 or 3x3). "variaton" determines the visual variation of the boulder (which model to use).
Every brick, plank, brace, etc. is a separate table with a "p" table, a "R" table and a "type" value. "p" is the position in X,Y and Z. "R" is the rotation in Quaternion (used by Unity). "type" is the ID number of the block.
You can build in your custom maps using save file editing: First, save the map, then start a sandbox game with it. Now enable debug mode and build. When you are done, save and copy the placedBlocks.json from the sandbox, then place it in the UGC map.[1]
Every block of terrain that has been destroyed is saved in RemovedVoxels.json as a table containing just the X,Y and Z coordinates of the removed block. The voxel may later be populated with placedBlocks or gameobjects.
You can remove voxels in custom maps using save file editing: First, save the map, then start a sandbox game with it. Now enable debug mode and destroy the voxels you don't want. When you are done, save and copy the RemovedVoxels.json from the sandbox, then place it in the UGC map.
There's more data not explained here, but the most important things are mentioned.