mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-16 08:36:07 +09:00
adding loadorder to savegame
This commit is contained in:
@@ -65,4 +65,6 @@ module Terrarum {
|
|||||||
exports net.torvald.terrarum.modulebasegame.gameworld;
|
exports net.torvald.terrarum.modulebasegame.gameworld;
|
||||||
exports net.torvald.terrarum.modulebasegame.ui;
|
exports net.torvald.terrarum.modulebasegame.ui;
|
||||||
exports net.torvald.terrarum.modulebasegame.worldgenerator;
|
exports net.torvald.terrarum.modulebasegame.worldgenerator;
|
||||||
|
|
||||||
|
exports net.torvald.terrarum.debuggerapp;
|
||||||
}
|
}
|
||||||
@@ -147,13 +147,12 @@ class SavegameCracker(
|
|||||||
@Command("Lists contents of the disk")
|
@Command("Lists contents of the disk")
|
||||||
fun ls(args: List<String>) {
|
fun ls(args: List<String>) {
|
||||||
letdisk {
|
letdisk {
|
||||||
it.entries.forEach { i, entry ->
|
it.entries.toSortedMap().forEach { (i, entry) ->
|
||||||
if (i != 0L)
|
if (i != 0L) println(
|
||||||
println(
|
ccNoun + i.toString(10).padStart(11, ' ') + " " +
|
||||||
ccNoun + i.toString(10).padStart(11, ' ') + " " +
|
ccNoun2 + (diskIDtoReadableFilename(entry.entryID) + cc0).padEnd(24) { if (it == 0) ' ' else '.' } +
|
||||||
ccNoun2 + (diskIDtoReadableFilename(entry.entryID) + cc0).padEnd(24) { if (it == 0) ' ' else '.' } +
|
ccConst + " " + entry.contents.getSizePure() + " bytes"
|
||||||
ccConst + " " + entry.contents.getSizePure() + " bytes"
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
val entryCount = it.entries.size - 1
|
val entryCount = it.entries.size - 1
|
||||||
println("${cc0}$entryCount entries, total ${it.usedBytes} bytes")
|
println("${cc0}$entryCount entries, total ${it.usedBytes} bytes")
|
||||||
|
|||||||
@@ -236,18 +236,22 @@ class VirtualDisk(
|
|||||||
fun diskIDtoReadableFilename(id: EntryID): String = when (id) {
|
fun diskIDtoReadableFilename(id: EntryID): String = when (id) {
|
||||||
0L -> "root"
|
0L -> "root"
|
||||||
-1L -> "savegameinfo.json"
|
-1L -> "savegameinfo.json"
|
||||||
-2L -> "thumbnail.tga.gz"
|
-2L -> "thumbnail.tga.gz (world)/spritedef (player)"
|
||||||
-16L -> "blockcodex.json.gz"
|
-3L -> "spritedef-glow (player)"
|
||||||
-17L -> "itemcodex.json.gz"
|
-4L -> "loadOrder.txt"
|
||||||
-18L -> "wirecodex.json.gz"
|
// -16L -> "blockcodex.json.gz"
|
||||||
-19L -> "materialcodex.json.gz"
|
// -17L -> "itemcodex.json.gz"
|
||||||
-20L -> "factioncodex.json.gz"
|
// -18L -> "wirecodex.json.gz"
|
||||||
-1024L -> "apocryphas.json.gz"
|
// -19L -> "materialcodex.json.gz"
|
||||||
in 1..65535 -> "worldinfo-$id.json"
|
// -20L -> "factioncodex.json.gz"
|
||||||
in 1048576..2147483647 -> "actor-$id.json"
|
// -1024L -> "apocryphas.json.gz"
|
||||||
|
-1025L -> "bodypart-to-entry.map"
|
||||||
|
-1026L -> "bodypartglow-to-entry.map"
|
||||||
|
in 1..65535 -> "bodypart #$id.tga.gz (player)"
|
||||||
|
in 1048576..2147483647 -> "actor #$id.json"
|
||||||
in 0x0000_0001_0000_0000L..0x0000_FFFF_FFFF_FFFFL ->
|
in 0x0000_0001_0000_0000L..0x0000_FFFF_FFFF_FFFFL ->
|
||||||
"World${id.ushr(32)}-L${id.and(0xFF00_0000).ushr(24)}-C${id.and(0xFFFFFF)}.gz"
|
"World${id.ushr(32)}-L${id.and(0xFF00_0000).ushr(24)}-C${id.and(0xFFFFFF)}.gz"
|
||||||
else -> "file-$id"
|
else -> "file #$id"
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiskEntry(
|
class DiskEntry(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.serialise
|
|||||||
import net.torvald.gdx.graphics.PixmapIO2
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.ItemCodex
|
import net.torvald.terrarum.ItemCodex
|
||||||
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||||
@@ -172,6 +173,16 @@ class WorldSavingThread(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// write loadorder //
|
||||||
|
val loadOrderBa64Writer = ByteArray64Writer(Common.CHARSET)
|
||||||
|
loadOrderBa64Writer.write(ModMgr.loadOrder.joinToString("\n"))
|
||||||
|
loadOrderBa64Writer.flush(); loadOrderBa64Writer.close()
|
||||||
|
val loadOrderText = loadOrderBa64Writer.toByteArray64()
|
||||||
|
val loadOrderContents = EntryFile(loadOrderText)
|
||||||
|
addFile(disk, DiskEntry(-4L, 0L, creation_t, time_t, loadOrderContents))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Echo("Writing file to disk...")
|
// Echo("Writing file to disk...")
|
||||||
|
|
||||||
disk.entries[0]!!.modificationDate = time_t
|
disk.entries[0]!!.modificationDate = time_t
|
||||||
|
|||||||
@@ -2,19 +2,15 @@ package net.torvald.terrarum.serialise
|
|||||||
|
|
||||||
import net.torvald.spriteanimation.AssembledSpriteAnimation
|
import net.torvald.spriteanimation.AssembledSpriteAnimation
|
||||||
import net.torvald.spriteanimation.HasAssembledSprite
|
import net.torvald.spriteanimation.HasAssembledSprite
|
||||||
import net.torvald.spriteanimation.SpriteAnimation
|
|
||||||
import net.torvald.terrarum.spriteassembler.ADProperties
|
|
||||||
import net.torvald.terrarum.ItemCodex
|
import net.torvald.terrarum.ItemCodex
|
||||||
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
|
||||||
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||||
import net.torvald.terrarum.printStackTrace
|
|
||||||
import net.torvald.terrarum.savegame.*
|
import net.torvald.terrarum.savegame.*
|
||||||
|
import net.torvald.terrarum.spriteassembler.ADProperties
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -111,7 +107,13 @@ object WritePlayer {
|
|||||||
addFile(playerDisk, DiskEntry(-3L, 0L, adlGlowCreationDate, time_t, adlGlowContents))
|
addFile(playerDisk, DiskEntry(-3L, 0L, adlGlowCreationDate, time_t, adlGlowContents))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write loadorder //
|
||||||
|
val loadOrderBa64Writer = ByteArray64Writer(Common.CHARSET)
|
||||||
|
loadOrderBa64Writer.write(ModMgr.loadOrder.joinToString("\n"))
|
||||||
|
loadOrderBa64Writer.flush(); loadOrderBa64Writer.close()
|
||||||
|
val loadOrderText = loadOrderBa64Writer.toByteArray64()
|
||||||
|
val loadOrderContents = EntryFile(loadOrderText)
|
||||||
|
addFile(playerDisk, DiskEntry(-4L, 0L, jsonCreationDate, time_t, loadOrderContents))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ The main game directory is composed of following directories:
|
|||||||
- "${PlayerName}-${UUID}", TVDA {
|
- "${PlayerName}-${UUID}", TVDA {
|
||||||
[-1] player JSON,
|
[-1] player JSON,
|
||||||
[-2] spritedef,
|
[-2] spritedef,
|
||||||
[-3] optional spritedef-glow,
|
[-3] !optional! spritedef-glow,
|
||||||
[-1025] sprite-bodypart-name-to-entry-number-map.properties,
|
[-4] loadOrder.txt
|
||||||
[-1026] spriteglow-bodypart-name-to-entry-number-map.properties,
|
[-1025] !optional! sprite-bodypart-name-to-entry-number-map.properties,
|
||||||
[1+] optional bodyparts tga.gz
|
[-1026] !optional! spriteglow-bodypart-name-to-entry-number-map.properties,
|
||||||
|
[1+] !optional! bodyparts tga.gz
|
||||||
}
|
}
|
||||||
*if file -1025 is not there, read bodyparts from assets directory
|
*if file -1025 is not there, read bodyparts from assets directory
|
||||||
*optionally encrypt the files other than -1
|
*optionally encrypt the files other than -1
|
||||||
@@ -27,6 +28,7 @@ The main game directory is composed of following directories:
|
|||||||
[actorID] actors (mainly fixtures) JSON,
|
[actorID] actors (mainly fixtures) JSON,
|
||||||
[0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data,
|
[0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data,
|
||||||
[-2] screenshot.tga.gz taken by the last player
|
[-2] screenshot.tga.gz taken by the last player
|
||||||
|
[-4] loadOrder.txt
|
||||||
}
|
}
|
||||||
*disk name is world's name encoded in UTF-8
|
*disk name is world's name encoded in UTF-8
|
||||||
```
|
```
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
A savegame consists of a Playable Character Information, Savegame Metadata, and other files.
|
|
||||||
A savegame is a single file in the format of TerranVirtualDisk.
|
|
||||||
|
|
||||||
Files contained the TerranVirtualDisk is as follows:
|
|
||||||
|
|
||||||
(root)
|
|
||||||
worldinfo0 -- Savegame Metadata (TESV)
|
|
||||||
Has fixed Entry ID of 32766
|
|
||||||
worldinfo1 -- (TODO Copy of blocks.csv OR BlockCodex in JSON) -- will use this from the next load
|
|
||||||
Has fixed Entry ID of 32765
|
|
||||||
worldinfo2 -- (TODO Copy of items.csv OR ItemCodex in JSON, static only) -- will use this from the next load
|
|
||||||
Has fixed Entry ID of 32764
|
|
||||||
worldinfo3 -- (TODO Copy of materials.csv OR MaterialCodex in JSON) -- will use this from the next load
|
|
||||||
Has fixed Entry ID of 32763
|
|
||||||
world[n] -- Layer Data (TEMD); [n] is a serial number of the world (starts at 1)
|
|
||||||
Has fixed Entry ID of [n]
|
|
||||||
(any random number in Hex ACTORID_MIN..FFFFFFFF) -- Serialised Entity Information (including Player), Entry ID is random
|
|
||||||
(PLAYER_REF_ID in Hex -- 91A7E2) -- Player Character Information (Serialised--JSON'd--Entity Information), Entry ID is random
|
|
||||||
(51621D) -- The Debug Player (Serialised Entity Information), Entry ID is random
|
|
||||||
load_order.txt -- LoadOrder.csv (NOT zipped)
|
|
||||||
Has fixed Entry ID of 32767
|
|
||||||
|
|
||||||
// TODO select one of following:
|
|
||||||
(any random number in Hex 32768..ACTORID_MIN - 1) -- Serialised Dynamic Item?
|
|
||||||
worldinfo4 -- dynamic item codex in JSON, has fixed Entry ID of 32762
|
|
||||||
|
|
||||||
Remarks: world history is created at the load time by scanning all the actors' corresponding ActorValue
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
Savegame metadata
|
|
||||||
|
|
||||||
* Endianness: LITTLE
|
|
||||||
* Filename: 'worldinfo0'
|
|
||||||
|
|
||||||
Ord Hex Description
|
|
||||||
00 54 T
|
|
||||||
01 45 E
|
|
||||||
02 4D S
|
|
||||||
03 44 V
|
|
||||||
|
|
||||||
04 01 Descriptor version number
|
|
||||||
|
|
||||||
05 03 Number of hashes
|
|
||||||
|
|
||||||
06 Name of the world in UTF-8 (arbitrary length, must not contain NULL)
|
|
||||||
n-1 00 String terminator
|
|
||||||
|
|
||||||
(Ord is now offset from n)
|
|
||||||
|
|
||||||
00 Terrain seed (8 bytes)
|
|
||||||
08 Randomiser s0 (8 bytes)
|
|
||||||
10 Randomiser s1 (8 bytes)
|
|
||||||
18 Weather s0 (8 bytes)
|
|
||||||
20 Weather s1 (8 bytes)
|
|
||||||
|
|
||||||
28 ReferenceID of the player (4 bytes, a fixed value of 91A7E2)
|
|
||||||
2C Current world's time_t (the ingame time, 8 bytes)
|
|
||||||
|
|
||||||
34 Creation time in time_t (6 bytes)
|
|
||||||
3A Last play time in time_t (6 bytes)
|
|
||||||
40 Total playtime in time_t (4 bytes) // will record 136.1 years of playtime
|
|
||||||
|
|
||||||
44 SHA-256 hash of worldinfo1 (32 bytes)
|
|
||||||
72 SHA-256 hash of worldinfo2 (32 bytes)
|
|
||||||
A4 SHA-256 hash of worldinfo3 (32 bytes)
|
|
||||||
|
|
||||||
D6 Uncompressed size (2 bytes)
|
|
||||||
D8 Deflated thumbnail image in TGA format
|
|
||||||
p-2 (it's deflated so that it saves faster, so no Lzma)
|
|
||||||
p-2 0xFF
|
|
||||||
p-1 0xFE
|
|
||||||
|
|
||||||
Note: if you're going to add more footer beyond this point, DON'T;
|
|
||||||
instead pack the thumbnail.tga and other footers in TEVD container.
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
Terrarum Game Map Format
|
|
||||||
|
|
||||||
* Endianness: LITTLE
|
|
||||||
|
|
||||||
Ord Hex Description
|
|
||||||
00 54 T
|
|
||||||
01 45 E
|
|
||||||
02 4D M
|
|
||||||
03 7A z # 'z' because it's compressed
|
|
||||||
|
|
||||||
04 03 Version revision number of this format (unreleased numbers also count)
|
|
||||||
|
|
||||||
05 03 Number of layers, NOT the number of payload
|
|
||||||
|
|
||||||
06 05 Number of payloads
|
|
||||||
|
|
||||||
07 01 Compression algorithm, 0 for none, 1 for DEFLATE, 2 for LZMA, otherwise undefined (maybe LZMA2 for the future?)
|
|
||||||
Value of 01 (DEFLATE) is recommended for its faster compression
|
|
||||||
|
|
||||||
08 World generator version. If the generator adds new feature (e.g. new ores, new buildings)
|
|
||||||
09 this number must be incremented by one.
|
|
||||||
|
|
||||||
0A World width
|
|
||||||
0B World width
|
|
||||||
0C World width
|
|
||||||
0D World width
|
|
||||||
|
|
||||||
0E World height
|
|
||||||
0F World height
|
|
||||||
10 World height
|
|
||||||
11 World height
|
|
||||||
|
|
||||||
12 Default spawn coord in Absolute Tile Number
|
|
||||||
13 Default spawn coord in Absolute Tile Number
|
|
||||||
14 Default spawn coord in Absolute Tile Number
|
|
||||||
15 Default spawn coord in Absolute Tile Number
|
|
||||||
16 Default spawn coord in Absolute Tile Number
|
|
||||||
17 Default spawn coord in Absolute Tile Number
|
|
||||||
|
|
||||||
# Payload
|
|
||||||
#
|
|
||||||
# Each layer and other information are stored as a "payload"
|
|
||||||
# A payload is consisted as follows:
|
|
||||||
#
|
|
||||||
# Literal Description
|
|
||||||
# "\0pLd" Payload header [00, 70, 4C, 64]
|
|
||||||
# [4] Identifier. 4 lettres ASCII string
|
|
||||||
# [6] Uncompressed size of DEFLATEd binary (max size 256 TB)
|
|
||||||
# [6] Length of the actual payload (max size 256 TB)
|
|
||||||
# [..] DEFLATEd binary (begins with one of these: 0x789C, 0x78DA, 0x7801)
|
|
||||||
|
|
||||||
|
|
||||||
Payload "TERR" -- world terrain data in Uint16
|
|
||||||
Uncompressed size will be 2x of (width * height)
|
|
||||||
|
|
||||||
Payload "WALL" -- world walls data in Uint16
|
|
||||||
Uncompressed size will be 2x of (width * height)
|
|
||||||
|
|
||||||
Payload "TdMG" -- world terrain damage data, array of: (Int48 tileAddress, Float32 damage)
|
|
||||||
Uncompressed size will be arbitrary (multiple of tens)
|
|
||||||
|
|
||||||
Payload "WdMG" -- world walls damage data, array of: (Int48 tileAddress, Float32 damage)
|
|
||||||
Uncompressed size will be arbitrary (multiple of tens)
|
|
||||||
|
|
||||||
Payload "FlTP" -- world fluid types, array of: (Int48 tileAddress, Signed Int16 type)
|
|
||||||
Uncompressed size will be arbitrary (multiple of eights)
|
|
||||||
|
|
||||||
Payload "FlFL" -- world fluid fills, array of: (Int48 tileAddress, Float32 amount)
|
|
||||||
Uncompressed size will be arbitrary (multiple of tens)
|
|
||||||
If the 'amount' < 0.0001f (WorldSimulator.FLUID_MIN_MASS), the entry must be discarded
|
|
||||||
|
|
||||||
Payload "WiNt" -- wiring nodes, in JSON format
|
|
||||||
|
|
||||||
Payload "TMaP" -- tile number to name map, array of: (Int32, tileNumber, String itemID)
|
|
||||||
String is null-terminated byte array
|
|
||||||
|
|
||||||
TODO need a format that can store arbitrary number of conduits, not just limited to 32
|
|
||||||
|
|
||||||
/*Payload "CtYP" -- conduit types, array of: (Int48 tileAddress, Uint32 bitarray)
|
|
||||||
can hold 32 different wires simultaneously
|
|
||||||
|
|
||||||
Payload "CfL0" -- conduit fills, aka size of liquid/gas packet, array of: (Int48 tileAddress, Float32 fill)
|
|
||||||
CfL0..CfL9, CfLa..CfLf are available to store values for 16 different things.*/
|
|
||||||
|
|
||||||
|
|
||||||
EOF 45 E
|
|
||||||
EOF 6E n
|
|
||||||
EOF 64 d
|
|
||||||
EOF 54 T
|
|
||||||
EOF 45 E
|
|
||||||
EOF 4D M
|
|
||||||
EOF FF Byte order mark
|
|
||||||
EOF FE Byte order mark
|
|
||||||
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
## Savegame Structure
|
|
||||||
|
|
||||||
- The Savegame is a TerranVirtualDisk archive that stores multiple files in the disk's root directory
|
|
||||||
- Savegame stores metadata, Worlds and Actors in the game
|
|
||||||
- A player gets one unique Savegame
|
|
||||||
- A player can have Multiple worlds
|
|
||||||
- Worlds are identified using integer ranged 1 through 32767 (inclusive)
|
|
||||||
- Actor ID is unique within the scope of the Savegame
|
|
||||||
- A World stores list of Actor IDs that resides in the world
|
|
||||||
|
|
||||||
|
|
||||||
### File Structure
|
|
||||||
|
|
||||||
Each file on the Savegame has following convention:
|
|
||||||
|
|
||||||
|Type|Filename|ID|
|
|
||||||
|---|---|---|
|
|
||||||
|Metadata|savegame|-1|
|
|
||||||
|Blocks Properties|blocks|-16|
|
|
||||||
|Items Properties|items|-17|
|
|
||||||
|Wires Properties|wires|-18|
|
|
||||||
|Materials Properties|materials|-19|
|
|
||||||
|Factions Properties|factions|-20|
|
|
||||||
|Other Properties used by modules|modprops|-1024|
|
|
||||||
|Worlds|world$n ($n is a world index)|$n|
|
|
||||||
|Actors|actor$n ($n is an Actor ID)|$n|
|
|
||||||
|
|
||||||
User formats can have ID of -2147483648..-65536
|
|
||||||
|
|
||||||
### Solving Problems
|
|
||||||
|
|
||||||
#### How do I determine which world to read in?
|
|
||||||
|
|
||||||
Load the player (always has the entry ID of 9545698) and the property "worldCurrentlyPlaying" should
|
|
||||||
contain an integer that is a world index. Only the actors that are instance of IngamePlayer will have
|
|
||||||
the property.
|
|
||||||
|
|
||||||
|
|
||||||
### Save File Examples
|
|
||||||
|
|
||||||
Following code is an example Savegame JSON files.
|
|
||||||
|
|
||||||
#### savegame.json
|
|
||||||
```
|
|
||||||
{
|
|
||||||
savename: "Test World 1",
|
|
||||||
genver: 0x00030001, /* generator version in integer; always use TerrarumAppConfiguration.VERSION_RAW */
|
|
||||||
terrseed: "84088805e145b555",
|
|
||||||
randseed: "19b25856e1c150ca834cffc8b59b23ad",
|
|
||||||
weatseed: "e5e72beb4e3c6926d3dc9e3e2ef7833b",
|
|
||||||
playerid: 9545698,
|
|
||||||
creation_t: <creation time in real-world unix time>,
|
|
||||||
lastplay_t: <last play time in real-world unix time>,
|
|
||||||
playtime_t: <total play time in real-world unix time>,
|
|
||||||
thumb: <Ascii85-encoded gzipped thumbnail image in TGA>,
|
|
||||||
loadorder: <LoadOrder serialised>,
|
|
||||||
worlds: [1,2,6,7]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### world1.json
|
|
||||||
|
|
||||||
File is named as `"world"+world_index+".json"`.
|
|
||||||
The fields are auto-generated by GDX's JSON serialiser.
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
worldName: "New World",
|
|
||||||
worldIndex: 1,
|
|
||||||
width: 9000,
|
|
||||||
height: 2250,
|
|
||||||
spawnX: 4500,
|
|
||||||
spawnY: 248,
|
|
||||||
creationTime: 1629857065,
|
|
||||||
lastPlayTime: 1629857065,
|
|
||||||
totalPlayTime: 0,
|
|
||||||
layerTerrain: {
|
|
||||||
h: <SHA-256 hash of 'b'>,
|
|
||||||
b: <Ascii85-encoded gzipped terrain layerdata>,
|
|
||||||
x: 9000,
|
|
||||||
y: 2250
|
|
||||||
},
|
|
||||||
layerWall: {
|
|
||||||
h: <SHA-256 hash of 'b'>,
|
|
||||||
b: <Ascii85-encoded gzipped wall layerdata>,
|
|
||||||
x: 9000,
|
|
||||||
y: 2250
|
|
||||||
},
|
|
||||||
wallDamages:{},
|
|
||||||
terrainDamages: {},
|
|
||||||
fluidTypes: {}
|
|
||||||
fluidFills: {},
|
|
||||||
wirings: {},
|
|
||||||
wiringGraph: {},
|
|
||||||
gravitation: {y:9.8}
|
|
||||||
globalLight: {
|
|
||||||
r:0.8826928,
|
|
||||||
g:0.8901961,
|
|
||||||
b:0.9055425,
|
|
||||||
a:0.93691504
|
|
||||||
},
|
|
||||||
averageTemperature: 288,
|
|
||||||
generatorSeed: 0,
|
|
||||||
worldTime: 27874,
|
|
||||||
tileNumberToNameMap: {},
|
|
||||||
extraFields: {},
|
|
||||||
genver: 4
|
|
||||||
comp: 1
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### actors.json
|
|
||||||
|
|
||||||
The fields are auto-generated by GDX's JSON serialiser.
|
|
||||||
|
|
||||||
```
|
|
||||||
[
|
|
||||||
{ /* actor serialised in JSON *
|
|
||||||
class: "net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer", /* depends on the actor */
|
|
||||||
referenceID: 1342111743,
|
|
||||||
actorValue: { /* actorValue serialised in JSON */ },
|
|
||||||
hitbox: ...,
|
|
||||||
...
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
47
work_files/DataFormats/terrarum_advanced_lang_file.txt
Normal file
47
work_files/DataFormats/terrarum_advanced_lang_file.txt
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
# example lang file
|
||||||
|
|
||||||
|
meta language:fiFI
|
||||||
|
meta nounclasslabel:nom,par,accnom,accgen,gen,iness,ela,illa,adess,abla,alla,ess,trans,inst,abess,comit,pnom,ppar,paccnom,paccgen,pgen,piness,pela,pilla,padess,pabla,palla,pess,ptrans,pinst,pabess,pcomit
|
||||||
|
meta nounseries:follow-nounclasslabel # basically tells the parser that 'nounclasslabel' has everything you need
|
||||||
|
CONTERT_HOUSE_NOUN:talo,taloa,talo,talon,talon,talossa,talosta,taloon,talolla,talolta,talolle,talona,taloksi,,talotta,,talot,taloja,talot,talot,talojen,taloissa,taloista,taloihin,taloilla,taloilta,taloille,taloina,taloiksi,taloin,taloitta,taloineen
|
||||||
|
CONTEXT_GO_TO_VERB:mennä <1:illa> # with CONTERT_HOUSE_NOUN: "mennä taloon"
|
||||||
|
|
||||||
|
|
||||||
|
meta language:koKR
|
||||||
|
meta nounclasslabel:use korean # built-in automation for korean
|
||||||
|
meta nounseries:undefined # the grammar of this language does not take noun's count into account
|
||||||
|
CONTEXT_HOUSE_NOUN:집
|
||||||
|
CONTEXT_TOWARDS_VERB:<1>{1:로,으로,로} 가기 # when 'korean' is used for nounclasslabel, the character code of the hangul letter is taken into account. GIVEN_WORD_SET.get(i), where i = ((char - 44032) % 28 == 0) ? 0 : ((char - 44032) % 28 == 8) 2 : 1
|
||||||
|
|
||||||
|
|
||||||
|
meta language:enUS
|
||||||
|
meta nounseries:singular-plural # tells the parser that first element is singular, and the second is plural
|
||||||
|
CONTEXT_HOUSE_NOUN:House,Houses
|
||||||
|
CONTEXT_TOWARDS_VERB:Go to <1>
|
||||||
|
|
||||||
|
|
||||||
|
meta language:frFR
|
||||||
|
meta nounclasslabel:m,f,pm,pf,vm,vf
|
||||||
|
meta nounseries:singular-plural # tells the parser that first element is singular, and the second is plural
|
||||||
|
CONTEXT_COVID_NOUN:f:Covid,Covid
|
||||||
|
CONTEXT_INTERNATIONALE_NOUN:vf:Internationale,Internationale
|
||||||
|
CONTEXT_THE_STH:{1:Le ,La ,L’,L’}<1> # with CONTEXT_COVID_NOUN: "La Covid"; with CONTEXT_INTERNATIONALE_NOUN: "L’Internationale"
|
||||||
|
|
||||||
|
|
||||||
|
meta language:la
|
||||||
|
meta nounclasslabel:m,f,n
|
||||||
|
meta nounseries:singular-plural # tells the parser that first element is singular, and the second is plural
|
||||||
|
CONTEXT_CHICKEN_NOUN:m:Gallus,Galli
|
||||||
|
CONTEXT_VERITAS_NOUN:f:Veritas,Veritates
|
||||||
|
CONTEXT_X_IS_MY_LIGHT:<1:plural> lux {1:meus,mea,meum} # 'plural' is pre-defined name that comes with 'singular-plural' nounseries
|
||||||
|
|
||||||
|
|
||||||
|
## the preamble
|
||||||
|
|
||||||
|
meta nounclasslabel:m,f,n,mp,fp,np # for german: masculine singular, feminine singular, neuter singular, masculine plural, feminine plural, neuter plural
|
||||||
|
|
||||||
|
meta nounclasslabel:m,f,n,md,fd,nd,mp,fp,np # for sanskrit: masc./fem./neu. singular, dual and plural
|
||||||
|
|
||||||
|
meta nounclasslabel:use korean # a pragma to use built-in automation labeled 'korean'
|
||||||
|
|
||||||
Reference in New Issue
Block a user