@v12-engine/assets
v0.1.1
Published
Models a game made with V12 may take: characters with their clips, buildings, nature, props, gear and resources, each free to publish with
Readme
@v12-engine/assets
Models a game made with V12 may take, in groups: characters with their clips, buildings, nature, props, gear and
resources, and the pictures effects are drawn with. Every file is free to publish a game with (CC0, as each group's
CREDITS.md says), and the package has nothing but models and pictures: a game's sounds, music and ground pictures are
its own (a ground can be made in code with no picture: pattern: 'grass' on a tile's look).
The engine and the client have no art of their own. A game takes what it wants from here, or nothing.
The groups
| Group | What | Size |
| --------------- | ---------------------------------------------------------------------------------------------------------------- | ------- |
| characters | A knight, a barbarian, a mage, a ranger, two rogues, four skeletons and mannequins, with their clips | 12.9 MB |
| animations | KayKit's every clip for its medium and large rigs, as they come: a game takes others from here | 8.7 MB |
| gear | What the adventurers hold: swords, axes, a dagger, bows, crossbows, arrows, shields, a staff, books | 0.5 MB |
| skeleton-gear | What the skeletons hold: a blade, an axe, a crossbow, a staff, shields, a quiver and arrows | 0.3 MB |
| weapon-bits | Swords, axes, hammers, spears, a halberd, bows and arrows, staffs, a wand, shields, fist weapons | 0.9 MB |
| weapons | Axes, a cleaver, a dagger, a talwar, a trident, a devil's sword and axe | 0.3 MB |
| ground | Pictures to paint the ground with: blight (for the client's blightLook) | 0.1 MB |
| fx | Pictures particles and marks are drawn with: smoke and flame flipbooks, sparks, flares, a ring, a scorch, glyphs | 0.3 MB |
| items | Armour, weapons, shields, potions, books, keys, coins, crowns | 1.8 MB |
| rts | A fantasy RTS in ages: town centres, barracks, temples, castles, walls, farms, mines, ports | 13.6 MB |
| village | A medieval village: houses, an inn, a blacksmith, a mill, a stable, and what lies about it | 3.0 MB |
| farm | Barns, a chicken coop, silos, a windmill and fences | 0.7 MB |
| dungeon-kit | KayKit's dungeon: floors, walls, gates, stairs, scaffolds, furniture, chests, loot, weapons, heroes | 5.6 MB |
| dungeon | Halls of stone to build: walls, floors, arches, columns, chests, torches, treasure | 2.1 MB |
| props | What fills a house, a shop or a forge: furniture, barrels, crates, books, candles, potions, banners | 15.4 MB |
| resources | Gold, silver, copper and iron as nuggets and bars, wood, planks, stone, bricks, cloth, fuel, parts | 2.6 MB |
| forest | Common, pine, dead and twisted trees, bushes, flowers, grass, mushrooms, rocks and paths | 9.1 MB |
| trees | Oaks, pines, columnar trees, swiggly trees and willows | 1.7 MB |
manifest.json lists every file with what it is: a model's clips, its parts and its size, and its credit.
In a game
A group is laid out as a game's own folder is (models/), and a game names its files as it names its own: a model by
its path in models/. The index gives each by a name in code, typed, so that a name that is not there is an error:
import { characters, forest, gear } from '@v12-engine/assets'
const view: GameView = {
units: {
looks: { knight: { model: { src: characters.models.knight, scale: 0.7, hold: [{ src: gear.models.sword1handed, at: 'handslot.r' }] } } }
},
ground: {
tiles: { grass: { color: [0.33, 0.52, 0.2], pattern: 'grass' } },
doodads: [forest.models.commonTree1, forest.models.rockMedium1]
}
}The paths are plain strings: 'characters/knight.glb' is the same thing. The characters play KayKit's clips, which
are the client's names for them by default (Idle_A, Running_A, Melee_1H_Attack_Chop, Death_A…). The characters of KayKit's
medium rig keep those clips in one file beside them (rig_medium_clips.glb, the skeletons' own in
rig_medium_skeleton_clips.glb), fetched once for all of them: each character's file names it (scripts/clips.mjs), the
client plays it on the character, and a build copies it with any character that plays it.
The page finds the files where it finds a game's shared ones (/models/…), served by the client's Vite plugin
(@v12-engine/client/vite). See docs/start/new-project.md.
Where the files came from
The packs the developer gave, made smaller and the package's size by scripts/packs.mjs (how, in the script):
rts,village,farm,dungeon,items,weapons: Quaternius's packs as poly.pizza gives them, CC0.forest,props: Quaternius's Stylized Nature MegaKit and Fantasy Props MegaKit (Standard), CC0.fx: Kenney's Particle Pack 1.1, CC0, made small and its smoke and flames put together as flipbooks byscripts/fx.mjs. The client's ready-made effects (presetFx) draw with these where a game has the package, and with pictures made in the page where it has not.characters: KayKit Adventurers 2.0 and Skeletons 1.1, each given clips of KayKit Character Animations 1.1 (Kay Lousberg, CC0), and Quaternius's Universal Animation Library mannequin (CC0).animations: those clips, all of them.dungeon-kit,skeleton-gear: KayKit Dungeon Pack 1.0, KayKit Skeletons 1.1, CC0.gear,weapon-bits,resources: KayKit Adventurers 2.0, Fantasy Weapons Bits 1.0, Resource Bits 1.0, CC0.trees: the Stylized Trees pack, FBX made GLB byscripts/fbx.mjs; its licence is not in the pack (credited CC0 as the developer gave it, to be checked).
Adding art
npm run add -w @v12-engine/assets -- nature path/to/oak.glb --author "You" --licence CC0-1.0
npm run add -w @v12-engine/assets -- characters orc.glb --as units/orc.glb
npm run add -w @v12-engine/assets -- sounds swing.mp3 # a sound named swing; another swing.mp3 is its next take
npm run add -w @v12-engine/assets -- dungeon wall.png --group-name Dungeon --group-description "Stone halls" --author "You" --licence CC0-1.0It checks the file, puts it where its kind goes under a plain name (models/<group>/<name>.glb when --as does not
say), takes out of a model what it does not use (--no-optimize leaves it as it is), makes a model's lighter levels
beside it (below; --no-lod makes none, --lod makes them for gear, weapons and items too), credits it (the group's credit
that is about it, or the one --author and --licence give), and writes the manifest, the index and the credits
again. It says where it went, its name in code, and what is not as the conventions below say; it does not change
a file to fit them. What is wrong (no credit, a licence a game cannot be published with, a GLB that needs files
beside it, a path two groups would share) stops it, with nothing written.
By hand: put the file in its group's folder, add a credit to group.json if none is about it, and
npm run index -w @v12-engine/assets. npm run check -w @v12-engine/assets (and the package's test) fails on anything
left wrong.
A new group is a folder of groups/ with a group.json: { "name", "description", "credits": [{ "files": ["models/<group>/*"], "author", "work", "licence", "url", "note" }] }.
A credit's files are patterns: * is anything within a folder, ** across folders.
Levels of a model
What is seen from far is drawn lighter there (the client's DetailLevel): each model of the groups seen from far
(forest, trees, rts, village, farm, dungeon, props, resources, dungeon-kit, characters) has two levels made beside it,
pine_1.lod1.glb and pine_1.lod2.glb, about 40% and 15% of its triangles, and the manifest lists them with its
model (levels: each file, its triangles, the part it keeps). A level is its model simplified (meshoptimizer), each
part on its own so its materials stay; its pictures and clips are left out, as the client draws it with its full
model's materials (by their names) and clips; a flat-shaded part is simplified by where its corners are and shaded
flat again, its error capped (0.01, 0.02) so its walls do not cave in; a skinned model keeps its one skin, its error
capped (0.03, 0.06) so its hair and its hat stay. A model under 300 triangles has none, and a level that keeps more
than 85% of the one before is not written. Made again with:
npm run lod -- packages/assets/groups/forest packages/assets/groups/trees # files or folders; levels made beside each model
npm run lod -- packages/assets/groups/dungeon-kit --borders # kit pieces that tile: their seams still meet
npm run lod -- some/model.glb --ratios 0.5,0.2 --error 0.01,0.05 # other parts kept; a cap on how far each strays
npm run lod -- packages/assets/groups/forest --check # which models have no levels, or levels older than they arethen npm run index -w @v12-engine/assets. A game's own models get theirs the same way, in public/models or its own
folder: the client finds them by the game's assets.json (levels), the shared models/levels.json the Vite plugin
serves, or beside the model.
Conventions
- Licences: CC0-1.0, CC-BY-4.0, CC-BY-3.0, OFL-1.1 or MIT, and nothing else: what a game can be published with. A file whose author or licence is not known is not added.
- Names: lower case, numbers and underscores (
tree_single_a.glb), saying what it is. - Models: GLB, textures inside. Its unit is a cell (a metre): a person is about 1.8 tall, a tree 3 to 6. It
stands on its origin, facing +Z (glTF's front, as the KayKit models do: they play with no
turn), Y up. Its animations are named as a game says them:idle,walk,run,attack,die,work,cast(the KayKit models keep their pack's names,Idle,Walking_A). A collection of several models in one file names each part (ModelDef.nodepicks one). - Textures: square, a power of two (256 or 512: the client draws a ground at 256), seamless where they repeat.
- Sounds: mp3, short, mono, 64 kbit/s or so. Takes of one sound are
name_1.mp3,name_2.mp3…, played one at a time. Music: mp3 insounds/music/, stereo, 128 kbit/s, made to loop. - Size: a group under 32 MB, the package under 128 MB, with its levels (the package's test says so).
The scripts
| Script | What it does |
| ---------------------------------------- | ---------------------------------------------------------------------------- |
| npm run index -w @v12-engine/assets | Writes manifest.json, index.js, index.d.ts and each CREDITS.md again |
| npm run check -w @v12-engine/assets | Writes nothing; fails where something is wrong or not written as it is now |
| npm run add -w @v12-engine/assets | Takes a file into a group, checked and credited (above) |
| npm run lod -- <files or folders> | Makes the lighter levels of models beside them (above) |
| node packages/assets/scripts/packs.mjs | Makes every group again from the packs as they came (how, in it) |
| node packages/assets/scripts/fbx.mjs | Makes GLBs of a pack that comes as FBX (the Stylized Trees), for packs.mjs |
index.js, index.d.ts, manifest.json and the CREDITS.md files are written by the index script, never by hand.
