From d5b1828df43beb6defabc351f21da27832a8182f Mon Sep 17 00:00:00 2001 From: MeatSlicer Developer Date: Thu, 30 Jul 2026 16:17:20 +1000 Subject: [PATCH] Fix help manual layout: shrink tabs to fit panel, space implant rows - 10+ tabs at fixed 108px overflowed the 920px panel; tabs now shrink to fit - Implant rows grew a rarity/cap sub-line but kept 20px spacing; now 26px with 10 rows per column (20 items/page, 5 pages for 82 items) - Bump asset cache to v=39; smoke test asserts tabs stay on-screen --- index.html | 42 +++++++++++++++++++++--------------------- js/help.js | 16 +++++++++------- js/sfxbank.js | 2 +- js/sprites.js | 2 +- test/smoke.js | 9 +++++++-- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/index.html b/index.html index a4dc2d2..e0e86f3 100644 --- a/index.html +++ b/index.html @@ -6,31 +6,31 @@ MEATSLICER - +
- - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/js/help.js b/js/help.js index 939ba9b..cc4326f 100644 --- a/js/help.js +++ b/js/help.js @@ -6,7 +6,7 @@ const HELP_BUTTON = { x: W - 104, y: 24, w: 80, h: 26 }; // Implant pages are generated from the live ITEMS roster so the manual never // drifts from the game data; the count and page count are dynamic. -const HELP_ITEM_PAGE_SIZE = 23; +const HELP_ITEM_PAGE_SIZE = 20; const HELP_ITEM_PAGE_COUNT = Math.ceil(Object.keys(ITEMS).length / HELP_ITEM_PAGE_SIZE); const HELP_PAGES = [ { title: 'CONTROLS' }, @@ -24,7 +24,9 @@ function hfont(px, bold) { return (bold ? 'bold ' : '') + Math.round(px * HELP_S function helpPanelX() { return (W - HELP_PANEL.w) / 2; } function helpTabRect(i) { - const tw = 108, gap = 6; + // tabs shrink to fit the panel width so a growing page count never overflows + const gap = 6; + const tw = Math.min(108, Math.floor((HELP_PANEL.w - 40 - (HELP_PAGES.length - 1) * gap) / HELP_PAGES.length)); const total = HELP_PAGES.length * tw + (HELP_PAGES.length - 1) * gap; return { x: W / 2 - total / 2 + i * (tw + gap), y: HELP_PANEL.y + 96, w: tw, h: 32 }; } @@ -199,16 +201,16 @@ function drawHelpItemList(ctx, px, py, page) { const pageEntries = entries.slice(page * HELP_ITEM_PAGE_SIZE, page * HELP_ITEM_PAGE_SIZE + HELP_ITEM_PAGE_SIZE); const colW = (HELP_PANEL.w - 80) / 2; for (let i = 0; i < pageEntries.length; i++) { - const col = Math.floor(i / 12), r = i % 12; - const lx = x + col * colW, ly = ty + r * 20; + const col = Math.floor(i / 10), r = i % 10; + const lx = x + col * colW, ly = ty + r * 26; const [iid, item] = pageEntries[i]; const rar = ITEM_RARITY[item.rarity]; ctx.fillStyle = rar.color; ctx.font = hfont(8, true); ctx.fillText(item.name.toUpperCase(), lx, ly); ctx.fillStyle = '#5f4d4d'; ctx.font = hfont(7, true); - ctx.fillText(item.rarity.toUpperCase().slice(0, 3) + '·' + item.cap, lx, ly + 12); + ctx.fillText(item.rarity.toUpperCase().slice(0, 3) + '·' + item.cap, lx, ly + 13); ctx.fillStyle = '#a08d84'; ctx.font = hfont(8, false); - ctx.fillText(fit(item.desc.toUpperCase(), 34), lx + 52, ly + 12); + ctx.fillText(fit(item.desc.toUpperCase(), 30), lx + 56, ly + 13); } } @@ -310,7 +312,7 @@ function drawPauseHelp(ctx) { color: active ? '#f1e4d5' : (hover ? '#cdbdb2' : '#7d6a68'), accent: active ? '#4a9cad' : '#3c2f38', fill: active ? 'rgba(24,15,22,0.95)' : 'rgba(12,7,11,0.85)', - font: hfont(8, true), + font: hfont(r.w < 100 ? 7 : 8, true), }); } diff --git a/js/sfxbank.js b/js/sfxbank.js index 472d718..180280b 100644 --- a/js/sfxbank.js +++ b/js/sfxbank.js @@ -115,7 +115,7 @@ const SfxBank = { if (this.buffers.has(name) || this.pending.has(name) || this.failed.has(name)) return; const file = this.FILES[name]; if (!file || !this.ctx || typeof fetch !== 'function') return; - const job = fetch('/assets/sfx/' + encodeURIComponent(file) + '?v=38') + const job = fetch('/assets/sfx/' + encodeURIComponent(file) + '?v=39') .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.arrayBuffer(); }) .then(bytes => this.ctx.decodeAudioData(bytes)) .then(buffer => this.buffers.set(name, this.trim(buffer))) diff --git a/js/sprites.js b/js/sprites.js index 78c71f2..9933395 100644 --- a/js/sprites.js +++ b/js/sprites.js @@ -81,7 +81,7 @@ const Sprites = { const img = new Image(); img.onload = () => { this.imgs[name] = img; if (--pending === 0) G.imagesLoaded = true; }; img.onerror = () => { if (--pending === 0) G.imagesLoaded = true; }; - img.src = 'assets/' + name + '.png?v=38'; + img.src = 'assets/' + name + '.png?v=39'; } }, diff --git a/test/smoke.js b/test/smoke.js index e3cd6b6..dbf4dc9 100644 --- a/test/smoke.js +++ b/test/smoke.js @@ -1014,8 +1014,13 @@ console.log('== item stickiness ramps with owned count =='); console.log('== help manual grows with the implant roster =='); { - check('10 help pages (4 implant pages for 82 items)', ctx.HELP_PAGES.length === 10); - check('10 help renderers', ctx.HELP_RENDERERS.length === 10); + check('11 help pages (5 implant pages for 82 items)', ctx.HELP_PAGES.length === 11); + check('11 help renderers', ctx.HELP_RENDERERS.length === 11); + check('help tabs never overflow the panel', (() => { + const last = ctx.helpTabRect(ctx.HELP_PAGES.length - 1); + const first = ctx.helpTabRect(0); + return first.x >= 0 && last.x + last.w <= ctx.W; + })()); ctx.G.player = ctx.G.player || {}; const fctx = fakeCtx(); let renderOK = true;