THE ACTION LIFECYCLE
One mining swing crosses four different layers
First, the browser decides what the player is pointing at and whether the equipped tool can physically reach it. A valid strike accumulates local damage and creates a pending record containing the target coordinate, block and resource IDs, selected tool slot, affected blocks, and a planned base-reward summary.
Second, the chain adapter turns that pending record into a transaction. Third, the chunk program verifies the action against canonical world and account state. Fourth, the automatic chain path reconciles and applies the accepted delta, then refreshes the chain-backed world and backpack views. A separate manual Confirm control can still resolve a pending delta locally and is not evidence of shared-state confirmation.
- Interact locally
Select a visible target, check reach and protection hints, animate the tool, and detect a real tool-box contact with the voxel.
- Create a pending action
Preserve an integer coordinate tuple and the exact local proposal without yet treating it as authoritative chain state.
- Submit and validate
Sign the transaction and let the program validate PDA derivations, recalculate generated facts, and validate current account contents.
- Confirm or roll back
In the automatic chain path, commit the rendered delta after confirmed submission, or remove the pending action and restore local tool damage when it fails. A manual local confirm remains a separate, non-authoritative path.
FRAME-SPEED WORK
What stays local, and why
Camera motion, pointer rays, target highlights, tool poses, hit sparks, sound, partial-damage indicators, and mesh updates are presentation and interaction work. Putting these on chain would add latency without making the underlying world rule more trustworthy.
The mining controller also checks obvious invalid cases locally: no usable tool, no backpack, a target outside reach, fluid or air, protected foundations, a target that changed before impact, or a duplicate pending target. These checks improve the experience, but they do not replace program validation.
AUTHORITATIVE WORK
The mining program checks the world instead of trusting the claim
The reward-bearing mine instruction receives 12 accounts: session authority, player profile, player session, player progress, ChunkBroken, foundation chunk, global configuration, resource-drop table, surface-decoration table, backpack program, backpack, and system program. It validates the exact count, writable status, program ownership where required, the PDAs explicitly derived by the instruction or backpack CPI, owner and data relationships for the remaining accounts, and the player's active action context before processing the target.
It reads the submitted world-coordinate tuple, checks its height, derives chunk and local coordinates with Euclidean division, recalculates the generated block, compares that result with the expected block ID, rejects air, water, and bedrock, checks foundation protection, and prevents the same generated coordinate from being recorded twice. It then resolves extra-drop and surface-decoration rules from the two program-owned tables.
The client submits the integer target; the program independently recalculates the generated block ID at that coordinate.
An accepted generated block removal is stored as a compact coordinate in its chunk account.
The primary block reward must fit. Eligible secondary rewards use a best-effort append and may be partial when capacity is exhausted.
CLIENT RECONCILIATION
The automatic chain path uses pending as a reversible bridge
The chain module signs and sends the transaction, then waits for confirmed commitment. A successful result carries the signature and, for a batched outcome, the reconciled block list. Only then does the automatic chain session ask the mining controller to confirm the pending delta.
If the wallet is unavailable, the adapter rejects the action, the transaction throws, or the program returns an unsuccessful result, mining rolls back its pending record. The controller restores the locally consumed tool damage and does not apply that pending block-removal delta.
- Batch outcomes such as support collapse can be reconciled to the exact subset the chain confirmed.
- After confirmation, the client requests fresh ChunkBroken snapshots and refreshes the PDA backpack.
- Local-preview mode is labeled separately; it must not be confused with a confirmed shared transaction.
- The current manual Confirm input has no chain-state guard and can apply a pending delta locally; that result is not a chain receipt.
- Console failure reports include transaction errors and program logs when available, making rejected actions diagnosable during the current session.
HONEST SCOPE
Verification is specific to the action and accounts involved
For mining, NiceChunk can verify the canonical generated-block identity at the submitted coordinate, protection state, rule-table result, duplicate-removal state, player session, an owner-derived backpack PDA, and the writes performed by that instruction. The client chooses the equipped backpack it submits; the programs validate ownership and PDA derivation rather than comparing that address with the profile's equipped-backpack field. The chain does not verify which coordinate the player actually aimed at, nor simulate the rendered camera, exact hand path, particles, every intermediate frame, or a manually confirmed local delta.
Other actions have their own instruction formats and checks. A forging transaction, for example, validates backpack material slots and compact design requirements rather than replaying the workbench animation.
EXECUTION GATES
Separate the program predicate from client reconciliation
The first equation summarizes the authoritative checks for one generated-block mine. The second describes the exact set intersection used when a batched result reports which proposed coordinates the chain accepted.
Core acceptance gate for a generated-block mine
accept(p) = validAccounts AND validSession AND expectedBlock = G_chain(p) AND G_chain(p) NOT IN {air, water, bedrock} AND NOT protected(p) AND p NOT IN ChunkBroken AND primaryRewardFitsThis is a compact model of the instruction rather than one literal source expression. Account validity includes the expected writable flags, owners, PDA derivations, both rule tables, backpack program, and owner-derived backpack. The primary reward append must succeed; eligible secondary rewards are best effort.
- p
- The submitted integer world coordinate x, y, z.
- G_chain(p)
- The block ID independently recalculated by the chunk program for p.
- validAccounts
- The instruction received the required accounts with valid count, ownership, and writability; it validates the PDAs explicitly derived by the instruction or backpack CPI plus owner and data relationships for the remaining accounts.
- ChunkBroken
- The program-owned set of generated coordinates already recorded as mined for the affected chunk.
- primaryRewardFits
- The validated backpack can accept the required mined-block reward; secondary rewards may be partial.
Confirmed subset for a batched outcome
K_commit = intersection(K_pending, K_chain)When a batch result carries confirmedBlocks, the client converts both proposals and confirmed coordinates to integer keys, keeps only their intersection, and filters pending air deltas and reward groups to that same subset before confirmation.
- K_pending
- Coordinate keys proposed by the local mining plan.
- K_chain
- Coordinate keys returned in the chain result as confirmed.
- K_commit
- The only proposed block keys retained for the confirmed local delta.
The program recalculates and rejects a mismatched block
Rustprograms/nicechunk_chunk/src/lib.rs let surface = generated_surface_height(global_config_view, args.world_x, args.world_z);
let block_id = generated_block_id_at_surface(global_config_view, &generated_args, surface);
if args.expected_block_id != block_id {
return Err(NicechunkChunkError::GeneratedBlockMismatch.into());
}
if matches!(block_id, BLOCK_AIR | BLOCK_WATER | BLOCK_BEDROCK) {
return Err(NicechunkChunkError::UnmineableBlock.into());
}
The signed payload supplies an expected block ID, but the instruction uses its own generated result and rejects a mismatch or an unmineable canonical block.
The client keeps only block keys confirmed by a batch result
JavaScriptplay/play-chain-mining-result.js const previousCount = Math.max(1, Math.trunc(Number(pending.minedBlockCount) || originalBlocks.length || 1));
const chainConfirmedBlocks = Array.isArray(chainResult?.confirmedBlocks) ? chainResult.confirmedBlocks : [];
let confirmedBlocks = originalBlocks;
if (chainConfirmedBlocks.length) {
const confirmedKeys = new Set(chainConfirmedBlocks.map(blockKey).filter(Boolean));
confirmedBlocks = originalBlocks.filter((block) => confirmedKeys.has(blockKey(block)));
if (!confirmedBlocks.length) return { changed: false, droppedCount: 0, confirmedCount: 0 };
const confirmedKeySet = new Set(confirmedBlocks.map(blockKey));
pending.blocks = confirmedBlocks.map((block) => ({ ...block }));
pending.pendingDeltas = (Array.isArray(pending.pendingDeltas) ? pending.pendingDeltas : [])
.filter((delta) => confirmedKeySet.has(blockKey(delta)))
.map((delta) => ({ ...delta }));
pending.collapseBlocks = (Array.isArray(pending.collapseBlocks) ? pending.collapseBlocks : [])
.filter((block) => confirmedKeySet.has(blockKey(block)))
.map((block) => ({ ...block }));
pending.minedBlockCount = confirmedBlocks.length;
}
Support-collapse and other batched proposals can be larger than the accepted result. Reconciliation removes every unconfirmed coordinate before the mining controller applies the pending air deltas.
IMPLEMENTATION EVIDENCE
Where these claims come from
Each claim is intentionally scoped to a concrete implementation path. These references are for verification, not decoration.
play/mining-controller.js
Implements local target validation, swept tool collision, partial damage, pending action records, confirmation, and reversible rollback.
play/play-chain-session.js
Separates local preview, wallet-needed, submitting, confirmed, and rejected states and confirms or rolls back pending actions from adapter results.
play/play-input-actions.js
Exposes the current manual Confirm and Rollback controls, including the local-confirm path that is not guarded by chain state.
play/play-chain-adapter.js
Maps pending integer action data to mining and placement calls in the lazily loaded chain module.
play/play-chain-mining-result.js
Reconciles batch mining proposals to the exact confirmed block subset and its confirmed base-reward block subset.
src/chain/nicechunkChain.js
Builds and signs gameplay transactions, waits for confirmed commitment, and returns structured action results.
programs/nicechunk_chunk/src/lib.rs
Validates mining accounts, session, generated block, protection, rule tables, ChunkBroken state, rewards, and player progress.
play/play-chain-chunk-deltas.js
Reads confirmed ChunkBroken account snapshots and applies their decoded coordinate deltas to loaded chunks.
