Skip to content

Optimization & Performance

This page explains the technical mechanisms Mosaikin uses to make player head walls practical — covering how images are rendered, how generation costs are reduced, and what affects in-world performance.

How Player Head Walls Work

Minecraft player head textures are 64×64 pixel images applied to a 3D cube. Mosaikin exploits the fact that a player head has six visible faces, each of which shows a distinct 8×8 pixel region of the texture.

When Mosaikin generates a wall:

  1. The source image is divided into an 8×8 pixel grid
  2. Each cell in the grid maps to one face of one player head
  3. Up to 6 cells are packed into a single player head texture (one per face)
  4. Each unique head texture is submitted to MineSkin to create a real Minecraft player skin
  5. In the world, one ItemDisplay entity per cell renders that face of the head at the right position and orientation

No resource pack is involved — these are real player head skins, visible on any vanilla client.

Chunk Deduplication

When two or more grid cells contain identical 8×8 pixel regions, they share a single head texture. Mosaikin identifies identical cells using a SHA-256 hash of each cell's pixel data.

This is particularly effective for:

  • Repeating patterns — tiled textures, grids, backgrounds
  • Solid colors — large areas of a single color all hash identically
  • Multi-frame animations — cells that don't change between frames are shared across all frames that use them

Deduplication reduces both the number of MineSkin submissions and the number of distinct entities in the world. You can see the before/after savings in /mosaikin <name> info.

Region Merging

Even after deduplication, cells that are individually similar (but not identical) still each require a separate entity. Region merging addresses this by detecting spatially uniform rectangular areas and replacing them with a single, larger entity.

When a region of the wall — say a 4×4 block of cells — stays visually consistent across some or all animation frames, Mosaikin can:

  1. Average the pixels in that region down to a single 8×8 texture
  2. Render the entire region as one large ItemDisplay entity scaled to cover the same area
  3. Spawn that entity only for the frames during which the region stays uniform, then swap back to individual cells for the rest

This is most effective for:

  • Solid backgrounds — the most common case; large uniform regions collapse to a single entity
  • Slow-changing areas — parts of an animation that don't move between many consecutive frames

The result is fewer entities, fewer MineSkin uploads, and lower server-side CPU cost during animation playback. The optimization is tunable via walls.regionMerge in config.yml.

Merge sizes

Mosaikin checks for mergeable regions at sizes 2×2, 4×4, and up to 8×8 cells (configurable). It also allows non-square regions (2×4, 4×2, etc.) when rectangular: true. Larger merges save more entities but require the region to stay more uniform to qualify.

Similarity threshold

Region merging doesn't require pixel-perfect uniformity. The similarityThreshold setting (default: 12, on a 0–255 scale) allows slight variations — gradients or noise up to this tolerance are treated as uniform. Raising this value merges more aggressively at the cost of some visible blurring in affected areas.

Frame Rate Capping

Minecraft's server tick rate is 20 TPS, which means walls can display at most 20 frames per second regardless of the source material's frame rate. Mosaikin automatically downsamples source animations during decoding:

  • A 60 FPS GIF is reduced to 20 FPS by keeping every third frame
  • Frames are selected at evenly spaced intervals to preserve timing
  • The exported archive already contains the downsampled frames — the plugin does not need to do this in-game

This prevents you from uploading more frames to MineSkin than the plugin can actually display.

Proximity Pausing

When playback.pauseWhenNoNearbyPlayers is enabled (the default), Mosaikin skips the per-tick animation update for walls that have no players within proximityDistanceBlocks. This eliminates the CPU overhead of animating walls that nobody is currently watching.

The check runs once per second (configurable with proximityCheckIntervalTicks). When a player enters range, animation resumes on the next check.

What Affects Generation Time

FactorEffect
Image resolutionQuadratic — doubling dimensions = 4× more cells
Frame countLinear — 2× the frames = roughly 2× the heads
Image complexityMore unique cells = more MineSkin submissions
Solid areasCollapse to very few heads via dedup + merging
MineSkin subscriptionHigher tiers allow more concurrent submissions

What Affects In-World Performance

FactorEffect
Total entity countMost significant — each visible cell is one entity
Animation frame rateHigher FPS = more frequent entity updates per tick
Number of simultaneous wallsEntity counts add across all walls in loaded chunks
Player proximityMore nearby players = more client-side rendering work

Region merging and chunk deduplication both directly reduce entity count. Beyond that, the main levers are image size and animation complexity — simpler, smaller images perform better.

Practical Guidelines

  • Start small. A 128×128 still image with default settings generates about 256 entities. Scale up from there once you know what works.
  • Use solid backgrounds. They compress extremely well via region merging.
  • Trim animations. Shorter loops with fewer unique frames generate far fewer heads.
  • Avoid placing multiple large walls in the same area. Entity counts add up quickly.
  • Check /mosaikin <name> info before spawning — it shows head count and grid dimensions so you can estimate the in-world impact.