Skip to content

Commit 2416c08

Browse files
TMHSDigitalclaude
andcommitted
catalog: add decision support for the three largest clusters (batch K)
The ledger said eight clusters were uncovered. Re-measuring first showed that number was stale: the tools table from batch E already covers seven of the original ten. But measuring by shared subcategory turned up much larger clusters that no pass had looked at, including one this session created. Three tables added, chosen by size and by how little the licence column helps you choose: 2d/README.md Choosing a pixel tileset (10 sources) 3d/README.md Choosing a PBR texture source (8 sources) fonts/README.md Choosing a pixel font (9 sources) The 2D tileset table is the one I owe. Batch H added six pixel tile packs to a category that already had four, and left a newcomer facing ten CC0 sources that look interchangeable from outside. The table sorts them by the two things that actually decide it: grid size and projection. Three grids are in play (8x8, 12x12, 16x16) and mixing two projections in one map reads as a bug, which is exactly the mistake the entries warn about individually and nothing surfaced at the category level. The 3D texture table sorts by licence first, because that is the real split and it is invisible on the sites themselves: six of the eight are genuine CC0, while sharetextures and freepbr are custom grants that permit shipping a game but restrict passing the textures on. Anyone assembling an asset pack others redistribute needs that distinction before they need resolution. The fonts table sorts by what kind of retro you mean and, more usefully, by CJK coverage, which three of the nine have and the licence column cannot show. V11 reworked, because writing the 3D table tripped it. That table leads with the entry link, which made it structurally identical to a catalog listing row, and seven false positives followed. V11 now finds the listing by its "| ID |" header instead of by row shape, so a comparison table can lead with a link like any other. To keep the check from silently measuring nothing if that header ever changes, a category README with entries and no such table is now itself an error. Verified by mutating the real catalog: drift is still caught in the 3d and 2d listings with comparison tables sitting above them, and removing a header is reported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
1 parent e264c10 commit 2416c08

5 files changed

Lines changed: 142 additions & 11 deletions

File tree

‎catalog/2d/README.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,34 @@ Do not mix tile grids or camera projections without scaling/reprojection. Typica
44

55
Optional frontmatter: `grid_dimensions`, `camera_perspective`, `hardware_tags`.
66

7+
## Choosing a pixel tileset
8+
9+
Ten CC0 pixel tilesets, and from the outside they look like the same thing ten times.
10+
Grid size and projection are what actually decide it, because **mixing two projections
11+
in one map reads as a bug** and mixing two grids needs integer scaling. Pick the row
12+
that matches the game you are building, not the one with the most tiles.
13+
14+
| If you are building | Take | Grid | View | Why this one |
15+
| --- | --- | ---: | --- | --- |
16+
| A whole RPG, one art style | [kenney-roguelike-rpg-pack](kenney-roguelike-rpg-pack.md) | 16x16 | 3/4 | 1700 tiles: overworld, town, interiors, items and matching UI. Gets a prototype furthest without a second source |
17+
| A small town or overworld | [kenney-tiny-town](kenney-tiny-town.md) | 16x16 | 3/4 | 130 tiles, exteriors only. Pairs exactly with Tiny Dungeon |
18+
| Dungeon interiors | [kenney-tiny-dungeon](kenney-tiny-dungeon.md) | 16x16 | 3/4 | The interior half of the Tiny pair, same grid and style |
19+
| A grittier dungeon | [ox72-dungeontileset-ii](ox72-dungeontileset-ii.md) | 16x16 | 3/4 | Darker palette with characters included; [vol. I](ox72-dungeon-tileset.md) is the older sibling |
20+
| A complete game in one download | [ninja-adventure](ninja-adventure.md) | 16x16 | 3/4 | Tiles **plus** 4-directional characters, UI, VFX, 100+ SFX and 37 music tracks |
21+
| An RPG without the Kenney look | [armm1998-zelda-like](armm1998-zelda-like.md) | 16x16 | 3/4 | Overworld, cave and indoor sets with a 4-directional sword character, single author |
22+
| A true overhead roguelike | [kenney-micro-roguelike](kenney-micro-roguelike.md) | **8x8** | **ortho** | Genuinely top-down, not 3/4. Half the grid of everything else here |
23+
| A turn-based strategy map | [kenney-tiny-battle](kenney-tiny-battle.md) | 16x16 | **ortho** | Roads, rivers, bridges and faction unit markers. Nothing else here covers wargames |
24+
| Enormous variety, one colour | [urizen-onebit](urizen-onebit.md) | **12x12** | 3/4 | 5500+ one-bit tiles across many genres. A third grid size, so commit early |
25+
| A monochrome prototype | [kenney-1-bit-pack](kenney-1-bit-pack.md) | 16x16 | either | 1078 1-bit tiles. Kenney ships both an overworld and a platformer sample, so it is the one set here that works in two projections |
26+
27+
Three grids are in play (8x8, 12x12, 16x16) and they do not mix without scaling.
28+
Two of these are orthographic overhead and the rest are 3/4; the difference is whether
29+
walls show a front face. See `camera_perspective` on each entry, or filter by View on
30+
the site.
31+
32+
**Characters:** only Ninja Adventure and ArMM1998 ship characters that turn.
33+
[kenney-roguelike-characters](kenney-roguelike-characters.md) is front-facing only.
34+
735
## Choosing an icon set
836

937
Eight icon sources are listed and seven of them are permissive UI sets that look

‎catalog/3d/README.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
# 3D — models, textures, environments
22

3+
## Choosing a PBR texture source
4+
5+
Seven texture libraries are listed and all seven market themselves as free PBR.
6+
They are not equally free, and that is the first thing to sort by.
7+
8+
| If you need | Take | Licence |
9+
| --- | --- | --- |
10+
| A default first stop | [ambientcg](ambientcg.md) — 1500+ seamless materials, no strings | **CC0** |
11+
| The other safe default | [poly-haven](../environment/poly-haven.md) — also HDRIs and models | **CC0** |
12+
| Photoscanned surfaces ambientCG lacks | [cgbookcase](cgbookcase.md) — 566 sets, 4K/8K, plus decals | **CC0** |
13+
| Parameters you can tweak | [texturecan](texturecan.md) — ships **SBSAR sources**, not just fixed maps | **CC0** |
14+
| Extra seamless coverage | [threedtextures-me](threedtextures-me.md) — aimed at Blender, Unreal, Unity and Godot | **CC0** |
15+
| Unique photo detail | [texture-ninja](texture-ninja.md) — you do the tiling cleanup; not seamless out of the box | **CC0** |
16+
| To read the terms first | [sharetextures](sharetextures.md) — a "Custom CC0" that **bans redistribution** on other sites, in plugins, or in collections | custom |
17+
| To read the terms first | [freepbr](freepbr.md) — free for games, but the About page is the grant, not the CC0 badge you might assume | custom |
18+
19+
The split that matters: the first six are real CC0 and you can redistribute the maps
20+
inside an asset pack. The last two are custom grants that permit shipping a game but
21+
restrict passing the textures on. If you are assembling something others will
22+
redistribute, stay in the CC0 block.
23+
24+
Two more caveats recorded on the entries themselves: texturecan's site footer still
25+
says "All rights reserved" while its terms page is the actual grant, and texture-ninja
26+
keeps its licence string inside a JS bundle rather than in static HTML.
27+
328
| ID | Name | License | Commercial | Status |
429
| --- | --- | --- | --- | --- |
530
| [kenney](kenney.md) | Kenney | CC0 | yes | active |

‎catalog/fonts/README.md‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
# Fonts
22

3-
Prefer **SIL OFL** for embedding in commercial games. See [docs/licenses.md](../../docs/licenses.md).
3+
Prefer **SIL OFL** for embedding in commercial games. See [docs/licenses.md](../../docs/licenses.md)
4+
and [docs/fonts.md](../../docs/fonts.md) for what you still owe when `attribution_required` is false.
5+
6+
## Choosing a pixel font
7+
8+
Nine pixel faces, and the difference is what kind of retro you mean, plus whether you
9+
need CJK. All nine are safe to embed; only the last is CC0 rather than OFL.
10+
11+
| You want | Take | Note |
12+
| --- | --- | --- |
13+
| A terminal or low-res HUD | [departure-mono](departure-mono.md) | Monospaced, the catalog's default pixel face. Site is MIT, the **font** is OFL |
14+
| A CRT or hacking UI | [vt323](vt323.md) | Soft-pixel terminal look, gentler than Press Start |
15+
| Hard 8-bit arcade | [press-start-2p](press-start-2p.md) | Title and score type. Reserved Font Name, so rename if you modify |
16+
| Chunky retro labels | [silkscreen](silkscreen.md) | The arcade weight without Press Start's blocky letterforms |
17+
| Readable pixel UI | [pixelify-sans](pixelify-sans.md) | Soft modern pixel sans; least crunchy of the set |
18+
| **Japanese** | [dotgothic16](dotgothic16.md) | Fontworks, on a 16px grid, covers what the Latin faces cannot |
19+
| **Pan-CJK, several sizes** | [ark-pixel-font](ark-pixel-font.md) | 10/12/16px, mono and proportional, language-specific glyphs. OFL on the font, MIT covers build tools only |
20+
| **CJK at 8x8** | [quanpixel](quanpixel.md) | The smallest CJK option. Download `QuanPixel.zip`; the itch slug still says galmuri-extended |
21+
| No licence file at all | [ggbotnet-fonts-cc0](ggbotnet-fonts-cc0.md) | 45 faces, **CC0**, so nothing to ship alongside. The same account's OFL collection is a different thing |
22+
23+
Match the font's design grid to your tile grid where you can: DotGothic16 is drawn for
24+
16px, QuanPixel for 8px. A 16px face in an 8px UI needs scaling and will blur.
25+
26+
427

528
| ID | Name | License | Commercial | Status |
629
| --- | --- | --- | --- | --- |

‎site/checks.mjs‎

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,29 @@ export function checkTaxonomyValues(rel, meta) {
259259
export function checkCategoryReadmeRows(categoryName, readmeText, entries) {
260260
const errors = [];
261261
const lines = readmeText.split(/\r?\n/);
262+
263+
// Only the catalog listing table is checked. A category README may also carry
264+
// comparison tables that link entries, and those have no license column to
265+
// contradict. The listing is found by its header rather than by row shape,
266+
// because a comparison table can legitimately lead with the entry link too.
267+
const start = lines.findIndex((l) => /^\|\s*ID\s*\|/i.test(l.trim()));
268+
if (start === -1) {
269+
if (entries.length) {
270+
errors.push(
271+
`catalog/${categoryName}/README.md has no catalog table (expected a header row starting "| ID |")`
272+
);
273+
}
274+
return errors;
275+
}
276+
const table = [];
277+
for (let i = start + 1; i < lines.length; i += 1) {
278+
if (!lines[i].trim().startsWith("|")) break;
279+
table.push(lines[i]);
280+
}
281+
262282
for (const entry of entries) {
263283
const stem = entry.rel.split("/").pop().replace(/\.md$/, "");
264-
// Only the catalog table is checked. A category README may also carry
265-
// comparison tables that link entries from a prose cell; those are not
266-
// listings and have no license column to contradict. A catalog row is the
267-
// one whose FIRST cell is the entry link.
268-
const row = lines.find((l) => {
269-
if (!l.trim().startsWith("|") || !l.includes(`(${stem}.md)`)) return false;
270-
const first = l.split("|").map((c) => c.trim()).filter(Boolean)[0] || "";
271-
return first.includes(`(${stem}.md)`);
272-
});
284+
const row = table.find((l) => l.includes(`(${stem}.md)`));
273285
if (!row) continue; // validate.mjs already reports an entry missing from the README
274286
const cells = row
275287
.split("|")

‎site/checks.test.mjs‎

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,43 @@ const readme = [
302302
"| [kenney](kenney.md) | Kenney | CC0 | active |",
303303
"| [lpc](lpc.md) | LPC | varies (SA) | active |",
304304
].join("\n");
305+
rejects(
306+
"V11 reports a category README with entries but no catalog table",
307+
checkCategoryReadmeRows("tools", "# Tools\n\nNo table here.\n", [
308+
{ rel: "catalog/tools/a.md", meta: { license: "MIT" } },
309+
]),
310+
"has no catalog table"
311+
);
312+
accepts(
313+
"V11 ignores a comparison table that leads with the entry link",
314+
checkCategoryReadmeRows(
315+
"3d",
316+
[
317+
"| If you need | Take | Licence |",
318+
"| A default | [ambientcg](ambientcg.md) - seamless | **CC0** |",
319+
"",
320+
"| ID | Name | License | Commercial | Status |",
321+
"| [ambientcg](ambientcg.md) | ambientCG | CC0 | yes | active |",
322+
].join("\n"),
323+
[{ rel: "catalog/3d/ambientcg.md", meta: { license: "CC0" } }]
324+
)
325+
);
326+
rejects(
327+
"V11 still catches drift in the listing when a link-first comparison table exists",
328+
checkCategoryReadmeRows(
329+
"3d",
330+
[
331+
"| If you need | Take | Licence |",
332+
"| A default | [ambientcg](ambientcg.md) - seamless | **CC0** |",
333+
"",
334+
"| ID | Name | License | Commercial | Status |",
335+
"| [ambientcg](ambientcg.md) | ambientCG | MIT | yes | active |",
336+
].join("\n"),
337+
[{ rel: "catalog/3d/ambientcg.md", meta: { license: "CC0" } }]
338+
),
339+
'does not carry its license "CC0"'
340+
);
341+
305342
rejects(
306343
"V11 rejects a README row whose license contradicts the frontmatter",
307344
checkCategoryReadmeRows("tools", readme, [
@@ -325,7 +362,11 @@ accepts(
325362
"V11 tolerates a trailing footnote marker",
326363
checkCategoryReadmeRows(
327364
"tools",
328-
["| [a](a.md) | A | CC0* | active |", "| [b](b.md) | B | CC-BY? | active |"].join("\n"),
365+
[
366+
"| ID | Name | License | Status |",
367+
"| [a](a.md) | A | CC0* | active |",
368+
"| [b](b.md) | B | CC-BY? | active |",
369+
].join("\n"),
329370
[
330371
{ rel: "catalog/tools/a.md", meta: { license: "CC0" } },
331372
{ rel: "catalog/tools/b.md", meta: { license: "CC-BY" } },
@@ -352,6 +393,8 @@ rejects(
352393
[
353394
"| If you want | Take | Over | Because |",
354395
"| A retro SFX fast | [jsfxr](jsfxr.md) | sfxr | Browser, no install |",
396+
"",
397+
"| ID | Name | License | Status |",
355398
"| [jsfxr](jsfxr.md) | jsfxr | public-domain | active |",
356399
].join("\n"),
357400
[{ rel: "catalog/tools/jsfxr.md", meta: { license: "Unlicense" } }]

0 commit comments

Comments
 (0)