Quick answer: JS numbers are all double-precision floats. Wrap reads in int(Array.At(x)) when you need integers, or use floor() in comparisons.

A grid puzzle stores tile IDs as integers in JSON. After loading, comparison Array.At(0) = 5 fails because the value is 5.0 (or 5.0000001 from rounding).

Convert at Read

Local var tile = int(Array.At(x, y))
If tile = 5:
    → do_something

int() floors and converts to whole number. Comparison reliable.

Avoid Subtle Float Drift

5 / 1.0 in JS is 5. But 5 * 0.1 * 10 = 4.99999999999. Don’t multiply / divide in event sheet expressions; do once with int() at the boundary.

Save with Quotes for Safety

Store as strings in JSON if you want strict typing:

{"tiles": [["1", "2", "3"]]}

Parse via int(Array.At(x, y)). Verbose but unambiguous.

Compare with Tolerance

For float fields:

abs(value - target) < 0.0001

Better than == when reading floats from JSON.

Verifying

Load level. Tile checks pass. No off-by-one float drift bugs.

“JSON numbers are floats in JS. Cast on read, compare with tolerance for floats.”

For huge tilemaps, consider packing tile data as a base64 string — faster to parse than nested arrays, no float ambiguity.