Skip to main content

Migrating from MonoGame.Extended.Tiled

Preview release

This feature is currently only available in the preview release 6.0.0-preview.1. If you find outdated information, please open an issue.

Samples are available in the version/6.0.0 branch of MonoGame-Extended-Samples.

The MonoGame.Extended.Tiled namespace has been deprecated in favor of the new MonoGame.Extended.Tilemaps system. The new system supports Tiled, LDtk, and Ogmo Editor through a single API and uses a simpler, SpriteBatch-based renderer.

Deprecated

MonoGame.Extended.Tiled is deprecated and will be removed in a future major version. Begin migrating to MonoGame.Extended.Tilemaps to avoid breaking changes in a future release.

What Changed and Why

The old MonoGame.Extended.Tiled system was designed exclusively for the Tiled Map Editor. Its core types (TiledMap, TiledMapTileLayer, etc.) were tightly coupled to Tiled-specific concepts, making it impossible to support other formats without duplicating the entire system.

The new MonoGame.Extended.Tilemaps system introduces a format-agnostic intermediate representation that all format parsers convert to. This means:

  • All three formats (Tiled, LDtk, Ogmo) share the same runtime types
  • The renderer does not need to know which editor created the map
  • Adding support for new formats in the future only requires a new parser

The new renderer is also simpler. The old TiledMapRenderer built vertex and index buffers and required manual blend state setup. The new TilemapSpriteBatchRenderer uses SpriteBatch with the same conventions as the rest of your game code.

Step 1: Update Namespaces

Replace the old namespace imports with the new ones:

Before:

using MonoGame.Extended.Tiled;
using MonoGame.Extended.Tiled.Renderers;

After:

using MonoGame.Extended.Tilemaps;
using MonoGame.Extended.Tilemaps.Rendering;

Step 2: Update the Content Pipeline

The new system uses different importers in the MGCB Editor. Open your .mgcb file or the MGCB Editor and update the importer and processor for each tilemap file:

SettingOld ValueNew Value
ImporterTiledMapImporter - MonoGame.ExtendedTiled Tilemap Importer - MonoGame.Extended
ProcessorTiledMapProcessor - MonoGame.ExtendedTilemapProcessor - MonoGame.Extended

Tileset files (.tsx) also need their importer and processor updated:

SettingOld ValueNew Value
ImporterTiledMapTilesetImporter - MonoGame.Extended(no longer needed as a separate asset)
note

In the new system, external tilesets (.tsx files) are loaded automatically by the tilemap importer. You do not need to add them as separate items in the MGCB Editor in most cases. Check your importer output for guidance if external tilesets are not found.

Step 3: Update Field Declarations

Before:

private TiledMap _tiledMap;
private TiledMapRenderer _tiledMapRenderer;

After:

private Tilemap _tilemap;
private TilemapSpriteBatchRenderer _renderer;

Step 4: Update LoadContent

Before:

protected override void LoadContent()
{
_tiledMap = Content.Load<TiledMap>("maps/level1");
_tiledMapRenderer = new TiledMapRenderer(GraphicsDevice, _tiledMap);
_spriteBatch = new SpriteBatch(GraphicsDevice);
}

After:

protected override void LoadContent()
{
_tilemap = Content.Load<Tilemap>("maps/level1");

_renderer = new TilemapSpriteBatchRenderer();
_renderer.LoadTilemap(_tilemap);

_spriteBatch = new SpriteBatch(GraphicsDevice);
}

The new renderer does not require a GraphicsDevice reference at construction time.

Step 5: Update the Update Method

Before:

protected override void Update(GameTime gameTime)
{
_tiledMapRenderer.Update(gameTime);
base.Update(gameTime);
}

After:

protected override void Update(GameTime gameTime)
{
_renderer.Update(gameTime);
base.Update(gameTime);
}

Step 6: Update the Draw Method

The old renderer required manual blend state management for transparency. The new renderer handles this through its BlendState property.

Before:

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);

BlendState previousBlendState = GraphicsDevice.BlendState;
GraphicsDevice.BlendState = BlendState.AlphaBlend;

_tiledMapRenderer.Draw(_camera.GetViewMatrix());

GraphicsDevice.BlendState = previousBlendState;

base.Draw(gameTime);
}

After:

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);

// BlendState.AlphaBlend is correct when using the content pipeline
_renderer.BlendState = BlendState.AlphaBlend;
_renderer.Draw(_spriteBatch, _camera);

base.Draw(gameTime);
}
tip

The default blend state on TilemapSpriteBatchRenderer is BlendState.NonPremultiplied. When loading through the content pipeline, set it to BlendState.AlphaBlend because the content pipeline premultiplies alpha. When using a runtime parser, the default is correct.

Common API Mappings

Map Properties

Old APINew API
tiledMap.Widthtilemap.Width
tiledMap.Heighttilemap.Height
tiledMap.TileWidthtilemap.TileWidth
tiledMap.TileHeighttilemap.TileHeight
tiledMap.WidthInPixelstilemap.WorldBounds.Width
tiledMap.HeightInPixelstilemap.WorldBounds.Height
tiledMap.Orientationtilemap.Orientation
tiledMap.BackgroundColortilemap.BackgroundColor

Layer Access

Old APINew API
tiledMap.GetLayer("name")tilemap.Layers["name"]
tiledMap.GetLayer<TiledMapTileLayer>("name")tilemap.Layers["name"] as TilemapTileLayer
tiledMap.TileLayerstilemap.Layers with is TilemapTileLayer filter
tiledMap.ObjectLayerstilemap.Layers with is TilemapObjectLayer filter
layer.IsVisiblelayer.IsVisible

Tile Access

Old APINew API
tileLayer.TryGetTile(x, y, out TiledMapTile? tile)TilemapTile? tile = tileLayer.GetTile(x, y)
tile.Value.GlobalIdentifiertile.Value.GlobalId
tile.Value.IsFlippedHorizontally(tile.Value.FlipFlags & TilemapTileFlipFlags.FlipHorizontally) != 0
tile.Value.IsBlanktile == null or !tile.HasValue

Tileset Access

Old APINew API
tiledMap.GetTilesetByTileGlobalIdentifier(gid)tilemap.Tilesets.GetTilesetByGlobalId(gid)
tiledMap.GetTilesetFirstGlobalIdentifier(tileset)tileset.FirstGlobalId

Object Access

Old APINew API
objectLayer.ObjectsobjectLayer.Objects
mapObject.Nameobj.Name
mapObject.Positionobj.Position
TiledMapRectangleObjectTilemapRectangleObject
TiledMapEllipseObjectTilemapEllipseObject
TiledMapPolygonObjectTilemapPolygonObject
TiledMapTileObjectTilemapTileObject

Properties

Old APINew API
map.Properties.TryGetValue("key", out string val)map.Properties.TryGetValue("key", out TilemapPropertyValue val)
(string) property valueval.AsString() or map.Properties.GetString("key", "default")

The new properties system is typed. Each property has an explicit type (String, Int, Float, Bool, Color) rather than storing everything as strings. Use the typed getter methods (GetString, GetInt, GetFloat, GetBool, GetColor) for safe access with defaults.

Camera Integration

The old renderer accepted a raw Matrix from _camera.GetViewMatrix(). The new renderer accepts an OrthographicCamera directly and derives the matrix internally, which allows it to apply parallax layer offsets correctly:

Before:

_tiledMapRenderer.Draw(_camera.GetViewMatrix());

After:

_renderer.Draw(_spriteBatch, _camera);

Before and After: Complete Example

Before (old system):

using MonoGame.Extended.Tiled;
using MonoGame.Extended.Tiled.Renderers;

public class Game1 : Game
{
private TiledMap _tiledMap;
private TiledMapRenderer _tiledMapRenderer;
private OrthographicCamera _camera;

protected override void LoadContent()
{
_tiledMap = Content.Load<TiledMap>("maps/level1");
_tiledMapRenderer = new TiledMapRenderer(GraphicsDevice, _tiledMap);
}

protected override void Update(GameTime gameTime)
{
_tiledMapRenderer.Update(gameTime);
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);

BlendState prev = GraphicsDevice.BlendState;
GraphicsDevice.BlendState = BlendState.AlphaBlend;
_tiledMapRenderer.Draw(_camera.GetViewMatrix());
GraphicsDevice.BlendState = prev;

base.Draw(gameTime);
}
}

After (new system):

using MonoGame.Extended.Tilemaps;
using MonoGame.Extended.Tilemaps.Rendering;

public class Game1 : Game
{
private Tilemap _tilemap;
private TilemapSpriteBatchRenderer _renderer;
private OrthographicCamera _camera;
private SpriteBatch _spriteBatch;

protected override void LoadContent()
{
_tilemap = Content.Load<Tilemap>("maps/level1");

_renderer = new TilemapSpriteBatchRenderer();
_renderer.BlendState = BlendState.AlphaBlend;
_renderer.LoadTilemap(_tilemap);

_spriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void Update(GameTime gameTime)
{
_renderer.Update(gameTime);
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
_renderer.Draw(_spriteBatch, _camera);
base.Draw(gameTime);
}
}