Phaser AE

Voxel Editor

Free packv3.0.0-33DLogic

Point at a block and change it. The targeting, the cadence, the mining progress and the guards a block-building game needs, with none of the effects, so a break means whatever your game says it means.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 19, 2026

Voxel Editor: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

The pack

voxelEdit3d

function voxelEdit3d(opts: VoxelEdit3dOptions = {}): Pack<{ voxelEdit: VoxelEdit3dApi }>

The voxel-edit-3d pack: targeting and editing for a voxel world. It emits events rather than effects, so the game decides what a break or a place actually does.

Helpers

cubeOutline

function cubeOutline(): Array<Array<[number, number, number]>>

The twelve edges of a unit cube, as polylines — the target outline.

Types

VoxelEdit3dApi

interface VoxelEdit3dApi

game.voxelEdit.

  • update(dt: number, input: VoxelEditInput): VoxelEditResult — One frame: aim, apply a held break or place, and report what happened.
  • block: number — The block a place drops. Set it from a hotbar. Live.
  • reach: number — Ray reach in blocks. Live.
  • hardness(fn: ((id: number) => number) | null): void — Hits needed to break a block, by id. Return 1 for instant creative mining, which is the default.
  • forbid(fn: ((x: number, y: number, z: number) => boolean) | null): void — Refuse to place into these cells — the player's own body, usually. The result reports it as blocked.
  • onHit(fn: ((e: VoxelHitEvent) => void) | null): void — Called on each mining hit, with the progress toward breaking.
  • onBreak(fn: ((e: VoxelEditEvent) => void) | null): void — Called when a block breaks — spawn the debris here.
  • onPlace(fn: ((e: VoxelEditEvent) => void) | null): void — Called when a block is placed.
  • readonly target: VoxelHit | null — The block currently aimed at, or null.
  • readonly placeCell: { x: number; y: number; z: number } | null — The cell a place would fill, or null.
  • readonly blocked: boolean — True when a place there is refused.

VoxelEdit3dOptions

interface VoxelEdit3dOptions

Manifest options.

  • reach?: number — How far the ray reaches, in blocks. Default 8, which is about creative reach.
  • block?: number — The block a place drops. Default stone.
  • breakRate?: number — Seconds between mining hits while the break button is held. Default 0.15.
  • placeRate?: number — Seconds between placements while the place button is held. Default 0.2.
  • debounce?: number — Frames a new target must hold before it commits. It de-twitches the outline at a block seam, where a single pixel of aim flips between two cells. Default 3; 0 is off.

VoxelEditEvent

interface VoxelEditEvent

A block placed or broken. id is the block placed, or the one that was there.

  • x: number — Cell x.
  • y: number — Cell y.
  • z: number — Cell z.
  • id: number — The block placed, or the one that was there.

VoxelEditInput

interface VoxelEditInput

Per-frame ray and button state.

  • origin: { x: number; y: number; z: number } — The start of the ray, world units — usually the eye.
  • dir: { x: number; y: number; z: number } — The ray direction; it is normalised for you.
  • mining?: boolean — Break button held.
  • placing?: boolean — Place button held.

VoxelEditResult

interface VoxelEditResult

What the editor changed this frame; also delivered to the callbacks.

  • target: VoxelHit | null — The committed target, or null when nothing is in reach.
  • placeCell: { x: number; y: number; z: number } | null — The empty cell a place would fill — the target plus its face normal.
  • blocked: boolean — True when placing there is refused by the guard.
  • hit: VoxelHitEvent | null — The mining hit applied this frame.
  • broke: VoxelEditEvent | null — The block broken this frame.
  • placed: VoxelEditEvent | null — The block placed this frame.

VoxelHitEvent

interface VoxelHitEvent extends VoxelEditEvent

One mining hit.

  • progress: number — How far toward breaking, 0..1.