Skip to main content

Tiled Levels And World Builder

Tiled maps are the preferred source for map-driven Hs2d worlds. A prepared map defines the world size, layer order, image layers, tile layers, decor, entity placements, and data-only zones. Runtime code binds those objects to fixed-capacity systems and then keeps gameplay state in scene-owned structures.

Use this page as the entry point. The detailed contracts live in the focused pages below.

Workflow

End-to-end Tiled workflow from finite map authoring and HST preparation to retained Hs2d layers, entity groups, decor, zones, and scene-owned simulationEnd-to-end Tiled workflow from finite map authoring and HST preparation to retained Hs2d layers, entity groups, decor, zones, and scene-owned simulation

During gameplay, update scene-owned state and synchronize retained sprites. Do not scan raw map data in the frame loop.

Tiny End-To-End Example

Keep the same names across the bundle, asset gate, Tiled properties, and world builder.

asset-bundle.json exposes namespaced manifest keys:

{
"bundleId": "my-game",
"assets": [
{ "key": "my-game.levels.level-1", "url": "/asset-bundles/my-game/levels/level-1.json", "fileName": "levels/level-1.json" },
{ "key": "my-game.images.tile-atlas", "url": "/asset-bundles/my-game/images/tile-atlas.png", "fileName": "images/tile-atlas.png" },
{ "key": "my-game.images.sky", "url": "/asset-bundles/my-game/images/sky.png", "fileName": "images/sky.png" },
{ "key": "my-game.images.enemy-atlas", "url": "/asset-bundles/my-game/images/enemy-atlas.png", "fileName": "images/enemy-atlas.png" }
]
}

Code resolves those manifest keys to URIs, then registers short asset-gate names:

const gate = new Hs2dAssetGate({ bitmapCache: this.bitmapCache })
.add('tile-atlas', this.resolveBundleUri(
'my-game.images.tile-atlas',
'pkg:/asset-bundles/my-game/images/tile-atlas.png',
))
.add('sky', this.resolveBundleUri(
'my-game.images.sky',
'pkg:/asset-bundles/my-game/images/sky.png',
))
.add('enemy-atlas', this.resolveBundleUri(
'my-game.images.enemy-atlas',
'pkg:/asset-bundles/my-game/images/enemy-atlas.png',
));

Tiled uses the gate names, not the namespaced manifest keys:

Image layer: sky
hs2d:role = sky
hs2d:asset = sky

Tile layer: terrain
hs2d:mode = auto
hs2d:z = 40

Object group: entities
hs2d:role = entities
object type = enemy

The builder uses the same gate names:

const built = Hs2dWorldBuilder.fromLevel({
level: this.loadedLevel as Hs2dLevel,
assets: gate,
viewportWidth: this.screenWidth,
viewportHeight: this.screenHeight,
tilesetAsset: 'tile-atlas',
entities: {
enemy: {
capacity: 16,
asset: 'enemy-atlas',
frames: [{ id: 'enemy', x: 0, y: 0, width: 64, height: 64 }],
initialFrameId: 'enemy',
spawn: (object, sprite) => {
sprite.setWorldPosition(object.x, object.y);
},
},
},
hud: this,
});
ConceptName in this example
Manifest keymy-game.images.enemy-atlas
Fallback URIpkg:/asset-bundles/my-game/images/enemy-atlas.png
Asset-gate nameenemy-atlas
Entity binding assetasset: 'enemy-atlas'
Tiled entity typeenemy

Do And Don't

DoDon't
Prepare raw Tiled JSON before runtime use.Ship raw compressed/chunked/infinite Tiled exports to the runtime.
Register every bitmap referenced by Tiled image layers, tilesets, decor, and entity bindings.Build the world before the asset gate reports ready.
Use short gate names consistently in Tiled and builder options.Put a namespaced manifest key in Tiled unless the gate uses that exact same string.
Copy object data into scene-owned arrays or pools during build/setup.Re-scan Tiled object arrays every frame.
Use hs2d:mode and builder overrides to choose tile renderers.Implement custom per-frame tile draw loops for ordinary maps.

Detailed Pages

PageUse it for
Tiled Map RequirementsRaw Tiled export versus prepared runtime JSON, supported map subset, prep behavior, runtime rejection cases, tilesets, tile ids, objects, and solidity.
Tiled Layer PropertiesVerified hs2d:* properties, native Tiled parallax/offset fields, image layer options, tile layer modes, object group roles, decor object properties, clear colors, and defaults.
World Builder And Level LoadingHs2dLevelManager, Hs2dLevelLoader, Hs2dAssetGate, Hs2dWorldBuilder.fromLevel, tile mode overrides, built world references, and sample build flow.
Entity Bindings Decor And ZonesBinding Tiled object types to sprite groups, spawn callbacks, capacity sizing, decor frame mapping, named sprite layers, zones, and game-owned object properties.

Source Anchors

The core implementation lives in:

  • ../games/hosanna-ui/src/hosanna-game/hosanna2d/level/Hs2dTiledLevel.ts
  • ../games/hosanna-ui/src/hosanna-game/hosanna2d/level/Hs2dLevel.ts
  • ../games/hosanna-ui/src/hosanna-game/hosanna2d/level/Hs2dLevelLoader.ts
  • ../games/hosanna-ui/src/hosanna-game/hosanna2d/level/Hs2dLevelManager.ts
  • ../games/hosanna-ui/src/hosanna-game/hosanna2d/Hs2dWorldBuilder.ts
  • ../hosanna-tools/src/support-tools/tiled-prep.ts

The most useful sample scenes are:

  • ../hosanna-ui-game-samples-public/src/hosanna-game-examples/native-shoot-em-up/VerticalShooterLevelScene.ts
  • ../hosanna-ui-game-samples-public/src/hosanna-game-examples/hosanario/HosanarioLevelScene.ts
  • ../hosanna-ui-game-samples-public/asset-bundles/hosanario/levels/build_levels.py
Talk to us