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.