@homie-rocks/studio 0.24.5 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1195,6 +1195,45 @@
1195
1195
  }
1196
1196
  }
1197
1197
  }
1198
+ },
1199
+ "0.25.0": {
1200
+ "files": {
1201
+ "CLAUDE.md": "ddf2b2a0376202f6",
1202
+ "README.md": "684b3cca8001673c",
1203
+ "HANDOFF.md": "ce7a8fd91c6bbee2",
1204
+ "games/README.md": "5ad32fe80c61f117",
1205
+ "music/README.md": "a3dc042dadd39df8",
1206
+ "videos/README.md": "16babc3437d5545b",
1207
+ "posts/README.md": "37841aae476bd540",
1208
+ "site/README.md": "ca131cd0472464fb",
1209
+ "site/src/worker.mjs": "ca3f1630f2420ad3"
1210
+ },
1211
+ "sections": {
1212
+ "AGENTS.md": {
1213
+ "(intro)": "214aa46eb3a895d5",
1214
+ "## Layout": "8baf49e4291e7e88",
1215
+ "## Commands (all through the pinned CLI in node_modules)": "d80ec56e4b4fc4c6",
1216
+ "## The site": "ab922bb6bde23293",
1217
+ "## Making games": "abf2f0d59341512d",
1218
+ "## The Game Codex and progress": "0738ef719cef3a4c",
1219
+ "## Art direction and models": "aaea65236db52126",
1220
+ "## Running live games (the back office)": "4aa5f513a7cd2c3b",
1221
+ "## Servers and AI seats": "98d08705087a33ec",
1222
+ "## Selling things (the shop)": "b04b0a2b25f524f2",
1223
+ "## Continuing a build from the Claude app": "0d68081e924ca419",
1224
+ "## Rules": "7e8458adc1b81ece",
1225
+ "## Beta": "9d02638207a26e73"
1226
+ }
1227
+ },
1228
+ "named": {
1229
+ "Homie Arcade": {
1230
+ "sections": {
1231
+ "AGENTS.md": {
1232
+ "## Commands (all through the pinned CLI in node_modules)": "b35df2c19cd4b534"
1233
+ }
1234
+ }
1235
+ }
1236
+ }
1198
1237
  }
1199
1238
  }
1200
1239
  }
@@ -0,0 +1,56 @@
1
+ /* The animation card: each character's clips against the verbs the game needs, every one a small looping preview drawn
2
+ * by the game engine under the game's light (anim_preview), where it came from (its own, or the CC0 library's clips
3
+ * retargeted onto its skeleton), the verbs it lacks with Add (anim_add: free, baked into its skeleton's clip library),
4
+ * and Feel: the Game Lab on the move that plays it (game_lab with its take), New beside Today. */
5
+ (function () {
6
+ var C = Card;
7
+ var state = { busy: null };
8
+ function tile(r, c, sc) {
9
+ var t = C.el('div', 'clip' + (c.have ? '' : ' missing'));
10
+ var art = C.el('div', 'art');
11
+ var src = r.previews && r.previews[c.verb];
12
+ var i = src ? C.img(src, r.id + ' ' + c.verb) : null;
13
+ if (i) art.appendChild(i); else art.appendChild(C.el('span', '', c.have ? '…' : '+'));
14
+ t.appendChild(art);
15
+ t.appendChild(C.el('b', '', c.verb + (c.loop ? ' ↻' : '')));
16
+ t.appendChild(C.el('span', '', c.have ? (c.source ? c.source + (c.retargeted ? ' · retargeted' : '') : 'its own') : 'missing'));
17
+ if (!c.have) t.appendChild(C.btn(state.busy === r.id + c.verb ? 'Adding…' : 'Add (free)', 'small', function () {
18
+ state.busy = r.id + c.verb; C.render();
19
+ C.call('anim_add', { game: sc.game, asset: r.id, verbs: [c.verb] }).then(function (res) { state.busy = null; C.tell('clip:' + r.id + c.verb, 'The person added the ' + c.verb + ' clip to ' + r.id + ' on the animation card (free, retargeted onto its skeleton).'); C.take(res); }).catch(function () { state.busy = null; C.render(); });
20
+ }));
21
+ var take = sc.feel && sc.feel[c.verb];
22
+ if (c.have && take) t.appendChild(C.btn('Feel', 'ghost small', function () {
23
+ state.busy = 'Opening the Game Lab on “' + take + '”…'; C.render();
24
+ C.tell('feel:' + c.verb, 'The person pressed Feel on ' + r.id + '\'s ' + c.verb + ' clip: the Game Lab opens on the "' + take + '" take, New beside Today; its Motion sliders (fade, actSpeed, jumpStretch, landSquash, lean, ...) tune how it feels.');
25
+ C.call('game_lab', { game: sc.game, take: take }).then(function (res) { state.busy = null; C.take(res); }).catch(function () { state.busy = 'The Game Lab did not start.'; C.render(); });
26
+ }));
27
+ return t;
28
+ }
29
+ function render(sc) {
30
+ var card = C.el('main', 'card');
31
+ var rows = sc.rows || [];
32
+ var missing = rows.reduce(function (n, r) { return n + (r.missing || []).length; }, 0);
33
+ C.add(card, C.top('Clips', C.add(C.el('div', 'actions'), C.pill(missing ? missing + ' missing' : 'All there', missing ? 'warn' : 'ok'), C.fullscreenButton())),
34
+ C.el('h1', '', 'How the characters of ' + sc.game + ' move'),
35
+ C.el('p', 'sub', 'The game needs ' + (sc.verbs || []).join(', ') + '. Clips are baked into one library per skeleton at build time; every character on that skeleton shares it.'));
36
+ if (state.busy && !/^[a-z0-9-]+[a-z]+$/.test(state.busy)) card.appendChild(C.el('p', 'note', state.busy));
37
+ rows.forEach(function (r) {
38
+ var sec = C.el('section', 'chars');
39
+ sec.appendChild(C.add(C.el('div', 'dirhead'), C.el('b', '', r.id), C.el('span', '', r.familyLabel + ' · ' + r.bones + ' bones' + (r.animsKB ? ' · clips ' + r.animsKB + ' KB' : '') + ' · ' + r.route)));
40
+ if (r.shown) {
41
+ var grid = C.el('div', 'clips');
42
+ (r.clips || []).forEach(function (c) { grid.appendChild(tile(r, c, sc)); });
43
+ (r.extra || []).forEach(function (v) { grid.appendChild(tile(r, { verb: v, have: true, loop: false, source: null }, sc)); });
44
+ sec.appendChild(grid);
45
+ if (!r.previewed) sec.appendChild(C.btn(state.busy === 'draw' + r.id ? 'Drawing…' : 'Draw its clips (free)', 'ghost small', function () { state.busy = 'draw' + r.id; C.render(); C.call('anim_preview', { game: sc.game, asset: r.id }).then(function (res) { state.busy = null; C.take(res); }).catch(function () { state.busy = null; C.render(); }); }));
46
+ } else sec.appendChild(C.btn('Show its clips', 'ghost small', function () { C.call('anim_plan', { game: sc.game, asset: r.id }).then(C.take).catch(C.render); }));
47
+ card.appendChild(sec);
48
+ });
49
+ (sc.unrigged || []).forEach(function (u) { card.appendChild(C.el('p', 'fine', u + ' has no rig: a still model (the animate guide says how to rig one).')); });
50
+ var foot = C.el('div', 'foot');
51
+ foot.appendChild(C.el('span', 'when', Object.keys(sc.feel || {}).length ? 'Feel opens the Game Lab on this computer' : 'No Game Lab take yet: the lab guide adds one'));
52
+ card.appendChild(foot);
53
+ return card;
54
+ }
55
+ C.start({ kind: 'animation', label: 'Clips', fullscreen: true, render: render, poll: null });
56
+ })();
package/mcp/ui/card.css CHANGED
@@ -88,3 +88,7 @@ input[type=text]{flex:1;min-width:0;font:14px/1.2 var(--f-sans);padding:8px 10px
88
88
  .budget .track{height:8px;border-radius:4px;background:var(--c-bg3);overflow:hidden}.budget .track i{display:block;height:100%;background:var(--c-ok)}.budget .track i.over{background:var(--c-bad)}
89
89
  details summary{cursor:pointer;color:var(--c-fg2);font-size:13px;margin-top:10px}
90
90
  @media (max-width:420px){.card{padding:14px 12px 12px;border-radius:var(--r-md)}h1{font-size:18px}.stages{grid-auto-flow:row;grid-auto-columns:auto}.frame{height:520px}}
91
+ .chars{margin:12px 0 0;padding:10px;border-radius:var(--r-md);background:var(--c-bg2)}.chars .dirhead{margin-bottom:8px}
92
+ .clips{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:8px}
93
+ .clip{display:grid;gap:3px;align-content:start;padding:6px;border-radius:var(--r-sm);background:var(--c-bg)}.clip .art{aspect-ratio:1;border-radius:var(--r-sm);background:var(--c-bg3);display:grid;place-items:center;overflow:hidden;color:var(--c-fg3);font-size:20px}.clip .art img{width:100%;height:100%;object-fit:cover}
94
+ .clip b{font-size:13px}.clip span{font-size:11.5px;color:var(--c-fg2);overflow-wrap:anywhere}.clip.missing{opacity:.8;box-shadow:inset 0 0 0 1px var(--c-line2)}.clip button{justify-self:start}
package/mcp/ui/cast.js CHANGED
@@ -48,12 +48,46 @@
48
48
  card.appendChild(grid);
49
49
  card.appendChild(C.el('p', 'fine', 'Every item is CC0 (free for any use, no credit required), already phone-sized. Adding one copies it into the game: it never loads from anywhere else.'));
50
50
  }
51
+ // The characters: the decisions that shape them, then each one made or planned, with its skeleton and clips.
52
+ function characters(card, sc) {
53
+ var d = sc.decisions || {};
54
+ var facts = C.el('ul', 'list decisions');
55
+ [['style.proportions', 'Proportions'], ['style.shape', 'Shape and silhouette'], ['cast.family', 'Library family'], ['rig.skeleton', 'Skeleton'], ['rig.source', 'Rigs from'], ['rig.bones', 'Bones']].forEach(function (k) {
56
+ var v = d[k[0]]; if (!v) return;
57
+ var li = C.el('li', v.state === 'locked' ? 'locked' : '');
58
+ li.appendChild(C.add(C.el('div', 'cb'), C.el('b', '', k[1] + ': ' + v.label), C.el('span', '', v.why || '')));
59
+ li.appendChild(C.pill(v.state, v.state === 'locked' ? 'ok' : ''));
60
+ facts.appendChild(li);
61
+ });
62
+ card.appendChild(facts);
63
+ var chips = C.el('div', 'chips');
64
+ (sc.palette || []).forEach(function (hex) { var s = C.el('span', 'swatch'); s.style.background = hex; s.title = hex; chips.appendChild(s); });
65
+ card.appendChild(C.add(C.el('p', 'fine', 'Palette and silhouette rule: ' + (sc.silhouette || '') + ' '), chips));
66
+ var list = C.el('ul', 'list cast');
67
+ (sc.rows || []).forEach(function (r) {
68
+ var li = C.el('li', r.state === 'made' ? 'done' : 'todo');
69
+ li.appendChild(thumb(r.thumb, r.id));
70
+ li.appendChild(C.add(C.el('div', 'cb'), C.el('b', '', r.id + (r.card ? ' · ' + r.card : '')), C.el('span', '', r.state === 'made' ? r.kind + ' · ' + (r.route === 'generated' ? 'generated (US$' + r.usd + ')' : r.route + (r.source ? ': ' + r.source : '')) + ' · ' + r.family + ' skeleton, ' + r.bones + ' bones · ' + r.tris + ' triangles · ' + r.heightM + ' m' : r.kind + ' · planned, ' + (r.heightM ? r.heightM + ' m' : 'no model yet')), r.verbs && r.verbs.length ? C.el('span', '', 'Clips: ' + r.verbs.join(', ')) : null));
71
+ var side = C.el('div', 'actions');
72
+ if (r.state === 'made') side.appendChild(C.btn('Clips', 'ghost small', function () { C.call('anim_plan', { game: sc.game, asset: r.id }).then(C.take).catch(C.render); }));
73
+ else {
74
+ side.appendChild(C.btn('Find in the library', 'small', function () { C.call('assets_find', { game: sc.game, query: r.id.replace(/-/g, ' '), kind: r.kind }).then(C.take).catch(C.render); }));
75
+ side.appendChild(C.btn('Generate', 'ghost small', function () { C.tell('char:' + r.id, 'The person wants ' + r.id + ' (' + (r.card || r.kind) + ') generated as a rigged character: price it with character_make (a dry run, about US$1.44) and ask before paying.'); busy[r.id] = 'Asked your AI to price it'; C.render(); }));
76
+ }
77
+ if (busy[r.id]) side.appendChild(C.el('span', 'fine', busy[r.id]));
78
+ li.appendChild(side);
79
+ list.appendChild(li);
80
+ });
81
+ card.appendChild(list);
82
+ card.appendChild(C.el('p', 'fine', 'Library characters are free (CC0); a generated one is about US$1.44 on your own fal account, priced and asked for first. Spent so far: US$' + (sc.spend ? sc.spend.used.toFixed(2) : '0.00') + '.'));
83
+ }
51
84
  function render(sc) {
52
85
  var card = C.el('main', 'card');
53
- var title = sc.mode === 'find' ? 'Free models for “' + sc.query + '”' : sc.mode === 'added' ? 'Added ' + (sc.added && sc.added.asset) : 'The cast of ' + sc.game;
54
- C.add(card, C.top('Cast', sc.mode === 'plan' ? C.pill((sc.rows || []).filter(function (r) { return r.state === 'made'; }).length + ' of ' + (sc.rows || []).length + ' made', '') : null), C.el('h1', '', title));
86
+ var title = sc.mode === 'find' ? 'Free models for “' + sc.query + '”' : sc.mode === 'added' ? 'Added ' + (sc.added && sc.added.asset) : sc.mode === 'characters' ? 'The characters of ' + sc.game : 'The cast of ' + sc.game;
87
+ C.add(card, C.top('Cast', sc.mode === 'characters' ? C.pill((sc.rows || []).filter(function (r) { return r.state === 'made'; }).length + ' made', '') : sc.mode === 'plan' ? C.pill((sc.rows || []).filter(function (r) { return r.state === 'made'; }).length + ' of ' + (sc.rows || []).length + ' made', '') : null), C.el('h1', '', title));
55
88
  if (sc.library && sc.library.error) card.appendChild(C.el('p', 'note', 'Starter library: ' + sc.library.error));
56
89
  if (sc.mode === 'plan') plan(card, sc);
90
+ else if (sc.mode === 'characters') characters(card, sc);
57
91
  else if (sc.mode === 'find') find(card, sc);
58
92
  else if (sc.added) card.appendChild(C.el('p', 'sub', sc.added.asset + ' is in games/' + sc.game + (sc.added.after ? ': ' + sc.added.after.tris + ' triangles, ' + sc.added.after.kb + ' KB' : '') + '. Licence: ' + (sc.added.license || 'CC0') + '.'));
59
93
  return card;
package/mcp/ui/lineup.js CHANGED
@@ -37,25 +37,25 @@
37
37
  var a = { game: sc.game, asset: sc.asset };
38
38
  for (var q in (sc.request || {})) a[q] = sc.request[q];
39
39
  for (var k in args) a[k] = args[k];
40
- C.call('asset_make', a).then(function (r) { state.busy = null; C.take(r); }).catch(function () { state.busy = 'That did not reach the studio.'; C.render(); });
40
+ C.call(sc.character ? 'character_make' : 'asset_make', a).then(function (r) { state.busy = null; C.take(r); }).catch(function () { state.busy = 'That did not reach the studio.'; C.render(); });
41
41
  };
42
42
  if (sc.concept) { var i = C.img(sc.concept, 'The concept for ' + sc.asset); if (i) { i.style.maxHeight = '360px'; i.style.objectFit = 'contain'; card.appendChild(C.add(C.el('div', 'preview'), i)); } }
43
43
  if (sc.dryRun) {
44
- card.appendChild(C.el('p', 'sub', (sc.step === 'mesh' ? 'The 3D model' : 'The concept image') + ' costs about US$' + (sc.price ? sc.price.usd : '?') + (sc.total ? '; the whole prop about US$' + sc.total : '') + ', on your own fal account.'));
44
+ card.appendChild(C.el('p', 'sub', (sc.step === 'mesh' ? (sc.character ? 'The rigged character' : 'The 3D model') : 'The concept image') + ' costs about US$' + (sc.price ? sc.price.usd : '?') + (sc.total ? '; the whole ' + (sc.character ? 'character' : 'prop') + ' about US$' + sc.total : '') + ', on your own fal account.'));
45
45
  card.appendChild(C.add(C.el('div', 'actions'), C.btn('Make it (US$' + (sc.price ? sc.price.usd : '?') + ')', '', function () { C.tell('approve:' + sc.asset + sc.step, 'The person approved US$' + (sc.price && sc.price.usd) + ' for the ' + sc.step + ' of ' + sc.asset + ' on the card.'); run({ step: sc.step, approve: true }, 'Making it…'); })));
46
46
  } else if (sc.needs === 'approval' || sc.why) card.appendChild(C.el('p', 'note', sc.why || 'Needs the person\'s yes.'));
47
47
  else if ((sc.step === 'concept' || sc.step === 'look') && sc.concept) {
48
- card.appendChild(C.el('p', 'sub', 'Look at it: the thing, whole, in the game\'s style, on a plain background? Then the 3D model (about US$' + (sc.then ? sc.then.usd : '0.50') + ').'));
49
- card.appendChild(C.add(C.el('div', 'actions'), C.btn('Make the 3D model', '', function () { C.tell('mesh:' + sc.asset, 'The person approved the 3D model of ' + sc.asset + ' (about US$' + (sc.then ? sc.then.usd : '0.50') + ') on the card.'); run({ step: 'mesh', approve: true }, 'Making the model (1 to 3 minutes)…'); })));
48
+ card.appendChild(C.el('p', 'sub', sc.character ? 'Look at it: one character, whole, in an A-pose, in the game\'s style, on a plain background? Then the rigged 3D character (about US$' + (sc.then ? sc.then.usd : '1.40') + '); its clips come from the free library.' : 'Look at it: the thing, whole, in the game\'s style, on a plain background? Then the 3D model (about US$' + (sc.then ? sc.then.usd : '0.50') + ').'));
49
+ card.appendChild(C.add(C.el('div', 'actions'), C.btn(sc.character ? 'Make the rigged character' : 'Make the 3D model', '', function () { C.tell('mesh:' + sc.asset, 'The person approved the ' + (sc.character ? 'rigged character' : '3D model') + ' of ' + sc.asset + ' (about US$' + (sc.then ? sc.then.usd : sc.character ? '1.40' : '0.50') + ') on the card.'); run({ step: 'mesh', approve: true }, sc.character ? 'Making the rigged character (2 to 5 minutes)…' : 'Making the model (1 to 3 minutes)…'); })));
50
50
  } else if (sc.step === 'mesh' && sc.after) {
51
- card.appendChild(C.el('p', 'note ok', sc.asset + ': ' + sc.before.tris + ' → ' + sc.after.tris + ' triangles, ' + sc.after.kb + ' KB, ' + sc.after.heightM + ' m. Recorded with its receipts and licence.'));
52
- card.appendChild(C.add(C.el('div', 'actions'), C.btn('Show the lineup', 'ghost', function () { state.busy = 'Drawing the lineup…'; C.render(); C.call('asset_lineup', { game: sc.game }).then(function (r) { state.busy = null; C.take(r); }); })));
51
+ card.appendChild(C.el('p', 'note ok', sc.asset + ': ' + sc.before.tris + ' → ' + sc.after.tris + ' triangles, ' + sc.after.kb + ' KB, ' + sc.after.heightM + ' m. Recorded with its receipts and licence.' + (sc.character && sc.verbs && sc.verbs.length ? ' Clips (the library\'s, retargeted, free): ' + sc.verbs.join(', ') + '.' : '')));
52
+ card.appendChild(C.add(C.el('div', 'actions'), C.btn('Show the lineup', 'ghost', function () { state.busy = 'Drawing the lineup…'; C.render(); C.call('asset_lineup', { game: sc.game }).then(function (r) { state.busy = null; C.take(r); }); }), sc.character ? C.btn('Show its clips', 'ghost', function () { state.busy = 'Drawing its clips…'; C.render(); C.call('anim_preview', { game: sc.game, asset: sc.asset }).then(function (r) { state.busy = null; C.take(r); }); }) : null));
53
53
  }
54
54
  }
55
55
  function render(sc) {
56
56
  var card = C.el('main', 'card');
57
57
  var flagged = sc.mode === 'lineup' ? sc.flagged : null;
58
- C.add(card, C.top(sc.mode === 'make' ? 'Make a prop' : 'Lineup', C.add(C.el('div', 'actions'), flagged !== null && flagged !== undefined ? C.pill(flagged ? flagged + ' flagged' : 'One look', flagged ? 'warn' : 'ok') : null, C.fullscreenButton())),
58
+ C.add(card, C.top(sc.mode === 'make' ? (sc.character ? 'Make a character' : 'Make a prop') : 'Lineup', C.add(C.el('div', 'actions'), flagged !== null && flagged !== undefined ? C.pill(flagged ? flagged + ' flagged' : 'One look', flagged ? 'warn' : 'ok') : null, C.fullscreenButton())),
59
59
  C.el('h1', '', sc.mode === 'make' ? sc.asset : 'The cast of ' + sc.game + ', at true scale'));
60
60
  if (state.busy) card.appendChild(C.el('p', 'note', state.busy));
61
61
  if (sc.mode === 'make') make(card, sc); else lineup(card, sc);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homie-rocks/studio",
3
- "version": "0.24.5",
3
+ "version": "0.25.0",
4
4
  "description": "A studio for games, music and video on its own Cloudflare: scaffold, multiplayer starters on the netplay contract, a port toolkit that makes existing single-player web games multiplayer, the site Worker with public rooms (Table/Lobby Durable Objects and D1, all on the free Workers plan, no payment method), a site with the hub's sections (Home, Games, Music, Videos, Rooms, Posts with feeds) in the studio's own look, an epic landing page for every game, big songs and videos in the studio's own R2 once it has storage (uploaded, checked by SHA-256, served at the same addresses), deploy, and the homie.rocks directory.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -46,6 +46,10 @@
46
46
  "types": "./assets/assets.ts",
47
47
  "default": "./assets/assets.ts"
48
48
  },
49
+ "./animate": {
50
+ "types": "./assets/animate.ts",
51
+ "default": "./assets/animate.ts"
52
+ },
49
53
  "./worker": "./worker/index.mjs",
50
54
  "./package.json": "./package.json"
51
55
  },
@@ -0,0 +1,163 @@
1
+ # Rights: Hero Rush 3D
2
+
3
+ Every file this game ships, where it came from, its licence and what that allows. Written by `homie-studio assets rights hero-rush-3d` from `assets/manifest.json`; do not edit it by hand.
4
+
5
+ ## What the providers' terms say
6
+
7
+ Read on the dates shown. Terms change: read the live page again before publishing anything commercial.
8
+
9
+ - **KayKit** (https://kaylousberg.itch.io/, read 2026-10-02): CC0 1.0: free for personal and commercial use, no attribution required.
10
+
11
+ ## Files
12
+
13
+ ### barbarian
14
+
15
+ - **What:** character (Players/Barbarian): `public/models/barbarian.glb`
16
+ - **From:** from the Homie starter library: KayKit Adventurers, barbarian (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Adventures-1.0); library
17
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
18
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
19
+ - **Notes:** From the Homie starter library (kaykit-adventurers); the pack's own licence text: licenses/kaykit-adventurers.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
20
+
21
+ ### barrel
22
+
23
+ - **What:** prop (Places/Barrel): `public/models/barrel.glb`
24
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, barrel (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
25
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
26
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
27
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
28
+
29
+ ### chest
30
+
31
+ - **What:** prop (Places/Treasure Chest): `public/models/chest.glb`
32
+ - **From:** from the Homie starter library: KayKit Dungeon Remastered, chest-gold (https://github.com/KayKit-Game-Assets/KayKit-Dungeon-Remastered-1.0); library
33
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
34
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
35
+ - **Notes:** From the Homie starter library (kaykit-dungeon); the pack's own licence text: licenses/kaykit-dungeon.txt. `game new` fetches the file; the repository holds no models.
36
+
37
+ ### coin
38
+
39
+ - **What:** prop (Items/Coin): `public/models/coin.glb`
40
+ - **From:** from the Homie starter library: KayKit Dungeon Remastered, coin (https://github.com/KayKit-Game-Assets/KayKit-Dungeon-Remastered-1.0); library
41
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
42
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
43
+ - **Notes:** From the Homie starter library (kaykit-dungeon); the pack's own licence text: licenses/kaykit-dungeon.txt. `game new` fetches the file; the repository holds no models.
44
+
45
+ ### crate
46
+
47
+ - **What:** prop (Places/Crate): `public/models/crate.glb`
48
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, crate-a-big (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
49
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
50
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
51
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
52
+
53
+ ### grove
54
+
55
+ - **What:** prop (Places/Grove): `public/models/grove.glb`
56
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, trees-a-medium (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
57
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
58
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
59
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
60
+
61
+ ### knight
62
+
63
+ - **What:** character (Players/Knight): `public/models/knight.glb`
64
+ - **From:** from the Homie starter library: KayKit Adventurers, knight (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Adventures-1.0); library
65
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
66
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
67
+ - **Notes:** From the Homie starter library (kaykit-adventurers); the pack's own licence text: licenses/kaykit-adventurers.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
68
+
69
+ ### mage
70
+
71
+ - **What:** character (Players/Mage): `public/models/mage.glb`
72
+ - **From:** from the Homie starter library: KayKit Adventurers, mage (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Adventures-1.0); library
73
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
74
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
75
+ - **Notes:** From the Homie starter library (kaykit-adventurers); the pack's own licence text: licenses/kaykit-adventurers.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
76
+
77
+ ### pine
78
+
79
+ - **What:** prop (Places/Pine): `public/models/pine.glb`
80
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, tree-single-a (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
81
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
82
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
83
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
84
+
85
+ ### pine-round
86
+
87
+ - **What:** prop (Places/Round Pine): `public/models/pine-round.glb`
88
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, tree-single-b (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
89
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
90
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
91
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
92
+
93
+ ### rock
94
+
95
+ - **What:** prop (Places/Rock): `public/models/rock.glb`
96
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, rock-single-e (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
97
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
98
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
99
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
100
+
101
+ ### rocks
102
+
103
+ - **What:** prop (Places/Rocks): `public/models/rocks.glb`
104
+ - **From:** from the Homie starter library: KayKit Medieval Hexagon, rock-single-c (https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0); library
105
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
106
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
107
+ - **Notes:** From the Homie starter library (kaykit-medieval-hexagon); the pack's own licence text: licenses/kaykit-medieval-hexagon.txt. `game new` fetches the file; the repository holds no models.
108
+
109
+ ### rogue
110
+
111
+ - **What:** character (Players/Rogue): `public/models/rogue.glb`
112
+ - **From:** from the Homie starter library: KayKit Adventurers, rogue (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Adventures-1.0); library
113
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
114
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
115
+ - **Notes:** From the Homie starter library (kaykit-adventurers); the pack's own licence text: licenses/kaykit-adventurers.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
116
+
117
+ ### rogue-hooded
118
+
119
+ - **What:** character (Players/Hooded Rogue): `public/models/rogue-hooded.glb`
120
+ - **From:** from the Homie starter library: KayKit Adventurers, rogue-hooded (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Adventures-1.0); library
121
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
122
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
123
+ - **Notes:** From the Homie starter library (kaykit-adventurers); the pack's own licence text: licenses/kaykit-adventurers.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
124
+
125
+ ### skeleton-mage
126
+
127
+ - **What:** creature (Creatures/Skeleton Mage): `public/models/skeleton-mage.glb`
128
+ - **From:** from the Homie starter library: KayKit Skeletons, skeleton-mage (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Skeletons-1.0); library
129
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
130
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
131
+ - **Notes:** From the Homie starter library (kaykit-skeletons); the pack's own licence text: licenses/kaykit-skeletons.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
132
+
133
+ ### skeleton-minion
134
+
135
+ - **What:** creature (Creatures/Skeleton Minion): `public/models/skeleton-minion.glb`
136
+ - **From:** from the Homie starter library: KayKit Skeletons, skeleton-minion (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Skeletons-1.0); library
137
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
138
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
139
+ - **Notes:** From the Homie starter library (kaykit-skeletons); the pack's own licence text: licenses/kaykit-skeletons.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
140
+
141
+ ### skeleton-rogue
142
+
143
+ - **What:** creature (Creatures/Skeleton Rogue): `public/models/skeleton-rogue.glb`
144
+ - **From:** from the Homie starter library: KayKit Skeletons, skeleton-rogue (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Skeletons-1.0); library
145
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
146
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
147
+ - **Notes:** From the Homie starter library (kaykit-skeletons); the pack's own licence text: licenses/kaykit-skeletons.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
148
+
149
+ ### skeleton-warrior
150
+
151
+ - **What:** creature (Creatures/Skeleton Warrior): `public/models/skeleton-warrior.glb`
152
+ - **From:** from the Homie starter library: KayKit Skeletons, skeleton-warrior (https://github.com/KayKit-Game-Assets/KayKit-Character-Pack-Skeletons-1.0); library
153
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
154
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
155
+ - **Notes:** From the Homie starter library (kaykit-skeletons); the pack's own licence text: licenses/kaykit-skeletons.txt. `game new` fetches the file, makes the character phone-sized and bakes its clips; the repository holds no models.
156
+
157
+ ### torch
158
+
159
+ - **What:** prop (Places/Torch): `public/models/torch.glb`
160
+ - **From:** from the Homie starter library: KayKit Dungeon Remastered, torch-lit (https://github.com/KayKit-Game-Assets/KayKit-Dungeon-Remastered-1.0); library
161
+ - **Licence:** CC0 1.0 (public domain) (https://creativecommons.org/publicdomain/zero/1.0/); owner: KayKit
162
+ - **A remix:** a remix gets this file (fetched from this studio's site, checked by SHA-256)
163
+ - **Notes:** From the Homie starter library (kaykit-dungeon); the pack's own licence text: licenses/kaykit-dungeon.txt. `game new` fetches the file; the repository holds no models.