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.


