The .dmod format (api 1)
A .dmod is a zip file. The Mod Studio makes it for you; this page is for making or changing mods
outside the game, and for knowing exactly what is allowed. The site checks every upload against
these rules and repacks it (every file stored, uncompressed, manifest.json first) — the game
server reads it without unpacking.
Limits: 25 MB and 2000 files in all, scripts up to 512 KB each, JSON files up to 4 MB, pictures up
to 4096 pixels a side (2048 in sprites/).
The files
| Path | What |
|---|---|
manifest.json |
Required. The mod's card and its settings |
server.lua |
The rules, run by the game server (Scripting) |
client.lua |
The screen, run by each player's game |
lua/<name>.lua |
Modules for require("<name>") (both scripts) |
lobby.json |
The mod's lobby |
sprites.json |
The mod's sprites (new ones, or replacing the game's) |
characters/<name>.json |
Changes to a character |
characters/<name>.lua |
Its own moves, in Lua (api 2) |
objects/<name>.json |
An object: coins, traps, enemies... (api 2) |
objects/<name>.lua |
Its events in Lua (api 2) |
maps/<name>.json |
A map |
maps/<name>.png |
Map pictures: tilesets, backgrounds, art, previews |
sprites/<name>.png |
Sprite strips |
sounds/<name>.ogg |
Sounds and music (Ogg Vorbis). sounds/snd_jump.ogg replaces the game's snd_jump |
preview.png |
The picture on the site (else the first map's preview) |
readme.txt |
Anything you want to say |
File names inside the folders: lower case, digits, _ . -. Nothing else is allowed in the package.
manifest.json
{
"id": "hot_potato",
"name": "Hot Potato",
"version": "1.0.0",
"api": 1,
"author": "you",
"description": "Pass the potato before it blows up.",
"maps": "add",
"bots": false,
"settings": [
{"key": "fuse", "name": "Fuse (seconds)", "type": "int", "default": 20, "min": 5, "max": 120}
]
}
| Field | |
|---|---|
id |
3-32 characters, a-z 0-9 _ -, starting with a letter or digit. Unique on the site |
name |
1-40 characters |
version |
major.minor.patch; every upload needs a higher one |
api |
1, or 2 when the mod has objects (the Mod Studio sets it) |
author, description |
Up to 40 and 1000 characters |
maps |
"add" (the mod's maps join the game's in the vote; the default) or "only" |
bots |
false: the server's bots don't play (default true) |
settings |
Up to 32 options the server host changes. The scripts read them as mod.config.<key> |
A setting: key (lower case, unique), name (what the host sees), type and default:
| type | default | also |
|---|---|---|
int |
a whole number | min, max |
number |
a number | min, max |
bool |
true / false |
|
text |
up to 200 characters | |
choice |
one of choices |
choices: a list of texts |
Maps: maps/<name>.json
Coordinates are pixels, y going down. The map editor writes all of this; an editor object it
adds is ignored by the game.
{
"name": "Test Hill",
"description": "Slopes, platforms and springs.",
"width": 3200, "height": 1024,
"time": 150,
"music": "mus_hill", "chase_music": "mus_hill_chase",
"background": {"image": "maps/sky.png", "color": "#203050", "parallax": 0.3},
"art": [{"image": "maps/castle.png", "x": 900, "y": 300}],
"tileset": "maps/tiles.png",
"tiles": {"data": "2:5,196:0,4:5,196:0"},
"solids": [[0, 800, 3200, 224]],
"platforms": [[300, 680, 160]],
"slopes": [[1072, 672, 128, 128, 1]],
"objects": [
{"type": "spawn", "x": 100, "y": 799},
{"type": "exe_spawn", "x": 3000, "y": 799},
{"type": "ring", "x": 600, "y": 760},
{"type": "exit", "x": 1600, "y": 800},
{"type": "spring_up", "x": 2000, "y": 800}
],
"preview": "maps/preview.png"
}
| Field | |
|---|---|
width, height |
480-32768 by 270-8192 |
name |
1-40 characters; description up to 300 |
time |
The round's length in seconds, 30-900 (default 180) |
music, chase_music |
A game music (mus_hill, mus_...) or a sound of the mod (sounds/x.ogg) |
background |
image (a picture of the mod or a sprite name), color (#rrggbb), parallax 0-1 (0 stays still, 1 moves with the map) |
art |
Pictures drawn over the background and under the players |
tileset, tiles.data |
16x16 tiles: the tileset is a picture of tiles, numbered left to right, top to bottom from 0. data covers the map row by row in runs count:value, where value is the tile's number + 1 (0: empty) |
solids |
[x, y, w, h] solid blocks |
platforms |
[x, y, w] one-way platforms |
slopes |
[x, y, w, h, dir]: dir 1 rises to the right, -1 to the left |
objects |
spawn (survivors), exe_spawn, ring, exit (where the big ring can appear), spring_up, spring_left, spring_right; also solid and platform with w / h; and the mod's objects: {"type": "object", "object": "coin", "x": 300, "y": 760} (at most 256) |
preview |
The map's card in the vote |
A map needs a spawn, an exe_spawn and an exit; at most 255 rings. Tiles are only pictures:
what players stand on is solids, platforms and slopes (the editor makes them from the tile
flags when it saves).
An exit's y is where the big ring stands (its bottom): on the ground, players run into it. The
map's left and right edges are walls; falling off the bottom brings a player back to the nearest
spawn, hurt.
sprites.json
{"sprites": {
"spr_ring": {"image": "sprites/blue_ring.png", "frames": 4, "origin": [8, 8]},
"potato": {"image": "sprites/potato.png", "frames": 1, "origin": [16, 16], "speed": 0.2}
}}
A sprite named like one of the game's (spr_ring, spr_tails_idle...) is drawn instead of it and
keeps the game's hit box. Other names are new sprites for client.lua (hud.sprite), for map
backgrounds, or for characters. frames: a strip left to right (1-256). origin: the point placed
on the position. speed: frames per game frame (default: the game sprite's, or 0.25).
characters/<name>.json
{
"replaces": "tails",
"name": "Speedy Tails",
"stats": {"speed": 1.25, "acceleration": 1.2, "jump": 1, "gravity": 1, "damage_taken": 1, "hp": 120},
"sprites": {"spr_tails_idle": "speedy_idle"}
}
replaces: tails, knuckles, eggman, amy, cream, sally, exe, chaos, exetior,
exeller. The stats multiply the character's own (1 = unchanged): speed, acceleration, jump and
gravity 0.3-3, damage taken 0-5; hp 10-127 is its starting HP. sprites swaps the character's
game sprites for sprites of sprites.json.
objects/<name>.json (api 2)
{
"sprite": "coin",
"box": [-8, -8, 16, 16],
"front": false,
"vars": {"value": 5}
}
An object the mod's maps place and its scripts make (game.spawn). sprite: a sprite of the
mod (sprites.json) or of the game (spr_ring); none: it is not drawn. box: where players touch
it, [left, top, width, height] from its x, y. front: drawn in front of the players. solid:
"solid" (players stand on it and bump into it) or "platform" (they stand on its top, and jump
through it from below); a moving one carries who stands on it. vars: the
fields each one starts with (numbers, texts, true / false), as self.<name>.
Its events are in objects/<name>.lua, each a function: create(self), step(self) (60 times a
second), touch(self, player), leave(self, player) and destroy(self). They run on the server
with the game rules' functions.
lobby.json
{
"title": "`HOT POTATO",
"text": "Touch another survivor to pass the potato.",
"background": "maps/preview.png",
"music": "mus_waiting"
}
Shown while players wait. title and text up to 300 characters; background a picture of the
mod or a sprite; music a game music or a sound of the mod.
Colour codes
Texts (lobby, map names, game.say, hud.text...) take the game's colour codes: ` yellow,
@ green, & purple, / blue, | grey, \ red, ~ back to the normal colour.
Checking a package
The Mod Studio's Check runs the same checks as the upload page: open your .dmod with Open a .dmod file and check it there.