Quick answer: GameMaker shader_set_uniform_i values above 2^23 reading wrong on the shader side? Some GPUs treat int uniforms as float32 - cast back from float in shader if precision matters.
Tile ID > 16777216 (2^24) reads back as a slightly different ID. Lookup table misindexes.
Use texture as data buffer
For large integer arrays, encode into a texture and sample. Texture sampling is precise; uniform int isn't on all GPUs.
Split into low/high
Pass two uniforms (low 16 bits, high 16 bits). Combine in shader: id = low | (high << 16).
Cap your ID range
Constrain tile IDs to < 2^23. Most games don't need more; the constraint sidesteps the precision class.
“GLSL ES int may be float-stored. Tight integers need explicit packing.”
If your shader does integer math, run a precision sweep test once. Bugs surface at the boundary value; tests catch the boundary.