Import maps into Unity, Godot, or Phaser
Prefer Tiled .tmx plus a tileset PNG for SuperTiled2Unity (Unity) or Godot’s Tiled importer. Use a Godot .tscn for a native scene, or JSON plus the C# / GDScript scripts below.
01The 3-step workflow
Design
Pick dungeon or platformer, a theme, and size. Share the URL — it includes the seed.
Export
Download Tiled .tmx + PNG (best for Unity/Godot/Phaser), a Godot .tscn, or JSON.
Import
Unity: SuperTiled2Unity on the .tmx. Godot: Tiled plugin or drop in the .tscn. Or run the importer scripts on JSON.
02Manifest Anatomy
{
"name": "Ancient Nexus",
"id": "biome_x1y2z3",
"index": 0,
"metadata": {
"name": "Ancient Nexus",
"id": "biome_x1y2z3",
"index": 0,
"seed": "alpha74x",
"mode": "dungeon",
"tileRegistry": [
{ "id": 1, "name": "WALL", "color": "#5d4057" },
{ "id": 3, "name": "ITEM", "color": "#f39c12" }
]
},
"layers": [
{ "name": "geometry", "tiles": [...] }
],
"entities": [...]
}High-Fidelity Mapping
- Sequential IndexNumerical ID (0, 1, 2...) for easy array-based level indexing in engines.
- Deterministic IDSeed-based unique string for reliable cross-session level referencing.
- Embedded RegistryTile IDs and color mappings are baked into the JSON for automatic engine styling.
Architect Tip
"Leverage the Tile Registry to map specific Biome IDs to your engine's Prefabs or TileSets. No more hardcoding offsets!"
03World Connectivity & Progression
Jaconir Architect utilizing Seed-Only Persistence. This ensures infinitely scalable production manifests while maintaining a footprint under 100KB.
Synthetic Worlds
Use the Sequential Auto-Batch to generate 50 randomized biomes in seconds. Ideal for rogue-likes or testing large-scale engine performance.
Curated Worlds
Hand-pick specific biomes from your history and add them to the Export Suite. This allows you to design a meticulously balanced level curve for your campaign.
Engine Boilerplates
Use these scripts as a starting point. They handle the heavy lifting of JSON parsing and coordinate mapping.
Unity (C#)
Tilemap & Prefab Based
using UnityEngine;
using UnityEngine.Tilemaps;
using System.Collections.Generic;
using System;
[Serializable]
public class LevelMetadata {
public string name;
public string seed;
public int width;
public int height;
public string theme;
public string mode;
}
[Serializable]
public class TileData {
public int x;
public int y;
public string type;
public int id;
}
[Serializable]
public class LayerData {
public string name;
public List<TileData> tiles;
}
[Serializable]
public class EntityData {
public string id;
public string type;
public float x;
public float y;
}
[Serializable]
public class LevelManifest {
public LevelMetadata metadata;
public List<LayerData> layers;
public List<EntityData> entities;
}
[Serializable]
public class WorldManifest {
public List<LevelManifest> worldManifest;
public int count;
}
public class JaconirLevelImporter : MonoBehaviour {
[Header("Tile Settings")]
public Tilemap targetTilemap;
public Tile wallTile;
[Header("Entity Prefabs")]
public GameObject playerPrefab;
public GameObject exitPrefab;
public GameObject itemPrefab;
public void Import(string jsonContent) {
LevelManifest manifest = JsonUtility.FromJson<LevelManifest>(jsonContent);
ImportFromManifest(manifest);
}
public void ImportFromManifest(LevelManifest manifest) {
Debug.Log($"Importing: {manifest.metadata.name} (Seed: {manifest.metadata.seed})");
// 1. Clear current level and previous entities
targetTilemap.ClearAllTiles();
foreach (Transform child in transform) {
Destroy(child.gameObject);
}
// 2. Build Geometry
foreach (var layer in manifest.layers) {
if (layer.name == "geometry") {
foreach (var tile in layer.tiles) {
if (tile.type == "wall") {
targetTilemap.SetTile(new Vector3Int(tile.x, -tile.y, 0), wallTile);
}
}
}
}
// 3. Spawn Entities (Mapping generator types 'spawn_gate' and 'transition_gate')
foreach (var entity in manifest.entities) {
Vector3 pos = new Vector3(entity.x, -entity.y, 0);
if (entity.type == "spawn_gate" && playerPrefab) Instantiate(playerPrefab, pos, Quaternion.identity, transform);
else if (entity.type == "transition_gate" && exitPrefab) Instantiate(exitPrefab, pos, Quaternion.identity, transform);
else if (entity.type == "item" && itemPrefab) Instantiate(itemPrefab, pos, Quaternion.identity, transform);
}
}
}
public class JaconirWorldManager : MonoBehaviour {
public JaconirLevelImporter importer;
private WorldManifest currentWorld;
private int currentLevelIndex = 0;
public void LoadWorld(string json) {
currentWorld = JsonUtility.FromJson<WorldManifest>(json);
currentLevelIndex = 0;
LoadCurrentLevel();
}
public void LoadNextLevel() {
if (currentLevelIndex + 1 < currentWorld.worldManifest.Count) {
currentLevelIndex++;
LoadCurrentLevel();
} else {
Debug.Log("World Complete!");
}
}
private void LoadCurrentLevel() {
importer.ImportFromManifest(currentWorld.worldManifest[currentLevelIndex]);
}
}Godot (GDScript)
TileMap & PackedScene
extends Node2D
@export var tilemap: TileMap
@export var tile_size: int = 32
@export var player_scene: PackedScene
@export var exit_scene: PackedScene
@export var item_scene: PackedScene
var world_data = null
var current_index = 0
func import_single_level(json_path: String):
var file = FileAccess.open(json_path, FileAccess.READ)
var data = JSON.parse_string(file.get_as_text())
_build_level(data)
func import_world_manifest(json_path: String):
var file = FileAccess.open(json_path, FileAccess.READ)
world_data = JSON.parse_string(file.get_as_text())
current_index = 0
_build_level(world_data["worldManifest"][0])
func load_next_biome():
if world_data and current_index + 1 < world_data["worldManifest"].size():
current_index += 1
_build_level(world_data["worldManifest"][current_index])
else:
print("All Biomes Completed!")
func _build_level(data):
tilemap.clear()
# Clean up entities
for child in get_children():
if child != tilemap:
child.queue_free()
# 1. Build Geometry
for layer in data["layers"]:
if layer["name"] == "geometry":
for tile in layer["tiles"]:
if tile["type"] == "wall":
tilemap.set_cell(0, Vector2i(tile["x"], tile["y"]), 0, Vector2i(0, 0))
# 2. Spawn Entities (Mapping generator types 'spawn_gate' and 'transition_gate')
for entity in data["entities"]:
var spawn_pos = Vector2(entity["x"] * tile_size, entity["y"] * tile_size)
var instance = null
match entity["type"]:
"spawn_gate": instance = player_scene.instantiate()
"transition_gate": instance = exit_scene.instantiate()
"item": instance = item_scene.instantiate()
if instance:
instance.position = spawn_pos
add_child(instance)