Asset library
Ready-made models, sprites, textures, sounds and music by name (Library.model).
The engine has a library of ready-made assets, all made in code in one consistent style: 145 low-poly 3D models, 88 2D sprites (10 animated characters, items, 32 UI icons, tiles and a tile set, background layers, effects), 15 textures, 16 looks (palettes with matching light), 72 sounds and 10 music loops. No files, no downloads, nothing to host: an asset is made the first time something draws it. Use it whenever the game has no art of its own: it looks better than shapes made by hand, and costs one line. The full reference (every option, every id) is "Asset library" in the API reference.
import { Transform } from '@onceworlds/engine';
import { Library, SpriteAnim } from '@onceworlds/engine/modules';
// 3D: a model where the Transform puts it, standing on y = 0, facing -z.
world.spawn([Transform({ position: [4, 0, -2] }), ...Library.model('tree.pine', { height: 6 })]);
world.spawn([Transform({ position: [0, 0, 0] }), ...Library.model('crate', {}, { body: 'dynamic' })]); // with physics
world.spawn([Transform({ position: [2, 1, 0] }), ...Library.model('coin', {}, { collider: 'sensor' })]); // a pickup trigger
Library.scatter(world, 'tree.oak', { count: 30, area: [80, 80], avoid: [[0, 0, 10]] }); // a forest, few draw calls
Library.backdrop(world, 'meadow'); // sky, sun with shadows, ambient light and fog in one look
// 2D: a sprite the size it should be; a character plays its clips (idle, run, jump, fall, hurt).
const hero = world.spawn([Transform({ position: [0, -2, 0] }), ...Library.sprite('char.knight')]);
hero.get(SpriteAnim).clip = 'run';
Library.backdrop(world, 'forest'); // in a 2D world: parallax background layers
// Sound: the catalog's names play like the built-in effects; loops by mood.
audio.play('coin.chime');
audio.music.play('music.adventure');
The rules that keep it looking good
- One look per game. Every asset takes
palette(a look):meadow(default),forest,autumn,winter,desert,tropical,swamp,volcanic,candy,neon,dusk,night,spooky,toy,pastel,scifi. Bind it once:const lib = Library.with({ palette: 'winter' }), thenlib.model('tree.pine'),lib.sprite('coin'). Light the scene with the same look:Library.backdrop(world, 'winter'). Mixing looks is what makes a game look thrown together. - Variety from seeds, sizes from parameters.
seedgives another variation of the same asset; numbers likeheight,size,lengthandfloorschange its shape. Out of range, a number is kept in range (and a warning says so). - Same name, one draw call. Every copy with the same id and parameters shares one geometry and draws in one call, so a forest of
one pine costs one draw. For variety use 3 to 5 seeds and turn and scale copies with their Transform (what
Library.scatterdoes), not a differentheightfor every tree. - Glowing parts glow. Lamps, flames, crystals, screens and lit windows have their own glow: add
PostFx.polished()(bloom) to the camera and they shine. - Scale. Metres, y up. A door is 2 m, a character 1.8 m, a crate 1 m. Models stand on y = 0 and face -z (a vehicle's nose, a
building's door).
Library.size(id, params)says how big one is, to place things on and next to each other. - Colliders fit.
{ body: 'static' | 'dynamic' | 'kinematic' }adds a body and the collider that fits the model;{ collider: true }a fixed collider,{ collider: 'sensor' }a trigger. Trees get a trunk-sized cylinder, round things a sphere, the rest a box.Library.collider(id, params)gives one on its own.
Finding assets
- Ids read as what they are:
tree.pine,rock.boulder,house.cottage,castle.tower,car.sports,coin,sword,char.ninja,icon.settings,tile.grass,bg.mountains,ui.click,explosion.big,music.battle. Models and sprites of the same thing share an id:Library.model('coin')is the 3D coin,Library.sprite('coin')the 2D one. Library.search('red mushroom'),Library.search('click', { kind: 'sound' })andLibrary.list({ kind: 'model', category: 'vehicles' })say what there is, with each asset's parameters, size and the line that uses it. A wrong id fails at once and names the nearest ones:Library.model('pine')says "Did you mean 'tree.pine'?".- Outside the game, the MCP tool
search_assetsfinds them by words, each with the line that uses it.
3D in more detail
Library.model(id, params, options)returns aMesh(its geometry, named'lib:model/<id>?...') and aMaterial(white: the model's own colours show).options.materialchanges the material ({ kind: 'toon' }, a tint,{ opacity: 0.5 }).- Change a model later by its name:
entity.get(Mesh).geometry = Library.name('model', 'tree.oak', { palette: 'autumn' }). Library.texture('brick')is a texture's name for any material:Material.standard({ map: Library.texture('wood'), repeat: [4, 4] }), orLibrary.material('stone')for a ready material. Textures tile without seams.- In a scene file, a library model is a
LibraryModel3Dnode:{ "kind": "LibraryModel3D", "components": { "Mesh": { "geometry": "lib:model/tree.pine?height=6" } } }. Build's Assets panel drags them in and edits their parameters in the Inspector.
2D in more detail
Library.sprite(id, params, { size, layer, z, clip }):sizeis a height (keeping the picture's shape) or[width, height]in world units. Characters are sheets of 13 frames (96 pixels each) with the clipsidle,run,jump,fallandhurt; they face right (Sprite.flipXfor left) and stand on their Transform (anchor at the feet).- Tiles:
tile.*sprites one by one, or the tile set for aTileMapnode:Tilemap({ tileset: Library.tileset('tiles.platformer'), tiles: ['. . 0 0', '0 0 1 1'] })(0 grass, 1 dirt, 2 stone, 3 brick, 4 wood, 5 ice, 6 sand, 7 metal, 8 lava, 9 water, 10 crate, 11 spikes, 12 ladder, 13 cloud, 14 bridge, 15 bonus). - Icons (
icon.play,icon.settings...) are white with an ink edge, for any background;{ badge: true }puts one on a round button (colorsets the button's colour). Library.backdrop(world, look)in a 2D world adds the look's background layers (sky, clouds, mountains, hills, forest, city, stars, sea, desert, cave), as tall as the camera's view, each scrolling slower the further away it is (Parallax).
Sound and music
- 72 sounds by moment:
ui.*(click, hover, toggle, open, close, confirm, back, error, notify, popup...),coin.*,gem.sparkle,pickup.*,powerup.*,jump.*,land.*,step.*,dash,water.*,hit.*,block,shoot.*,explosion.smalland.big,hurt,death,enemy.defeat,door.*,chest.open,lever,bell,portal,teleport,alarm,timer.*, and stingers (stinger.win,.lose,.levelup,.unlock,.achievement,.gameover,.start,.secret).audio.play(name)and anAudioSource'ssoundtake them like the built-in effects. - 10 loops:
music.adventure,.battle,.calm,.mystery,.spooky,.happy,.space,.retro,.race,.victory.audio.music.setIntensity(0..1)adds layers as the game heats up.
In tests
Geometry and pictures are made by code that loads the first time a game draws a library asset (so a game that uses none downloads
none of it). Game logic never waits for it: names, sizes and colliders are there at once. A test that reads geometry or draw lists
calls await Library.load() first.