Quick answer: Sprite flickering on mobile is almost always caused by sub-pixel rendering. Enable Pixel rounding in Project Properties, set Sampling to Point for pixel art games, and use Letterbox Scale or Letterbox Integer Scale as your fullscreen mode. These three changes eliminate the fractional positioning that causes sprites to shimmer between frames on mobile GPUs.

Here is how to fix Construct 3 sprite flickering on mobile devices. Your game looks perfect in the browser preview on desktop, but the moment you test on a phone or tablet — or wrap it in a WebView for a mobile app — sprites start visually flashing, shimmering, or producing thin lines between tiles. This is one of the most reported Construct 3 issues on mobile, and it comes down to how mobile GPUs handle sub-pixel rendering.

The Symptom

Sprites flicker, flash, or produce visible seams while the game runs on a mobile device. The flicker is often intermittent — it shows up when the camera scrolls, when sprites move at certain speeds, or when the device orientation changes. Tile-based games are especially affected: you see thin lines between tiles that appear and disappear as the camera moves.

On desktop, the same project runs without any visual artifacts. The problem only manifests on mobile browsers (Chrome on Android, Safari on iOS) or when the game is packaged inside a WebView wrapper like Cordova or Capacitor.

In some cases the flicker only appears at certain scroll speeds. Moving the camera slowly produces clean output; moving it at normal gameplay speed causes sprites to shimmer. This speed-dependent behavior is the hallmark of a sub-pixel rendering issue rather than a logic or z-order bug.

What Causes This

There are five common causes, roughly ordered by frequency:

1. Sub-pixel positioning without pixel rounding. This is the cause in the majority of cases. When a sprite sits at position (102.4, 55.7), the GPU must decide how to render that fractional pixel. On desktop GPUs with higher precision, this blending is invisible. On mobile GPUs, the rounding produces visible shimmer — the sprite visually jumps between two pixel positions on alternating frames. Construct 3 has a Pixel rounding setting that snaps rendered positions to whole numbers, but it is off by default.

2. Linear sampling on pixel art. Linear sampling blends neighboring texels when a sprite is rendered at a non-integer position or scale. For HD art this looks like smooth anti-aliasing. For pixel art, it produces blurry, shimmery edges that flicker as the sprite moves. Pixel art games should always use Point sampling, which renders each texel as a hard-edged block.

3. Fullscreen scaling mode producing fractional ratios. If your viewport is 320x180 and the device screen is 1170x2532, the scaling ratio is not a clean integer. Modes like Scale Outer or Crop can produce non-integer scaling, which means some pixel rows get an extra pixel while others do not. This creates visible banding and shimmer, especially on tiles and repeating patterns.

4. Tilemap seams from floating-point precision. When the camera position is a floating-point number, adjacent tiles can round to positions that leave a sub-pixel gap between them. The gap reveals the background color for a single frame, producing a flickering line. This is distinct from sprite flickering — it appears as thin colored lines between tiles.

5. WebGL rendering issues on specific mobile GPUs. Some older mobile GPUs (particularly Mali-4xx and Adreno 3xx series) have precision issues in their WebGL implementations that cause texture sampling artifacts. This is hardware-level and cannot be fully fixed in project settings, but the rendering workarounds below significantly reduce the effect.

The Fix

Step 1: Enable pixel rounding. Open your project and go to Project Properties. Find the Pixel rounding setting and set it to On.

// Project Properties
Pixel rounding: On

// If you need sub-pixel movement for gameplay logic
// but want pixel-snapped rendering, keep pixel rounding On.
// The object's internal position stays fractional;
// only the rendered position is rounded.

Pixel rounding does not affect gameplay physics or collision detection. It only changes where the sprite is drawn on screen. Your movement code can still use fractional positions for smooth velocity calculations.

Step 2: Set the correct sampling mode. In Project Properties, change Sampling based on your art style:

// For pixel art games:
Sampling: Point

// For HD / high-resolution art:
Sampling: Linear

// If using a mix, set the project to Point and use
// the "Set blend mode" action on HD sprites that need Linear.

Point sampling eliminates the sub-texel blending that causes shimmer on pixel art. If your game mixes pixel art backgrounds with HD UI elements, set the project to Point and handle exceptions per-sprite.

Step 3: Choose the right fullscreen scaling mode. Go to Project Properties and set Fullscreen mode:

// Best for pixel art (clean integer scaling):
Fullscreen mode: Letterbox Integer Scale

// Good general-purpose (maintains aspect ratio):
Fullscreen mode: Letterbox Scale

// Avoid for pixel art (causes fractional scaling):
// Scale Outer, Scale Inner, Crop

Letterbox Integer Scale ensures the viewport is always scaled by a whole number (2x, 3x, 4x), which means every source pixel maps to exactly the same number of screen pixels. No fractional rounding, no shimmer.

Step 4: Fix tilemap seams. If you see lines between tiles, the issue is floating-point camera positioning. Round the scroll position to whole numbers:

// Event sheet: Every tick, snap scroll to integer
SystemEvery tick
  SystemScroll to round(ScrollX), round(ScrollY)

// Or in JavaScript (Construct 3 scripting):
const runtime = this.runtime;
const layout = runtime.layout;
layout.scrollX = Math.round(layout.scrollX);
layout.scrollY = Math.round(layout.scrollY);

Step 5: Handle problematic mobile GPUs. If flickering persists on specific Android devices, try reducing GPU load by disabling effects and lowering the rendering resolution:

// Event sheet: On start of layout
BrowserIs mobile
  // Reduce device pixel ratio for older GPUs
  BrowserSet CSS style "devicePixelRatio" to "1"

// In JavaScript:
if (/Android/.test(navigator.userAgent)) {
  runtime.setTargetFrameRate(60);
}

Why This Works

Sprite flickering on mobile fundamentally comes from the gap between logical positions and physical pixels. Desktop GPUs have enough precision and fill rate to handle this gap invisibly. Mobile GPUs cut corners for power efficiency, and those corners show up as visual artifacts.

Pixel rounding eliminates the root cause by ensuring every sprite renders at a whole-pixel position. The GPU never has to decide how to blend a sprite across a pixel boundary, so there is nothing to flicker.

Point sampling removes the secondary blending pass that linear filtering introduces. For pixel art, this is doubly important because linear filtering on a pixelated texture creates ghost pixels at the edges that shimmer as the sprite moves.

Integer scaling ensures the viewport-to-screen mapping is uniform. When every source pixel becomes exactly 3x3 screen pixels (for example), there are no uneven rows or columns that create banding artifacts during scroll.

Rounded scroll positions prevent tilemap seams by ensuring adjacent tiles always butt up against each other at exact pixel boundaries. A camera at position 100.3 might cause tile A to render at x=200 and tile B at x=232 instead of x=231.7, leaving a gap. Rounding to 100 prevents this.

"Mobile flickering is the number one visual bug report I get from playtesters. Two checkboxes in project properties — pixel rounding and point sampling — fix it every time for pixel art games."

Related Issues

If your sprites render correctly but touch input is not working on mobile, the problem is in input handling rather than rendering. For sprites that visually appear fine but pass through solid surfaces, see our guide on physics objects falling through the floor. If your tilemap collisions are not registering at all, tilemap collision setup covers the collision polygon configuration. And if your events are running more often than expected and causing visual glitches, check events firing multiple times per tick.

Pixel rounding on, Point sampling, integer scale. The mobile flicker trifecta.