A .tauric file is a protobuf message. These are the schema files it is written against — the same ones the editor compiles, read straight from the repository rather than copied, so this page cannot drift from what the code does.
Protobuf was chosen to keep files compact. A map is mostly repetition — thousands of tile references, thousands of points — and protobuf writes those as packed numbers against integer tags instead of spelling out a key for every one of them. Measured on the map this editor opens with, the protobuf file is about a quarter the size of the same map as Tiled JSON with its tileset beside it.
Being straight about the limit of that: over a connection that compresses, the gap all but disappears — JSON's repetition is exactly what a compressor eats, and the same two files gzip to within a few percent of each other. The saving is real on disk, in memory, and in not parsing text; it is not a bandwidth argument.
What it costs is readability — this is the one format here you cannot open in a text editor, which is a large part of why this page exists.
Two pages of the specification cover most of what a reader needs: the proto3 language guide for what the schema below means, and the encoding reference for the bytes themselves — the second is the one to read if you are writing a parser rather than generating one.
The schema is MIT licensed. Compile it, vendor it, ship a reader or a writer — no permission needed, and the licence travels inside the file you download. That covers the schema text, not the editor.
What we can't promise is that a fork of it still interoperates. Add a field, renumber one, widen a type, and you have a dialect that shares a package name — and because protobuf skips tags it doesn't recognise instead of complaining, the divergence shows up as quietly missing data rather than an error. Unmodified, this schema round- trips. If you need something it doesn't carry, ask and it gets a field number everyone agrees on.
Field numbers are append-only. A number that has been used is never reused or renumbered: readers skip tags they don't know, which is what lets an old file open in a new build. Each message below lists the next free number.
package tauric.map.v1
common.proto2 messages
Copyright (c) 2026 Gnarled Helix LLC. All rights reserved.
Shared primitives for the Tauric native format.
Vec2next free number 3
1
double
x
2
double
y
Propertynext free number 6
Strongly-typed simple property metadata (map-, layer-, and tile-level). Richer foreign values (Tiled class/list properties) are not representable and are dropped at save time with a warning.
1
string
name
2
PropertyType
type
3
bool
boolean_value
4
double
number_value
5
string
string_value
oneof value: boolean_value, number_value, string_value — at most one is set.
Copyright (c) 2026 Gnarled Helix LLC. All rights reserved.
The Tauric native map format: the lossless serialization of a map
document. A .tauric file is one MapFile message, encoded binary.
Tileset definitions and packed tile placements live in tiles.proto;
shared primitives in common.proto. Tiled's own file formats are never
embedded — the feature set this editor uses is replicated as typed
messages.
Field numbers are append-only. The schema still gains fields between
releases, so a reader should skip tags it does not recognize rather than
treat them as an error.
EdgePayloadnext free number 4
A line between two points, optionally bent. LEGACY: nothing writes this any more — a two-point polyline with an arc segment says the same thing — but it stays in the schema permanently and a reader must still handle it, because files written before the change keep opening.
1
Vec2
start
2
Vec2
end
3
optional double
curvature
StraightSegmentnext free number 1
A straight span. Present as an explicit case so one span can be straight in an array whose others bend; an ABSENT segment means the same thing.
ArcSegmentnext free number 2
A true circular arc: the subtended angle in degrees, positive bulging left of start→end in y-down pixel space. The same quantity DXF encodes as a per-vertex bulge, tan(θ/4).
1
double
curvature
BezierSegmentnext free number 3
A cubic Bézier. Handles are stored RELATIVE to their own span's endpoints — control1 from the span's start point, control2 from its end.
1
Vec2
control1
2
Vec2
control2
ShapeSegmentnext free number 4
How one span between consecutive shape points is drawn.
1
StraightSegment
straight
2
ArcSegment
arc
3
BezierSegment
bezier
oneof kind: straight, arc, bezier — at most one is set.
CommentPayloadnext free number 2
1
string
text
TextPayloadnext free number 7
A text label placed as map content. Distinct from a comment: comments are editor annotation and are stripped from every export, whereas a label is part of the map and travels with it.
1
string
text
2
optional double
font_size — Per-label overrides of the type's text graphic. Unset means the type decides.
3
optional string
font_family
4
optional string
color
5
optional string
outline_color
6
optional double
outline_width
PointListnext free number 2
1
repeated Vec2
points
EntityPlacementnext free number 20
1
string
id
2
string
type_id
3
double
tile_x — Tile coords, Y-down; fractional after fine drags
4
double
tile_y
5
optional double
width — Pixel overrides; absent = type defaultSize
6
optional double
height
7
optional double
angle — Degrees, clockwise
8
optional google.protobuf.Struct
properties
9
EdgePayload
edge
10
CommentPayload
comment
18
TextPayload
text
11
PointList
polyline
12
PointList
polygon
19
repeated ShapeSegment
segments — One per span between consecutive shape points, parallel to whichever shape case is set (a polygon's last span wraps back to its first point). Empty, short, or all-straight all mean the same thing: straight spans.
oneof payload: edge, comment, text — at most one is set.
oneof shape: polyline, polygon — at most one is set.
TileLayernext free number 14
1
string
id
2
string
name
3
bool
visible
4
double
opacity
5
optional double
parallax_x
6
optional double
parallax_y
7
optional string
tint_color
8
optional double
offset_x
9
optional double
offset_y
10
repeated Property
properties
11
TileLayerTiles
tiles
12
optional string
parent_id
13
optional bool
locked — Drawn, but not touchable in the viewport. Absent means unlocked.
EntityLayernext free number 9
1
string
id
2
string
name
3
bool
visible
4
optional double
opacity
5
repeated Property
properties
6
repeated EntityPlacement
entities
7
optional string
parent_id
8
optional bool
locked
ImageLayernext free number 17
1
string
id
2
string
name
3
bool
visible
4
string
image_path
5
string
image_name
6
optional string
image_url
7
double
offset_x
8
double
offset_y
9
double
opacity
10
optional double
parallax_x
11
optional double
parallax_y
12
optional bool
repeat_x
13
optional bool
repeat_y
14
repeated Property
properties
15
optional string
parent_id
16
optional bool
locked
GroupLayernext free number 11
A folder of other layers. Holds no content; its visibility, opacity and offset apply to everything inside it. Membership is by the CHILD's parent_id rather than a list of children here.
1
string
id
2
string
name
3
bool
visible
4
optional double
opacity
5
optional double
offset_x
6
optional double
offset_y
7
optional bool
collapsed
8
repeated Property
properties
9
optional string
parent_id
10
optional bool
locked
Layernext free number 6
1
TileLayer
tile
2
EntityLayer
entity
3
ImageLayer
image
5
GroupLayer
group
oneof kind: tile, entity, image, group — at most one is set.
TilesetEntrynext free number 3
One entry per tileset the map references. Order matters: packed tile cells index into this list. `definition` is absent for tilesets the session had no definition for (their source paths ride in unknown_tileset_sources).
1
string
name
2
optional TilesetDefinition
definition
EmbeddedAssetnext free number 4
One image asset the map's entity types draw from, as stored (a PNG, or a .prs sheet with its sprite layout inside it).
1
string
id
2
string
name
3
bytes
data
EmbeddedProjectnext free number 3
A copy of the project state this map needs, so the file can be opened somewhere that has never seen the project it came from. Without it a .tauric is only meaningful next to its project: placements carry a type_id, and the definition behind that id — its graphic, its category kind, the image it draws — lives in the project.
1
google.protobuf.Struct
config — ProjectConfig verbatim: categories, entity types, tile size, real-world scale. A Struct rather than a typed mirror, so a reader does not drop whatever the writing version knew and it did not.
2
repeated EmbeddedAsset
assets — Only the assets the map's types actually reference, not the whole project's art library.
MapFilenext free number 13
1
uint32
format_version — 1
2
string
map_name
3
string
background_color
4
optional string
map_uuid
5
repeated Layer
layers
6
repeated TilesetEntry
tilesets
7
repeated Property
map_properties
11
optional EmbeddedProject
project — Absent in files written before self-contained saves, and in exports that deliberately omit it.
12
optional bool
tiled_infinite — False for a fixed-size (finite) Tiled map. Absent means infinite.
tiles.proto7 messages
Copyright (c) 2026 Gnarled Helix LLC. All rights reserved.
Tile-related messages for the Tauric native format: typed tileset
definitions replicating the subset of Tiled's .tsj feature set Tauric
uses (no raw Tiled JSON embeds), and a compact chunked encoding for tile
placements (no per-cell tileset names).
ImageRefnext free number 7
1
string
source — Original image filename/path, kept so exports reference the same file.
format — Encoding of image_bytes; always set (PNG) when bytes are embedded. UNSPECIFIED for references, whose format is the referenced resource's.
oneof data: image_bytes, image_ref — at most one is set.
AnimationFramenext free number 3
1
uint32
tile_id — Local tile id within the same tileset
2
uint32
duration_ms
CollisionShapenext free number 8
One collision shape from a tile's Tiled objectgroup: a rect unless `polygon` is set (polygon points are relative to x/y, in pixels).
1
double
x
2
double
y
3
double
width
4
double
height
5
repeated Vec2
polygon
6
optional double
rotation
7
optional string
shape_class — Tiled object `class`/`type`
TileDefinitionnext free number 8
Per-tile data. Entries are sparse — only tiles that carry any of this are stored, keyed by their sheet position (never a dense array with empty items). The linear tile id is derived: row * columns + column.
2
optional string
tile_class — Tiled `class`/`type` (e.g. "ground")
3
repeated AnimationFrame
animation
4
repeated CollisionShape
collision
5
repeated Property
properties
6
uint32
row
7
uint32
column
TilesetDefinitionnext free number 10
1
string
name
2
uint32
tile_width
3
uint32
tile_height
4
uint32
columns
5
uint32
tile_count
6
uint32
margin
7
uint32
spacing
8
ImageRef
image
9
repeated TileDefinition
tiles
TileChunknext free number 4
1
sint32
x — Chunk origin in tile coords (multiple of chunk_size)
2
sint32
y
3
repeated uint32
cells — Row-major, chunk_size² entries
TileLayerTilesnext free number 3
1
uint32
chunk_size — 16
2
repeated TileChunk
chunks
The collaboration protocol — how peers and the relay talk to each other — is a separate schema and is not published here.