Skip to content

Windows checkouts silently corrupt map .bin files (no .gitattributes; autocrlf converts them as text) #4601

Description

@Karamilol

Problem

The repo has no .gitattributes, so binary map assets are subject to git's text/eol handling. On a default Windows clone (core.autocrlf=true — the Git for Windows recommended installer setting), checkout LF→CRLF conversion rewrites map bins: every 0x0A byte in the terrain data grows a 0x0D prefix. The file on disk no longer matches width*height, and the game crashes the moment such a map loads:

Error: Invalid data: buffer size 4855502 incorrect for 2904x1672 terrain plus 4 bytes for dimensions.
    at genTerrainFromBin (src/core/game/TerrainMapLoader.ts)

Currently corrupted on a default Windows checkout (7 files): europe/map.bin (+14 bytes), greatlakes/map.bin (+8), korea/map.bin (+2), levant/map.bin (+57), didierfrance/map16x.bin (+113), losangeles/map4x.bin (+1), venice/map4x.bin (+15).

Why it's sneaky

  • The committed blobs are clean — verified via git cat-file -s (e.g. europe/map.bin blob is exactly 4,855,488 = 2904×1672). Corruption happens purely at checkout, so prod/CI (non-Windows or autocrlf off) never sees it. It strictly bites Windows contributors, who get a broken game out of a fresh clone.
  • Every map bin is exposed, not just these 7. git's binary-detection heuristic looks for a NUL byte in the first ~8k; terrain data contains none there, so ALL map*.bin files are classified as "text" and eligible for conversion. The 7 above are simply the maps whose bytes happen to include 0x0A today — any map regenerated in the future can silently join them.

Repro

  1. Windows, Git for Windows with the default "Checkout Windows-style" setting (core.autocrlf=true).
  2. Fresh clone (or fresh worktree checkout).
  3. resources/maps/europe/map.bin is 4,855,502 bytes on disk vs a 4,855,488-byte blob. Verified each inserted byte is a 0x0D immediately preceding an existing 0x0A (14 LFs in the file, 14 CRLF pairs after checkout, +14 bytes exactly).
  4. Load Europe (or Great Lakes / Korea / Levant) → genTerrainFromBin throws the size error above.

Fix

One .gitattributes at the repo root immunizes everything forever:

*.bin binary
*.webp binary
*.png binary

(Existing corrupted working copies self-heal on the next checkout of those paths after the attributes land.)


Made and verified by Claude — blob sizes checked against two independent clones, corruption reproduced on demand via a fresh checkout of a pre-.gitattributes revision, and the LF→CRLF byte accounting confirmed exactly (every excess byte is a CR inserted before an existing LF).

Metadata

Metadata

Assignees

No one assigned

    Labels

    approvedApproved for a PR, if you assigned to the issue.

    Type

    No type

    Projects

    Status
    Triage

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions