Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/BunnyNabbit/celaria-formats/llms.txt

Use this file to discover all available pages before exploring further.

Serialization converts an in-memory map object back into a binary buffer that can be saved to disk or sent over a network. Both CelariaMap and EditableCelariaMap expose a serialize method that accepts a version number controlling the binary format used.

Serializing .cmap files

Call map.serialize() on a CelariaMap instance. The version defaults to 2 if omitted.
import fs from "node:fs"
import { CelariaMap, Block, PlayerSpawnPoint } from "celaria-formats"

const map = new CelariaMap()
map.name = "My Map"
map.mode = CelariaMap.gameModes.timeTrial

// Add a player spawn
const spawn = new PlayerSpawnPoint()
spawn.position = [0, 0, 0]
map.instances.push(spawn)

// Add a plain block
const floor = new Block(Block.types.plain)
floor.position = [0, -2, 0]
floor.scale = [10, 2, 10]
map.instances.push(floor)

// Add a checkpoint
const checkpoint = new Block(Block.types.checkpoint)
checkpoint.position = [5, 0, 0]
checkpoint.medalTimes = { platinum: 300, gold: 500, silver: 800, bronze: 1200 }
map.instances.push(checkpoint)
map.checkpointOrder.add(checkpoint)

// Add the goal (last in checkpoint order)
const goal = new Block(Block.types.goal)
goal.position = [10, 0, 0]
goal.medalTimes = { platinum: 300, gold: 500, silver: 800, bronze: 1200 }
map.instances.push(goal)
map.checkpointOrder.add(goal)

const buffer = map.serialize(2) // or just map.serialize()
fs.writeFileSync("./output.cmap", buffer)

Version compatibility

VersionStatusPosition encodingBarriers supported
0LegacyScaled integersNo
1LegacyScaled integersNo
2Current64-bit doublesYes
Barriers (wall and floor) require version 2 or later. Attempting to serialize a map that contains a Barrier with version 0 or 1 throws an error.

Checkpoint ordering

The checkpointOrder property is an OrderedSet<Block> that determines the sequence in which checkpoints appear in the binary output. The last block added to checkpointOrder is written as the goal block. All other blocks in checkpointOrder are written as checkpoints, in insertion order. Blocks in map.instances that are not in checkpointOrder but have type checkpoint or goal are reset to plain during serialization.
// Add checkpoints in the order the player should reach them
map.checkpointOrder.add(checkpoint1)
map.checkpointOrder.add(checkpoint2)
map.checkpointOrder.add(goal) // goal is always last
Every block in checkpointOrder must have medalTimes set before calling serialize. Missing medal times throws an error. This applies to both checkpoint and goal blocks in CelariaMap.
Set all four medal time values even if your map only uses some of them. The binary format always writes all four fields.

Serializing .ecmap files

Call map.serialize(version) on an EditableCelariaMap instance. Unlike CelariaMap, the version argument is required — omitting it throws an error.
EditableCelariaMap.serialize(version) has no default version. Calling it without an argument throws Error("No version defined.").
import fs from "node:fs"
import { Block } from "celaria-formats/class/maps/objects/Block.mjs"
import { EditableCelariaMap } from "celaria-formats/class/maps/EditableCelariaMap.mjs"

// Parse an existing map, modify it, and save
const map = EditableCelariaMap.parse(fs.readFileSync("./myMap.ecmap"))

// Turn all plain blocks into speed blocks
map.instances
  .filter(instance => instance.instanceId === 0)
  .forEach(block => block.type = Block.types.speed)

const buffer = map.serialize(4)
fs.writeFileSync("./modified.ecmap", buffer)
Use EditableCelariaMap when working with maps that will be opened in the Celaria map editor. Use CelariaMap for maps that will be served or played directly.

Writing to disk

Both serialize methods return a Node.js Buffer. Write it to disk with fs.writeFileSync:
import fs from "node:fs"

// CelariaMap
const cmapBuffer = map.serialize(2)
fs.writeFileSync("./output.cmap", cmapBuffer)

// EditableCelariaMap
const ecmapBuffer = editableMap.serialize(4)
fs.writeFileSync("./output.ecmap", ecmapBuffer)

Build docs developers (and LLMs) love