Ok, so I have it figured out now. It’s caused by texture bleeding:
In the background.atlas you have a white background image and the curve image:
If we hide the background it becomes obvious what’s going on:
The edge of the curve image bleeds together with the white background image when the data from the texture is read. The solution is to extrude the border of each image. Out texture packer can do it for you if you specify a non zero value for Extrude Borders when the root of an atlas is selected. A value of 2 is recommended if you’re going to scale the sprites using the images in the atlas.
The reason why it wasn’t always apparent is that both the icon images and the curve images are on the same z-depth of 0. When multiple sprites have the same z-value the rendering order is not guaranteed. Sometimes a curve image is rendered above an icon and sometimes below.
BTW If you want a white background image you can instead do like this:
msg.post("@render:", "clear_color", { color = vmath.vector4(1,1,1,1) })
This will post a clear_color message to the render script and the specified color will be used as background color.
An alternative solution would be to use a 1x1 pixel white dot and scale it to cover the entire background. This would reduce the atlas size significantly and save GPU memory but otherwise be equivalent to what you’re using today.