Skip to content

fix(map): transparent spaces in art overlays and register missing tiles - #17

Open
s6pa1rta3n-lab wants to merge 6 commits into
Bitcoindefi:mainfrom
s6pa1rta3n-lab:fix/issue-6-solid-spaces
Open

fix(map): transparent spaces in art overlays and register missing tiles#17
s6pa1rta3n-lab wants to merge 6 commits into
Bitcoindefi:mainfrom
s6pa1rta3n-lab:fix/issue-6-solid-spaces

Conversation

@s6pa1rta3n-lab

@s6pa1rta3n-lab s6pa1rta3n-lab commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #6

This PR resolves the invisible walls issue in the plaza and across maps:

  1. Updates write() in makeHighResolutionCityRows() (lib/map.js) to ignore spaces (if (ch === ' ') continue) when rendering art overlays/strings so that underlying walkable cobblestones/roads are not overwritten with solid space characters.
  2. Adds missing characters (' ', '=', '', "'"- representing 24.9% of glyphs in maps) to theTILESdictionary so they are explicitly defined rather than defaulting toNOWHERE`.
  3. Adds automated tests in test/index.js to assert that all map characters are defined in TILES and that the plaza fountain perimeter is clear of invisible solid space tiles.

Testing

  • npm test passed.
  • node test/map.smoke.js passed.
  • npm run lint passed with 0 errors.

Payout Routing

  • EVM (Base/Arbitrum/Polygon/ETH): 0xF46C9F6d70C50BF81ef3588AB523a90a594a2F89
  • Stellar: GCL6OXAMLD75BMTINA6EMRUDWK5THQUSHMYNLSNBCJAPZJHNYJTUNIBC

Comment thread lib/map.js
Comment thread test/index.js Outdated
@leocagli

Copy link
Copy Markdown
Collaborator

This one no longer merges into main.

main moved a lot since it was opened: the save slot system, the coliseum map, the
world boss, and several render fixes all landed. The branch conflicts, so I cannot
test what the merged result would do.

If you rebase it on today's main I will re-run it and report the numbers here. The
current baseline is 65 tests and 515 assertions in green.

One thing worth checking while rebasing: another contributor opened a pull request
for the same issue, so it is worth a look before spending time on the conflict, in
case the work is already covered.

@s6pa1rta3n-lab
s6pa1rta3n-lab force-pushed the fix/issue-6-solid-spaces branch from 0bbaba6 to 415aaee Compare August 25, 2026 18:05
@s6pa1rta3n-lab

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main, resolved conflicts with the new test suite, and verified npm test and npm run lint are green.

@s6pa1rta3n-lab

Copy link
Copy Markdown
Contributor Author

Rebased onto current main, resolved any conflicts, and verified all tests pass cleanly.

@s6pa1rta3n-lab

Copy link
Copy Markdown
Contributor Author

Rebased on latest main, resolved any conflicts, and ensured all tests and linting pass locally.

@leocagli

Copy link
Copy Markdown
Collaborator

Gracias por rebasear los cuatro, se nota y sirve.

Tres ya estan en main:

Los tres con el CI entero en verde y main verde despues de cada merge.

Este quedo en conflicto justo por el merge de #18: los dos tocan lib/map.js. Un
rebase mas sobre el main de ahora y lo mergeo. La base actual es 65 tests y 517
aserciones en verde.

@s6pa1rta3n-lab
s6pa1rta3n-lab force-pushed the fix/issue-6-solid-spaces branch from 415aaee to 62517f5 Compare August 26, 2026 03:07
@s6pa1rta3n-lab

Copy link
Copy Markdown
Contributor Author

@leocagli The rebase is complete and all 65 tests are passing (70 tests in the latest main). 517+ assertions are green.

@s6pa1rta3n-lab

Copy link
Copy Markdown
Contributor Author

Hola @leocagli! El PR para los espacios transparentes en el mapa está rebasado y pasando todos los test suites. Listo para revisión y merge cuando tengas un momento. ¡Muchas gracias!

@s6pa1rta3n-lab
s6pa1rta3n-lab force-pushed the fix/issue-6-solid-spaces branch from 62517f5 to 3c30ebb Compare August 28, 2026 04:12
Comment thread lib/map.js
Comment thread lib/map.js
Comment on lines 1538 to 1546
for (let row = 0; row < PLAZA_FOUNTAIN.art.length; row++) {
write(PLAZA_FOUNTAIN.x, PLAZA_FOUNTAIN.y + row, PLAZA_FOUNTAIN.art[row])
const artRow = PLAZA_FOUNTAIN.art[row]
const first = artRow.search(/\S/)
if (first === -1) continue
let last = artRow.length - 1
while (last > first && artRow[last] === ' ') last--
fill(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, last - first + 1, 1, ' ')
write(PLAZA_FOUNTAIN.x, PLAZA_FOUNTAIN.y + row, artRow)
}

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: Fountain overlay stamps padding spaces as solid, re-creating invisible walls

In civicSquare(), write() was reverted to stamp every character including spaces, and it is called with the full 47-char padEnd'd artRow starting at PLAZA_FOUNTAIN.x. Since ' ' is registered as a solid 'building' tile (line 62), every leading indentation space and every trailing padEnd space is written as a solid tile, producing a ~47-wide solid rectangle across all 19 fountain rows in the plaza — exactly the invisible-wall bug (#6) this PR claims to fix. The first/last computation and the preceding fill(...) are effectively dead code because the subsequent write() overwrites the same span and the full padded remainder. Fix: only render the trimmed art span so surrounding cobblestone stays walkable, e.g. fill [first..last] to make interior gaps solid, then write only the substring: write(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, artRow.slice(first, last + 1)).

Write only the trimmed art span so leading/trailing padding spaces don't become solid tiles, while fill keeps interior gaps solid.:

for (let row = 0; row < PLAZA_FOUNTAIN.art.length; row++) {
  const artRow = PLAZA_FOUNTAIN.art[row]
  const first = artRow.search(/\S/)
  if (first === -1) continue
  let last = artRow.length - 1
  while (last > first && artRow[last] === ' ') last--
  fill(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, last - first + 1, 1, ' ')
  write(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, artRow.slice(first, last + 1))
}
  • Apply fix

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

@gitar-bot

gitar-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Code Review ⚠️ Changes requested 3 resolved / 4 findings

Fixes invisible walls in art overlays by skipping spaces in write() and registering missing tile characters, but the fountain overlay still stamps padding spaces as solid tiles, re-creating the invisible-wall bug across all 19 plaza fountain rows. The fix requires rendering only the trimmed art span rather than the full padded string to preserve walkable cobblestones around decorative text.

⚠️ Bug: Fountain overlay stamps padding spaces as solid, re-creating invisible walls

📄 lib/map.js:1369-1371 📄 lib/map.js:1538-1546 📄 lib/map.js:62

In civicSquare(), write() was reverted to stamp every character including spaces, and it is called with the full 47-char padEnd'd artRow starting at PLAZA_FOUNTAIN.x. Since ' ' is registered as a solid 'building' tile (line 62), every leading indentation space and every trailing padEnd space is written as a solid tile, producing a ~47-wide solid rectangle across all 19 fountain rows in the plaza — exactly the invisible-wall bug (#6) this PR claims to fix. The first/last computation and the preceding fill(...) are effectively dead code because the subsequent write() overwrites the same span and the full padded remainder. Fix: only render the trimmed art span so surrounding cobblestone stays walkable, e.g. fill [first..last] to make interior gaps solid, then write only the substring: write(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, artRow.slice(first, last + 1)).

Write only the trimmed art span so leading/trailing padding spaces don't become solid tiles, while fill keeps interior gaps solid.
for (let row = 0; row < PLAZA_FOUNTAIN.art.length; row++) {
  const artRow = PLAZA_FOUNTAIN.art[row]
  const first = artRow.search(/\S/)
  if (first === -1) continue
  let last = artRow.length - 1
  while (last > first && artRow[last] === ' ') last--
  fill(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, last - first + 1, 1, ' ')
  write(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, artRow.slice(first, last + 1))
}
✅ 3 resolved
Edge Case: write() skipping spaces leaves gaps inside decorative art

📄 lib/map.js:605-611 📄 lib/map.js:933-947 📄 lib/map.js:995-1004 📄 lib/map.js:966-975
Making write() skip every space is correct for text overlays sitting on walkable ground, but it also applies to standalone decorative art drawn with write(). The fountain (drawn on ';' cobble) and the civicSquare statue (drawn over a '.' approach filled through its center) now keep their walkable base wherever the art has interior spaces, so the player can step between the glyphs into the fountain bowl / statue footprint — contradicting the "statue is solid" intent. If these should stay solid obstacles, fill their footprint with a solid glyph first (as buildings already do with fill(x,y,w,h,' ')) rather than relying on write() to paint spaces.

Quality: Plaza test relies on brittle magic coordinates

📄 test/index.js:1066-1075
The regression test hardcodes fountainRow=79 and x 140..156, which are tied to the current makeHighResolutionCityRows() layout (fountain drawn at 146,79). Any future tweak to the fountain position or plaza fill will silently break this test without indicating a real regression. Consider deriving the scan region from the fountain's known origin/constants, or asserting the property more robustly (e.g., scanning the plaza fill area for unexpected solid ' ' tiles).

Bug: Duplicate backtick key in TILES makes quiet-ground solid

📄 lib/map.js:51 📄 lib/map.js:62-65
The delta adds '': { id: 'quiet-ground', solid: false }at lib/map.js:51, but a pre-existing entry'': { id: 'ornament', solid: true } at lib/map.js:64 sits later in the same object literal, so it wins and the backtick tile resolves to solid:true (verified: TILES['']` = ornament/solid). Backtick is the dominant background glyph in makeRunaCapitalRows and NOX (~37.7k/64k cells in city, ~41k in nox come from the grid default and quietGround), so the entire capital and NOX become impassable — a flood-fill from spawn reaches only 79 city / 116 nox cells, versus ~49k once the tile is walkable. This defeats the whole PR (the quiet-ground fix has no effect) and breaks player movement. Fix by removing the solid ornament backtick entry at line 64 and keeping the walkable quiet-ground definition.

🤖 Prompt for agents
Code Review: Fixes invisible walls in art overlays by skipping spaces in `write()` and registering missing tile characters, but the fountain overlay still stamps padding spaces as solid tiles, re-creating the invisible-wall bug across all 19 plaza fountain rows. The fix requires rendering only the trimmed art span rather than the full padded string to preserve walkable cobblestones around decorative text.

1. ⚠️ Bug: Fountain overlay stamps padding spaces as solid, re-creating invisible walls
   Files: lib/map.js:1369-1371, lib/map.js:1538-1546, lib/map.js:62

   In civicSquare(), write() was reverted to stamp every character including spaces, and it is called with the full 47-char padEnd'd artRow starting at PLAZA_FOUNTAIN.x. Since ' ' is registered as a solid 'building' tile (line 62), every leading indentation space and every trailing padEnd space is written as a solid tile, producing a ~47-wide solid rectangle across all 19 fountain rows in the plaza — exactly the invisible-wall bug (#6) this PR claims to fix. The first/last computation and the preceding fill(...) are effectively dead code because the subsequent write() overwrites the same span and the full padded remainder. Fix: only render the trimmed art span so surrounding cobblestone stays walkable, e.g. fill [first..last] to make interior gaps solid, then write only the substring: `write(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, artRow.slice(first, last + 1))`.

   Fix (Write only the trimmed art span so leading/trailing padding spaces don't become solid tiles, while fill keeps interior gaps solid.):
   for (let row = 0; row < PLAZA_FOUNTAIN.art.length; row++) {
     const artRow = PLAZA_FOUNTAIN.art[row]
     const first = artRow.search(/\S/)
     if (first === -1) continue
     let last = artRow.length - 1
     while (last > first && artRow[last] === ' ') last--
     fill(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, last - first + 1, 1, ' ')
     write(PLAZA_FOUNTAIN.x + first, PLAZA_FOUNTAIN.y + row, artRow.slice(first, last + 1))
   }

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Important

Your trial ends in 4 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.

Was this helpful? React with 👍 / 👎 | Gitar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

paredes invisibles: los espacios del arte quedan solidos y chocas contra la nada

2 participants