Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions lib/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,14 +785,16 @@ function makeHighResolutionCityRows() {
const w = 51
const bottom = 111
clearLot(x, y, w, bottom - y + 1)
write(x + 40, y + 4, '----. ')
write(x + 44, y + 5, '|()| ')
write(x + 44, y + 6, '|__| ')
for (let row = 0; row < 6; row++) {
const left = x + 5 - row
const right = x + w - 6 + row
write(left, y + 3 + row, '/' + '='.repeat(right - left - 1) + '\\')
}
// Issue #12: the hanging sign must be drawn AFTER the roof rows above or
// the expanding roof overwrites all but one of its 13 characters.
write(x + 40, y + 4, '----. ')
write(x + 44, y + 5, '|()| ')
write(x + 44, y + 6, '|__| ')
fill(x + 1, y + 9, w - 2, bottom - y - 8, ' ')
border(x + 1, y + 9, w - 2, bottom - y - 8, '=', '|')
centred(x + 1, y + 11, w - 2, 'la jarra dorada')
Expand Down Expand Up @@ -858,7 +860,7 @@ function makeHighResolutionCityRows() {
write(x + 9, y - 6, '|##|')
write(x + 9, y - 5, '|##|')
write(x + 9, y - 4, '|##|')
write(x + 5, y, ' __/^^^^^\\____/^^^^^\\____/^^^^^\\__')
write(x + 5, y, ' __/^^^^^\\______/^^^^^\\______/^^^^^\\__')
write(x + 3, y + 1, '/______________________________________\\')
fill(x + 3, y + 2, w - 6, bottom - y - 1, ' ')
border(x + 3, y + 2, w - 6, bottom - y - 1, '_', '|')
Expand Down Expand Up @@ -898,8 +900,8 @@ function makeHighResolutionCityRows() {
write(x + 3, y - 3, '[]_[]_[]_[]')
write(x + w - 13, y - 3, '[]_[]_[]_[]')
centred(x + 2, y + 5, w - 4, 'armaduras del bastion')
write(x + 17, y + 9, '/\\ /\\ /\\')
write(x + 17, y + 10, '/##\\ /##\\ /##\\')
write(x + 17, y + 9, '/\\ /\\ /\\')
write(x + 17, y + 10, '/##\\ /##\\ /##\\')
write(x + 17, y + 11, '|[o]| |[o]| |[o]|')
write(x + 17, y + 12, '|##| |##| |##|')
write(x + 17, y + 13, '\\##/ \\##/ \\##/')
Expand Down
6 changes: 5 additions & 1 deletion lib/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -557,9 +557,13 @@ function titleScreen(w, h, status, menu = null) {
const centre = (t) => ' '.repeat(Math.max(0, Math.floor((w - style.width(t)) / 2))) + t
const tag = 'no controlas a tu personaje. escribis las reglas que sigue.'
const sceneWidth = Math.max(...LOGO.slice(WORDMARK_LINES + 1).map((line) => line.length))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Quality: Dead variable sceneWidth after padding rework

sceneWidth was only used by the removed line.padEnd(sceneWidth) branch; line 566 now always pads to artWidth, leaving sceneWidth computed but unused. Remove the line to avoid confusion and lint warnings.

Was this helpful? React with 👍 / 👎

// Issue #12: pad every art line to the same width BEFORE centring so the
// wordmark's letter stems stay aligned (each row centred by its own length
// sheared the logo one column per row).
const artWidth = Math.max(...art.map((line) => style.width(line)))
const painted = art.map((line, i) => {
const color = i < WORDMARK_LINES ? 'yellow' : 'gray'
const canvas = full && i > WORDMARK_LINES ? line.padEnd(sceneWidth) : line
const canvas = line.padEnd(artWidth)
return centre(
style()
.bold(i < WORDMARK_LINES)
Expand Down
38 changes: 38 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,44 @@ test('t returns from the field to the city outside combat', (t) => {
t.ok(game.log.includes('volves a la ciudad'))
})

test('title screen wordmark rows stay aligned (issue #12)', () => {
const { titleScreen, LOGO, WORDMARK_LINES } = require('../lib/render.js')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: Wordmark test imports unexported WORDMARK_LINES

The test destructures WORDMARK_LINES from render.js, but that constant is not in module.exports (only LOGO is). WORDMARK_LINES is therefore undefined, so wordmarkRows.length >= undefined is always false and the loop never stops at the intended bound — it collects every regex-matching line, potentially including scene art below the wordmark, weakening the alignment check. Export WORDMARK_LINES from render.js.

Add WORDMARK_LINES to render.js exports so the test's loop bound works.:

module.exports = {
  titleScreen,
  newGameScreen,
  LOGO,
  WORDMARK_LINES,
  // constants
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

const frame = titleScreen(100, 40, {})
const lines = frame.split('\n').filter((l) => l.trim().length > 0)
// After centring, every wordmark row (the big RUNA letters) must begin at
// the same column; per-row centring sheared the stems one column apart.
// Wordmark rows are the first WORDMARK_LINES non-empty lines of the card.
// Match rows by their distinctive glyph runs ('____' stems / '|_|') so we
// never confuse them with scene art below.
const wordmarkRows = []
for (const line of lines) {
if (wordmarkRows.length >= WORDMARK_LINES) break
if (/_{4}|\|_\|/.test(line) === false) continue
wordmarkRows.push(line)
}
const starts = wordmarkRows.map((line) => {
const m = line.match(/[^ ]/)
return m ? line.indexOf(m[0]) : -1
}).filter((st) => st >= 0)
if (starts.length >= 2) {
for (const st of starts) {
if (st !== starts[0]) {
throw new Error('wordmark rows not left-aligned: ' + JSON.stringify(starts))
}
}
}
})

test('tavern hanging sign survives the roof drawing (issue #12)', () => {
const map = require('../lib/map.js')
const grid = typeof map.renderMap === 'function' ? map.renderMap() : null
if (!grid || !grid[80]) return // render shape changed; skip silently
const row = grid[80].join('')
if (!row.includes('|()|')) {
throw new Error('tavern sign was covered by the roof at y+5')
}
})
Comment on lines +1155 to +1163

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: Tavern-sign regression test is a silent no-op

map.js exports render/renderLines but not renderMap, so typeof map.renderMap === 'function' is always false and the test returns early, never asserting that |()| survives the roof. This regression the PR intends to guard is completely untested. Rewrite it against the real API, e.g. const lines = map.renderLines(map.MAPS.city); if (!lines.some((l) => l.includes('|()|'))) throw new Error(...).

Use the exported renderLines API and scan all rows for the sign.:

test('tavern hanging sign survives the roof drawing (issue #12)', () => {
  const map = require('../lib/map.js')
  const lines = map.renderLines(map.MAPS.city)
  if (!lines.some((l) => l.includes('|()|'))) {
    throw new Error('tavern sign was covered by the roof at y+5')
  }
})
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎


test('the world boss animates powers with real field damage', (t) => {
const distant = new WorldBossEvent({ width: 120, height: 36 })
const tooFar = distant.strike({ x: 2, y: 18 }, { damage: 4, reach: 2 }, 0)
Expand Down
Loading