Veduta

Compiled container — .vda

veduta cook compiles each asset source (model, texture, material, scene) into one .vda file under the project's cooked directory (default assets/.cooked). A .vda file is a small chunked binary container inspired by PNG. Never edit cooked files: change the source and cook again. Cooking is incremental: a source is recompiled only when the hash stored in its META chunk no longer matches, or the compiler version changed.

Everything is little-endian.

Container

file  = magic chunk*
magic = "VDA1"                       4 bytes, ASCII
chunk = type length payload crc
  type    4 bytes   ASCII letters and digits, case-sensitive (e.g. "MESH")
  length  u32       payload size in bytes (0 to 4294967295)
  payload length bytes
  crc     u32       CRC-32 (IEEE 802.3 polynomial, as in PNG and zip) of type + payload
ChunkKindPayload
METAallasset metadata, canonical JSON (below)
MESHmodelcompiled model
TEXRtexturecompiled texture with its mip chain
MATLmaterialcompiled material
SCENscenecompiled scene
PRFBprefabcompiled prefab (since v1.2.0)
WRLDworldcompiled world (since v1.2.0)
TMAPmapcompiled tile map (since v2.0.0-rc.11)

META

UTF-8 JSON object, canonical: keys in this (sorted) order, no whitespace, no HTML escaping, deps sorted without duplicates and [] when empty. Readers reject META that is not byte-for-byte canonical, so equal metadata always has equal bytes.

{"compiler":"veduta-asset/0.8.0","deps":[],"kind":"model","name":"crate","source":"models/crate.vmodel","source_hash":"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}
KeyMeaning
compilerCompiler version (asset.CompilerVersion: veduta-asset/0.8.0 since map tilesets, veduta-asset/0.7.0 since texture autotiles, veduta-asset/0.6.0 since texture frames, clips and edges, maps and entity clips, veduta-asset/0.5.0 since material grids and entity frames, veduta-asset/0.4.0 since model levels of detail and world terrain and vegetation, veduta-asset/0.3.0 since prefabs and worlds, veduta-asset/0.2.0 since scene entities carry a hitbox and a layer, veduta-asset/0.1.0 before). A different version forces a recompile.
depsOther input files the compiled output depends on besides the source (for example the PNG of a texture image layer), as paths relative to the assets directory.
kindmodel, texture, material, scene, prefab, world or map.
nameAsset name (the source file name without its suffix).
sourceSource path relative to the assets directory, forward slashes (models/crate.vmodel).
source_hashLowercase hex SHA-256 (64 characters) of the compiler inputs, computed by cook: SHA-256 over veduta-cook/1\n, the compiler version and \n, then source <path> <length>\n followed by the source bytes, then for each dependency in deps order dep <path> <length>\n followed by its bytes (missing <path>\n when it cannot be read). It changes whenever the source or any dependency changes.

Primitive encodings

NameSizeEncoding
u81unsigned byte
bool10 = false, 1 = true; any other value is an error
u324unsigned 32-bit
i648signed 64-bit, two's complement (every Go int field)
f324IEEE-754 binary32 bit pattern, stored as a u32 (exact, including −0 and NaN payloads)
str4 + nu32 byte length n, then n bytes of UTF-8, no terminator
vec28f32 x, f32 y
vec312f32 x, f32 y, f32 z
aabb24vec3 min, vec3 max
color4u32 0xAARRGGBB, i.e. bytes B, G, R, A in the file
list<T>4 + …u32 count, then count elements of T

Empty lists are written with count 0 and read back as absent (nil) lists. A payload must be consumed exactly: missing bytes and trailing bytes are errors.

MESH — compiled model

#FieldTypeMeaning
1namestrmodel name
2pivotstrorigin, center or bottom-center
3symmetrystr"", x, y or z (symmetry check requested)
4smooth_angle_degf32normal smoothing angle in degrees
5triangle_budgeti64triangle budget for inspection
6pivot_offsetvec3translation applied to every vertex to honour the pivot
7boundsaabbmesh bounding box (after the pivot offset)
8verticeslist<vertex>vertex = vec3 position, vec3 normal, vec2 uv (32 bytes)
9indiceslist<u32>triangle vertex indices, 3 per triangle, counter-clockwise front faces
10mesh_partslist<mesh_part>mesh_part = i64 first index, i64 index count, i64 material (index into materials)
11materialslist<str>material names in first-use order; "" = the entity's material or the default
12partslist<part>one per source part, see below
13draw_distancef32meters beyond which the model is not drawn; 0 for no limit (since v1.3.0)
14lodslist<lod>levels of detail, nearest first (since v1.3.0)

part = i64 index (source part index), str shape, i64 first index, i64 index count, str material ("" for none), str uv mapping, bool flip_normals, i64 of (mirror: mirrored source part index; −1 otherwise).

lod = f32 distance, str model ("" when the level has its own geometry), aabb bounds, list<vertex> vertices, list<u32> indices, list<mesh_part> mesh parts (both empty when model is set; otherwise one mesh part per base mesh part, materials indexing the base's materials).

Readers check: the index count is a multiple of 3; every index is below the vertex count; every mesh part and part range lies within the indices and its count is a multiple of 3; every mesh part's material is a valid index into materials (or 0 when materials is empty); every of is ≥ −1; draw_distance is ≥ 0; lod distances increase; a level has as many mesh parts as the base mesh, or none and a model.

TEXR — compiled texture

#FieldTypeMeaning
1namestrtexture name
2tilingboolthe source asked for a tileable texture
3layersi64number of source layers
4widthu32width of level 0 in pixels
5heightu32height of level 0 in pixels
6levelsu32number of mip levels (1 without mipmaps)
7wrapu80 = repeat (tiling), 1 = clamp
8level × levelsfor level i = 0 … levels−1: u32 w, u32 h, then w × h color pixels, row-major, top row first
9gridu32 × 2columns and rows of frames, 0 0 for a single image
10clipsu32 count, then per clipstr name, u32 count and that many u32 frames, f32 fps, bool loop, str next ("" for none)
11playstrthe clip shown when nothing picks a frame, "" for none
12edgebool, then when truei64 priority, f32 width, f32 roughness, i64 seed
13autotileboolevery frame is 6 × 3 tiles, an island and a lake

Readers check: level i measures exactly max(1, width >> i) × max(1, height >> i); levels is at most 1 + ⌊log₂ max(width, height)⌋ (the chain stops at 1 × 1); width and height are 1 to 16777216 when levels > 0 and both 0 when levels = 0; wrap is 0 or 1; grid is both 0 or both 1 to 256; clips are in name order, each with at least one frame of the grid and fps above 0; an edge has priority at least 1, width above 0 and roughness 0 to 1.

MATL — compiled material

#FieldTypeMeaning
1namestrmaterial name
2albedocolorbase color
3texturestrtexture name, "" for none
4unlitboolignore the light
5alphastropaque, blend or cutout (anything else is an error)
6cutofff32alpha threshold used by cutout
7cullu80 = back, 1 = none
8filteru80 = bilinear, 1 = nearest
9gridu32 × 2columns and rows of frames in the texture, each 1 to 256, or both 0 for none

SCEN — compiled scene

#FieldTypeMeaning
1namestrscene name
2camera.orthoboolorthographic camera
3camera.fov_degf32vertical field of view in degrees (0 for orthographic)
4camera.sizef32orthographic visible height in meters (0 for perspective)
5camera.nearf32near plane distance
6camera.farf32far plane distance
7camera.positionvec3eye position
8camera.look_atvec3target point
9light.directionvec3direction the light travels, as written in the source
10light.colorvec3linear RGB in [0, 1]
11light.ambientvec3linear RGB in [0, 1]
12backgroundcolorclear color
13entitieslist<entity>in scene-file order
14mapstrthe scene's tile map, "" for none

entity = str name, str kind, str model ("" for none), str material ("" for none), vec3 position, vec3 rotation_deg, vec3 scale, list<str> tags, str parent ("" for none), bool visible, bool has_hitbox, then only when has_hitbox is true aabb hitbox (local space, min <= max on every axis; readers reject any other box), then i64 layer (in [-1000, 1000]), u32 frame (in [0, 65535]), str anim ("" for none).

PRFB — compiled prefab

#FieldTypeMeaning
1namestrprefab name
2footprintvec2width (x) and depth (z) in meters, each in (0, 1024]
3tagslist<str>structure tags
4biomeslist<str>allowed biomes (empty: any)
5distanceslist<distance>str tag, f32 meters in [0, 4096]; sorted by tag
6entitieslist<entity>as in SCEN

WRLD — compiled world

#FieldTypeMeaning
1namestrworld name
2seedu64generator seed
3cellf32meters per cell, in (0, 64]
4chunki64cells per chunk side, 4 to 64
5extenti64chunks from the origin, 1 to 4096; extent × chunk × cell ≤ 8192
6viewi64chunks loaded around the focus, 1 to 4
7biome_scalei64cells per noise period, 4 to 4096
8–14cameraas SCEN fields 2–8relative to the start cell
15–17lightas SCEN fields 9–11
18backgroundcolor
19biomeslist<biome>str name, str ground material, i64 weight in [1, 1000]; at least one
20scatterlist<scatter>str prefab, list<str> biomes, f32 density in (0, 1]
21siteslist<site>str tag, list<str> prefabs, list<str> biomes, i64 spacing in [2, 4096], f32 chance in (0, 1]
22placeslist<place>str name, str prefab, i64 x, i64 z (cells inside the world), i64 rotation (0, 90, 180 or 270)
23entitieslist<entity>persistent entities, as in SCEN
24–29terrainf32 relief in [0, 256], i64 relief_scale in [4, 4096], bool sea, f32 sea_level in [−1024, 1024], str water material ("" built-in), f32 lod_distance > 0since v1.3.0
30featureslist<feature>str name, str kind (hill, plain, lake, sea), i64 x, i64 z (inside the world's vertices), i64 radius in [1, 16384], bool has_height, f32 height in [−1024, 1024], f32 depth in (0, 256], i64 falloff in [0, 16384], f32 roughness in [0, 1]; since v1.3.0
31vegetationlist<vegetation>str name, str prefab, str model (exactly one non-empty), f32 density in (0, 1], list<str> biomes, bool area, i64 x, i64 z, i64 radius (checked with area), f32 scale min, f32 scale max (0 < min ≤ max ≤ 16); since v1.3.0

u64 is an unsigned 64-bit little-endian integer.

Determinism

Encoding the same compiled asset twice yields identical bytes, and decoding then re-encoding a file reproduces it byte for byte: every field has one encoding, floats are stored as raw bits and META is canonical.

TMAP — compiled tile map

#FieldTypeMeaning
1namestrmap name
2columns, rowsu32 × 21 to 1024 each
3tilef32meters per cell, above 0
4originvec3the top-left corner
5terrainsu32 count, then per terrainu32 key (a code point), str name, str texture, str material (exactly one of the two not ""), bool tileset, u8 tile column, u8 tile row, u8 variants (1 to 64), u8 flip (bit 0 left to right, bit 1 top to bottom), list<str> tags
6layersu32 count, then per layerstr name, f32 z, i64 layer, bool ysort, then columns × rows u16 cells, row by row from the top: 0 empty, else a terrain's index + 1
7objectsu32 count, then per objectstr name, u32 x, y, columns, rows (on the map), str prefab ("" for none), list<str> tags, u32 count of props, each str name, u8 type and its value: 0 str, 1 f64 (8 bytes little-endian), 2 bool