npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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 by scripts/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 by scripts/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.0

It 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 are

then 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.node picks 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 in sounds/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.