Skip to content

Loaders

three-flatland provides loaders for common 2D asset formats. All loaders share a unified texture configuration system with hierarchical presets.

Available Loaders

LoaderFormatUse Case
TextureLoaderPNG, JPG, SVG, etc.Single textures with preset support
SpriteSheetLoaderTexturePacker JSONSpritesheets and atlases
TiledLoaderTiled .json/.tmjTile-based maps
LDtkLoaderLDtk .ldtkLevel design with entities

TextureLoader

Load textures with automatic preset application. Works seamlessly with R3F’s useLoader.

import { TextureLoader, Sprite2D } from 'three-flatland';
// Load texture (presets automatically applied)
const texture = await TextureLoader.load('/sprites/player.png');
const sprite = new Sprite2D({ texture });

Multiple Textures

import { TextureLoader } from 'three-flatland';
// Preload multiple textures
const textures = await TextureLoader.preload([
'/sprites/player.png',
'/sprites/enemy.png',
'/sprites/items.png',
]);

Override Presets

// Override preset for specific texture
const smoothTexture = await TextureLoader.load('/sprites/hd-ui.png', {
texture: 'smooth'
});

SpriteSheetLoader

Load spritesheets exported from TexturePacker or compatible tools.

import { SpriteSheetLoader, Sprite2D } from 'three-flatland';
const sheet = await SpriteSheetLoader.load('/sprites/player.json');
// Access frames
const idleFrame = sheet.getFrame('player_idle_0');
const allFrames = sheet.getFrameNames();
// Use with Sprite2D
const sprite = new Sprite2D({ texture: sheet.texture });
sprite.setFrame(idleFrame);

Multiple Spritesheets

const sheets = await SpriteSheetLoader.preload([
'/sprites/player.json',
'/sprites/enemies.json',
]);

Supported Formats

  • JSON Hash (TexturePacker default) - Frames as object properties
  • JSON Array - Frames as array with filename property

TiledLoader

Load maps from Tiled Map Editor. See the Tilemaps guide for detailed usage.

import { TiledLoader, TileMap2D } from 'three-flatland';
const mapData = await TiledLoader.load('/maps/level1.json');
const tilemap = new TileMap2D({ data: mapData });

Features

  • Embedded and external tilesets
  • Tile layers with flip flags
  • Object layers for entities and collision
  • Tile animations
  • Infinite maps with chunks

LDtkLoader

Load projects from LDtk. See the Tilemaps guide for detailed usage.

import { LDtkLoader, TileMap2D } from 'three-flatland';
// Load a specific level
const mapData = await LDtkLoader.load('/maps/world.ldtk', 'Level_0');
const tilemap = new TileMap2D({ data: mapData });
// List all levels in project
const levelIds = await LDtkLoader.getLevelIds('/maps/world.ldtk');

Features

  • Multi-level projects
  • Tile layers (Tiles, AutoLayer, IntGrid)
  • Entity layers with custom fields
  • IntGrid collision data
  • Tile flip flags

Texture Presets

All loaders use a unified texture configuration system. Presets control filtering, wrapping, and mipmaps.

Available Presets

PresetFilteringWrapMipmapsBest For
'pixel-art'NearestClampOffPixel art, retro games, tilemaps
'smooth'LinearClampOnHD sprites, smooth graphics
'none'Full manual control

Configuration Hierarchy

Texture options follow a hierarchy (highest to lowest priority):

Instance preset/options → Loader.options → TextureConfig.options → 'pixel-art'
(highest) (middle) (lowest) (default)

For TextureLoader with R3F’s useLoader, the instance preset is set via the extension callback:

// Instance-level override via extension
const texture = useLoader(TextureLoader, '/sprite.png', (loader) => {
loader.preset = 'smooth'; // Highest priority
});

Each level overrides the ones below it. If nothing is set, 'pixel-art' is used.

Global Configuration

Set a system-wide default for all loaders:

import { TextureConfig } from 'three-flatland';
// Change global default
TextureConfig.options = 'smooth';
// All loaders now use smooth filtering
const sheet = await SpriteSheetLoader.load('/sprites/player.json');
const mapData = await TiledLoader.load('/maps/level.json');
// Reset to system default
TextureConfig.reset(); // Back to 'pixel-art'

Per-Loader Configuration

Override the default for a specific loader type:

import { TextureLoader, SpriteSheetLoader, TiledLoader } from 'three-flatland';
// HD textures with smooth filtering
TextureLoader.options = 'smooth';
// HD sprites with smooth filtering
SpriteSheetLoader.options = 'smooth';
// Tilemaps stay pixel-perfect
TiledLoader.options = 'pixel-art';
// Now these use different settings
const texture = await TextureLoader.load('/sprites/hd-player.png'); // smooth
const sprites = await SpriteSheetLoader.load('/sprites/ui.json'); // smooth
const mapData = await TiledLoader.load('/maps/dungeon.json'); // pixel-art

Per-Instance Configuration

Override for a specific load call:

// One-off override
const hdSheet = await SpriteSheetLoader.load('/sprites/hd-ui.json', {
texture: 'smooth'
});
// Custom options
const customSheet = await SpriteSheetLoader.load('/sprites/special.json', {
texture: {
minFilter: LinearFilter,
magFilter: NearestFilter, // Mix filtering modes
}
});

Full Manual Control

Use 'none' for complete control via .then():

import { RepeatWrapping } from 'three';
const sheet = await SpriteSheetLoader.load('/sprites/tiles.json', {
texture: 'none'
}).then(s => {
// Full manual configuration
s.texture.wrapS = RepeatWrapping;
s.texture.wrapT = RepeatWrapping;
s.texture.anisotropy = 16;
return s;
});

Common Patterns

Pixel Art Game (default)

// Just use defaults - pixel-art is the system default
const sheet = await SpriteSheetLoader.load('/sprites/player.json');
const mapData = await TiledLoader.load('/maps/level.json');

HD Game

// Set global default once at startup
TextureConfig.options = 'smooth';
// All loads now use smooth filtering
const sheet = await SpriteSheetLoader.load('/sprites/player.json');

Mixed Styles

// Configure each loader type
SpriteSheetLoader.options = 'smooth'; // HD sprites
TiledLoader.options = 'pixel-art'; // Pixel tilemaps
// Or override per-instance
const pixelSprite = await SpriteSheetLoader.load('/sprites/retro.json', {
texture: 'pixel-art'
});

Caching

All loaders cache results by URL and texture options. Subsequent loads return the cached promise:

// First load - fetches from network
const sheet1 = await SpriteSheetLoader.load('/sprites/player.json');
// Second load - returns cached result instantly
const sheet2 = await SpriteSheetLoader.load('/sprites/player.json');
console.log(sheet1 === sheet2); // true

Different texture options create separate cache entries:

// These are cached separately
const pixelSheet = await SpriteSheetLoader.load('/sprites/ui.json', { texture: 'pixel-art' });
const smoothSheet = await SpriteSheetLoader.load('/sprites/ui.json', { texture: 'smooth' });
console.log(pixelSheet === smoothSheet); // false

Clear the cache when needed:

TextureLoader.clearCache();
SpriteSheetLoader.clearCache();
TiledLoader.clearCache();
LDtkLoader.clearCache();

Preloading

Load multiple assets in parallel:

// Preload spritesheets
const sheets = await SpriteSheetLoader.preload([
'/sprites/player.json',
'/sprites/enemies.json',
'/sprites/items.json',
]);
// Preload maps
const maps = await TiledLoader.preload([
'/maps/level1.json',
'/maps/level2.json',
]);

With texture options:

const sheets = await SpriteSheetLoader.preload(
['/sprites/ui.json', '/sprites/hud.json'],
{ texture: 'smooth' }
);