diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index 6968aae2..a530fe06 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -27,6 +27,9 @@
* [Datatypes](engine/datatypes.md)
* Formats
* [ZenGin Animations](engine/formats/animation.md)
+ * ZenGin Scripts
+ * [Script Binaries](engine/formats/script_binaries.md)
+ * [Daedalus Bytecode](engine/formats/bytecode.md)
* [ZenGin Font](engine/formats/font.md)
* [ZenGin Texture](engine/formats/texture.md)
* [ZenGin Virtual File System](engine/formats/vdf.md)
diff --git a/docs/engine/formats/bytecode.md b/docs/engine/formats/bytecode.md
new file mode 100644
index 00000000..b9b7e821
--- /dev/null
+++ b/docs/engine/formats/bytecode.md
@@ -0,0 +1,137 @@
+# ZenGin Bytecode
+
+Bytecode is read from [`DatFile.bytecode`](./script_binaries.md#format-description) field
+
+```c title="Bytecode Buffer"
+struct Bytecode {
+ Instruction instructions[/* Read until there is no bytes left in the buffer */]
+};
+```
+
+## Instruction
+
+```c title=""
+struct Instruction {
+ Opcode opcode,
+ InstructionData data,
+};
+```
+
+### Opcode
+
+??? "enum Opcode: uint { ... }"
+
+ Unused variants are commented out
+ ```c title=""
+ enum Opcode: uint {
+ zPAR_OP_PLUS = 0,
+ zPAR_OP_MINUS = 1,
+ zPAR_OP_MUL = 2,
+ zPAR_OP_DIV = 3,
+ zPAR_OP_MOD = 4,
+ zPAR_OP_OR = 5,
+ zPAR_OP_AND = 6,
+ zPAR_OP_LOWER = 7,
+ zPAR_OP_HIGHER = 8,
+ zPAR_OP_IS = 9,
+ zPAR_OP_LOG_OR = 11,
+ zPAR_OP_LOG_AND = 12,
+ zPAR_OP_SHIFTL = 13,
+ zPAR_OP_SHIFTR = 14,
+ zPAR_OP_LOWER_EQ = 15,
+ zPAR_OP_EQUAL = 16,
+ zPAR_OP_NOTEQUAL = 17,
+ zPAR_OP_HIGHER_EQ = 18,
+ zPAR_OP_ISPLUS = 19,
+ zPAR_OP_ISMINUS = 20,
+ zPAR_OP_ISMUL = 21,
+ zPAR_OP_ISDIV = 22,
+ // zPAR_OP_UNARY = 30,
+ zPAR_OP_UN_PLUS = 30,
+ zPAR_OP_UN_MINUS = 31,
+ zPAR_OP_UN_NOT = 32,
+ zPAR_OP_UN_NEG = 33,
+ // zPAR_OP_MAX = 33,
+ // zPAR_TOK_BRACKETON = 40,
+ // zPAR_TOK_BRACKETOFF = 41,
+ // zPAR_TOK_SEMIKOLON = 42,
+ // zPAR_TOK_KOMMA = 43,
+ // zPAR_TOK_SCHWEIF = 44,
+ zPAR_TOK_NONE = 45,
+ // zPAR_TOK_FLOAT = 51,
+ // zPAR_TOK_VAR = 52,
+ // zPAR_TOK_OPERATOR = 53,
+ zPAR_TOK_RET = 60,
+ zPAR_TOK_CALL = 61,
+ zPAR_TOK_CALLEXTERN = 62,
+ // zPAR_TOK_POPINT = 63,
+ zPAR_TOK_PUSHINT = 64,
+ zPAR_TOK_PUSHVAR = 65,
+ // zPAR_TOK_PUSHSTR = 66,
+ zPAR_TOK_PUSHINST = 67,
+ // zPAR_TOK_PUSHINDEX = 68,
+ // zPAR_TOK_POPVAR = 69,
+ zPAR_TOK_ASSIGNSTR = 70,
+ zPAR_TOK_ASSIGNSTRP = 71,
+ zPAR_TOK_ASSIGNFUNC = 72,
+ zPAR_TOK_ASSIGNFLOAT = 73,
+ zPAR_TOK_ASSIGNINST = 74,
+ zPAR_TOK_JUMP = 75,
+ zPAR_TOK_JUMPF = 76,
+ zPAR_TOK_SETINSTANCE = 80,
+ // zPAR_TOK_SKIP = 90,
+ // zPAR_TOK_LABEL = 91,
+ // zPAR_TOK_FUNC = 92,
+ // zPAR_TOK_FUNCEND = 93,
+ // zPAR_TOK_CLASS = 94,
+ // zPAR_TOK_CLASSEND = 95,
+ // zPAR_TOK_INSTANCE = 96,
+ // zPAR_TOK_INSTANCEEND = 97,
+ // zPAR_TOK_NEWSTRING = 98,
+ zPAR_TOK_FLAGARRAY = zPAR_TOK_VAR + 128
+ };
+ ```
+
+### Instruction Data
+
+Depending on `opcode` the data may be different or in most cases 0 sized.
+
+=== "CALL, JUMPF, JUMP"
+
+ ```c title=""
+ struct InstructionData {
+ uint address;
+ };
+ ```
+
+=== "PUSHINT"
+
+ ```c title=""
+ struct InstructionData {
+ int immediate;
+ };
+ ```
+
+=== "CALLEXTERN, PUSHVAR, PUSHINST, SETINSTANCE"
+
+ ```c title=""
+ struct InstructionData {
+ uint symbol;
+ };
+ ```
+
+=== "PUSHVAR + FLAGARRAY"
+
+ ```c title=""
+ struct InstructionData {
+ uint symbol;
+ byte index;
+ };
+ ```
+
+=== "any other"
+
+ ```c title=""
+ struct InstructionData {};
+ ```
+
diff --git a/docs/engine/formats/script_binaries.md b/docs/engine/formats/script_binaries.md
new file mode 100644
index 00000000..d3695d72
--- /dev/null
+++ b/docs/engine/formats/script_binaries.md
@@ -0,0 +1,170 @@
+# ZenGin Script Binaries
+
+!!! abstract inline end "Quick Infos"
+ **Type:** Script Format
+ **Format Name:** DAT
+ **File Extension:** `.DAT`
+ **Class Name:** `zCParser`
+ **Encoding:** [Binary](../encodings/binary.md)
+
+*ZenGin* DAT files contain symbols and [bytecode](./bytecode.md) used by the VM of the engine.
+DAT files are the result of Daedalus script compilation process.
+
+## Format Description
+
+Compiled scripts are stored in a [binary](../encodings/binary.md) file which contains the following data. Also refer to the
+[Datatype Reference](../datatypes.md) for general information about often used datatypes.
+
+```c title="DAT Structure"
+struct DatFile {
+ byte version;
+
+ uint symbolCount;
+ uint symbolIds[/* symbolCount */]; // (1)
+ zCPar_Symbol symbolTable[/* symbolCount */];
+
+ uint bytecodeSize;
+ byte bytecode[/* bytecodeSize */]; // (2)
+};
+```
+
+1. Symbol IDs sorted lexicographically
+2. Read [bytecode](./bytecode.md) page for more info about this data.
+
+### Symbol
+
+```c title=""
+struct zCPar_Symbol {
+ byte isNamed; // (1)
+ SymbolName name;
+
+ SymbolParameters params;
+ SymbolCodeSpan span;
+ SymbolData data;
+ int parent; // (2)
+};
+```
+
+1. Does this symbol have a name
+2. Parent type, `-1` means `None`
+
+#### Symbol Name
+
+=== "If isNamed == 1"
+ ```c title=""
+ struct SymbolName {
+ string name;
+ };
+ ```
+=== "If isNamed == 0"
+ ```c title=""
+ struct SymbolName {};
+ ```
+
+#### Symbol Parameters
+
+```c title=""
+struct SymbolParameters {
+ int offset; // (1)
+ uint count: 12; // (2)
+ zPAR_TYPE type: 4;
+ zPAR_FLAG flags: 6;
+ uint space: 1;
+ uint reserved: 9;
+};
+
+enum zPAR_TYPE: uint {
+ VOID = 0,
+ FLOAT = 1,
+ INT = 2,
+ STRING = 3,
+ CLASS = 4,
+ FUNC = 5,
+ PROTOTYPE = 6,
+ INSTANCE = 7,
+};
+
+// Parameter bitflags
+enum zPAR_FLAG: uint {
+ CONST = 1,
+ RETURN = 2,
+ CLASSVAR = 4,
+ EXTERNAL = 8,
+ MERGED = 16
+};
+```
+
+1. Depending on `type` either Offset (ClassVar), Size (Class) or ReturnType (Func)
+2. How many sub items does this symbol have
+
+#### Symbol Code Span
+This is span debug information, pointing at the source daedalus script
+
+```c title=""
+struct SymbolCodeSpan {
+ uint fileIndex: 19;
+ uint reserved: 13;
+ uint lineStart: 19;
+ uint reserved: 13;
+ uint lineCount: 19;
+ uint reserved: 13;
+ uint charStart: 24; // (1)
+ uint reserved: 8;
+ uint charCount: 24; // (2)
+ uint reserved: 8;
+};
+```
+
+1. Points to a byte of a source code file at which the span starts
+2. Determines how many bytes does the span starting at `charStart` has
+
+#### Symbol Data
+
+This depends on `params.flags`, if `CLASSVAR` flag is set this data will always be 0 sized.
+=== "If `CLASSVAR` flag is not set"
+ It also depends on `params.type` of the symbol.
+
+ === "FLOAT"
+ ```c title=""
+ struct SymbolData {
+ float value[/* params.count */];
+ };
+ ```
+ === "INT"
+ ```c title=""
+ struct SymbolData {
+ int value[/* params.count */];
+ };
+ ```
+ === "STRING"
+ ```c title=""
+ struct SymbolData {
+ string value[/* params.count */];
+ };
+ ```
+
+ !!! warning
+ Some mods don't terminate those strings correctly, look at this [code](https://github.com/GothicKit/ZenKit/commit/0e7e507de92e8da4ec28513e6be56e4043329990)
+ and the [issue related to it](https://github.com/Try/OpenGothic/issues/483).
+ === "CLASS"
+ ```c title=""
+ struct SymbolData {
+ int classOffset;
+ };
+ ```
+ === "INSTANCE, FUNCTION, PROTOTYPE"
+ ```c title=""
+ struct SymbolData {
+ int address;
+ };
+ ```
+ === "VOID"
+ ```c title=""
+ struct SymbolData {}
+ ```
+
+=== "If `CLASSVAR` flag is set"
+ ```c title=""
+ struct SymbolData {}
+ ```
+