Files

17 KiB

Shacraft Core acceptance criteria

Status: criteria for the local MVP. Implemented scenarios and evidence are listed in STATUS and VERIFICATION. This document preserves the original acceptance plan; limitations in broader stress testing and compatibility are not hidden behind a general readiness flag.

Shacraft Core is an independent open-source Rust engine. The Shacraft server and Spleef test its practical suitability. Reducing server RAM use is the primary architectural requirement. A complete base Minecraft 26.2 catalog means content, states, and shapes; it does not require reproducing Minecraft's architecture or the entire vanilla game.

Recording results

For every check, retain its identifier, source revision, tool versions, command or scenario, input data, actual result, and path to the evidence. Statuses: not tested, passed, failed, or blocked, with a specific reason. A build alone does not establish that networked gameplay works or that imports are correct.

The checks below form two milestones. The first provides a working foundation and helps uncover integration errors quickly. Passing it does not mean that the full MVP is complete or reduce the original scope.

Milestone A: minimal end-to-end implementation

A-CORE: storage and independent worlds

  • The core builds and can be used from a separate Rust process without HTTP, rendering, a browser, or a running Minecraft server.
  • A template and two independent worlds based on it exist. Changing a block in the first world does not change the template or the second world. Replacing the source template does not change an already pinned immutable version.
  • Deleting an inherited block records air in the overlay, rather than returning the template block on the next read. Check positive and negative coordinates and section boundaries.
  • world.edit accepts or rejects an entire batch of changes atomically. A stale revision, unknown block, or invalid coordinates leave no partial changes.
  • Repeating an operation with the same operation_id and content returns replayed: true, does not increase the revision, and does not apply the edit again. Reusing an identifier with different content must have documented safe behavior; this check cannot be closed until that behavior is defined.
  • world.undo restores the previous content of the selected operation; conflicts with subsequent edits follow an explicit policy. Check restoration of inherited state and removal of overlays.
  • world.reset restores the selected template version without damaging other worlds. Its revision change and treatment of the operation journal are documented and tested.
  • read_region returns the correct nonzero blocks within inclusive bounds. A region of exactly 262144 cells is accepted; exceeding the limit or overflowing boundary arithmetic is rejected before a large allocation.

A-E2E: two clients, MCP, and restart

Run this reproducible scenario on one local installation with a clean data directory:

  1. Start the server at 127.0.0.1:4000, check /api/health, open two independent browser sessions, and connect MCP as a separate process.
  2. Both clients enter the same world. Each sees the geometry and the other player; movement, turning, jumping, and collisions use the shared coordinate system defined in the contract.
  3. The first client breaks and places an available block. The second receives the change without reloading. Reconnecting retrieves the same state and current revision.
  4. MCP reads a region, finds a block through the catalog, and makes an edit with expected_revision and operation_id. Both clients see the edit. Repeating the same operation is idempotent; an intentionally stale revision returns a clear error.
  5. MCP performs undo, and both clients see the restoration. MCP requests a camera image; the PNG opens and shows the expected part of the world rather than a blank image.
  6. Create a second world from the template, switch one client to it, and edit a block. The other client, still in the original world, receives neither the other world's edits nor its player states.
  7. Record the positions to verify, block values, world names, pinned templates, block identifiers, and revisions. Stop the server, start it with the same data directory, and reconnect the clients and MCP. All recorded values match; acknowledged durable operations have not been lost.
  8. Repeat recovery after forcibly terminating the process in a controlled test. A corrupt or incomplete write tail does not make a previously acknowledged world unreadable. If acknowledgement guarantees differ from flush guarantees, the contract states this in advance.

Evidence: a log of actions and protocol responses, comparisons before/after restart, and a screenshot of two clients. A protocol script supplements browser visual verification but does not replace it.

A-SERVER: the server determines game state

  • Attempting to join an arbitrary unknown world, submit nonnumeric/unbounded coordinates, or use an invalid BlockId cannot crash the process.
  • The client sends input; the server determines coordinates, velocity, collisions, and action outcomes. A forged packet containing a final position does not teleport the player.
  • The server checks interaction distance and whether the game state permits an action. A player cannot break distant blocks or edit a world they are not in.
  • Packet rates and message sizes are bounded. A stream of malformed, oversized, or overly frequent messages from one connection cannot create an unbounded queue or prevent the second client from playing.
  • The control HTTP API rejects missing and invalid tokens. The token never appears in the public manifest, client build, URLs, or ordinary logs. The token file is created with permissions 0600.
  • Incompatible protocol versions and manifests result in a documented rejection or update before entry. A matching claimed hash is not treated as proof that the client program is trustworthy.
  • After a disconnection, the player is removed from the corresponding world; reconnection does not create an indefinite duplicate entity.

A-CLIENT: a playable browser client

  • The client opens at the server address, obtains the manifest and catalog, and displays blocks, open space, shapes from the initial set, and players.
  • Camera controls, movement, jumping, block selection, placement/removal, and world switching are available without manually sending requests from the developer console.
  • The client explains rejected entry, lost connections, and action errors with clear messages; a stuck state is not presented as server-confirmed.
  • Geometry updates after network edits. Initial loading, reconnection, and world switching do not retain geometry from the previous world.

A-MCP: a real, separate MCP implementation

  • A separate MCP process successfully completes initialize, advertises tools, and executes tools/call through an MCP client. Providing only /api/control does not satisfy this criterion.
  • World operations, catalog search, reading, batch editing, undo, metrics, arena startup, camera images, and the entity operations declared in the contract are available.
  • Argument schemas, results, and errors match actual behavior. An unavailable server or invalid token produces a tool error without hanging the MCP process.
  • MCP uses the same revision, boundary, and data-validity checks as other administrative requests. Search limits response size, and reads do not dump an entire large world into context.

A-SPLEEF: one complete match

  • Two clients take part in an arena on a shared map. There are waiting/preparation, start, active play, and completion phases; the server reports the phase and remaining time.
  • During active play, only the permitted arena layer can be broken. Block placement and edits outside the region are restricted by the mode's rules.
  • Falling below the configured boundary eliminates the player on the server. One winner is declared when a single participant remains; the rules define the outcome of simultaneous eliminations and disconnects.
  • Completion and restart restore the map and participants. A parallel arena based on the same template retains its own state.
  • Starting an already active match twice cannot create multiple timers or award the result repeatedly.

A-MEMORY: bounded memory in the foundation

  • Reading more distinct sections than cache_sections does not increase the number of resident cached sections beyond the configured capacity. Also test a capacity of 0 or its explicitly documented rejection.
  • Two or more worlds with a shared immutable base do not each receive a complete copy of the map data in RAM. World metadata and changes are accounted for separately.
  • Unloading a modified section preserves its changes; reading it again after eviction and after restart returns the same result.
  • Operation history is stored on disk. A long sequence of edits does not require keeping the entire journal and all state snapshots in RAM.
  • Metrics expose at least the world count, resident section count, and configured cache capacity. Process RSS is measured externally; a single cache counter is not presented as the entire server's memory use.

Milestone B: the complete agreed MVP

All milestone A checks are mandatory. The following parts must also be completed; an initial demonstration with a few blocks does not replace them.

B-CONTENT: the complete base Minecraft 26.2 catalog

  • The exact 26.2 edition/build, catalog source, and input checksums are recorded. Completeness is checked against that dataset, not a predetermined block count.
  • Automated comparison covers every base block, valid states, render and collision shapes, and every base entity type in the target set.
  • Canonical names and properties survive registration, storage, network transmission, and restart without loss. Unknown states are not silently replaced with air.
  • The entity catalog includes data needed for rendering, placement, storage, and world interchange; each type's behavioral capabilities are explicitly marked. A stub for every type does not count as a complete catalog with working shapes.
  • Non-full-cube shapes, orientations, multipart blocks, transparency, and blocks with additional data are checked separately. Client and server use compatible shapes and properties.
  • Resources are built reproducibly from declared sources. A missing resource produces a diagnostic with its specific identifier, and the report includes a complete list of gaps.

B-PACKAGES: a unified system for modules and resources

  • One versioned package format describes modules, textures, shaders, and other resources, dependencies, compatibility, and execution sides.
  • The server generates a manifest with exact versions and hashes; the client automatically obtains the required client-side parts, verifies integrity, and reuses its local cache.
  • Checks cover a missing package, incompatible version, dependency cycle, corrupt download, interruption/resumption, and changes to the package set between connections. A partial installation is not activated as a complete one.
  • Server files and secrets are excluded from client distribution. Packages cannot write outside the installation directory through relative paths or archive entries.
  • An extension registers new content through a documented interface and can be connected without editing core source code. Execution permissions, available APIs, and module resource limits are defined and tested.
  • The project runs independently of Shacraft Launcher. The future integration interface is documented. Actual changes to or verification of the existing launcher belong to a separate integration stage and do not block a local engine release.

B-INTEROP: Minecraft ↔ Shacraft import and export

  • Import/export commands and formats are documented. Small reference worlds for the target version cover multiple dimensions, negative coordinates, block states, entities, block-entity data, and custom data.
  • The server and client open an imported world; sampled and complete automated comparisons against the fixtures verify coordinates, states, and supported data.
  • The Minecraft → Shacraft → Minecraft cycle preserves supported data semantically. Decoded values are compared; compressed files need not be byte-identical.
  • Original unknown or unsupported data is preserved for export back to the source format when its meaning cannot be transferred correctly. Export does not silently destroy it after edits to other parts of the world.
  • Changes made through the client and MCP appear correctly in the exported world. Block deletion, new states, and entities are checked separately.
  • The report lists preserved, transformed, unsupported, and lost data, with a coordinate/identifier and reason. Missing data is not concealed behind a success status.
  • A corrupt file, incomplete region, unknown version, oversized decompressed record, or cancelled operation does not damage the source or a pre-existing target world.
  • The converter processes the world in portions; RAM use does not grow to the size of the entire world. A reference dataset larger than the cache budget converts successfully.

B-PERSISTENCE: durable server state

  • Worlds, pinned template versions, the content registry, edits, required undo data, arena configuration and rules, and persistent entities are stored on disk.
  • The policy for an active match after restart is defined: resume or safely reset. The result leaves neither a permanently active arena nor a duplicated victory.
  • Interruptions during section, metadata, and journal writes are tested. Recovery selects a consistent version; data already acknowledged as durable survives according to the contract.
  • The storage format version is checked on open. An incompatible version produces a clear refusal or a verifiable migration that allows recovery of the original data.

B-MEMORY: demonstrated server RAM savings

Run the benchmark on a fixed dataset and hardware. Before measurement, record limits, map size, world and player counts, edit rate, active region volume, and permitted RSS headroom; publish these values with the results.

  • Compare 1, 10, and 100 independent worlds based on one large template: without players, with the same active region, and with different active regions. Metadata and changed data may grow; there is no complete map copy per world.
  • For each variant, record RSS/p95/peak, resident sections and their bytes, overlay size, player count, network queues, tick rate/latency, and on-disk data size.
  • After traversing regions larger than the cache, inactive sections are evicted. Repeated traversals and world creation/reset cycles do not cause continuous linear growth in retained memory.
  • A slow client, long journal, frequent MCP images, and concurrent imports cannot bypass limits through queues, response buffers, or auxiliary caches.
  • Target memory and tick-latency limits hold under the published load. Without a predefined budget, individual structures can be shown to be bounded, but a specific server scale cannot be claimed as achieved.

B-DELIVERY: a reproducible open-source project

  • The repository contains source for the independent Rust core, separate server, client, MCP, converter, base-content packages, and an example game mode; dependency boundaries can be verified by building.
  • A clean installation following the README reproduces the build, tests, and A-E2E scenario. Configuration, ports, startup commands, the data directory, and obtaining the token are described explicitly.
  • Extension APIs, the protocol, package format, storage, durability guarantees, and compatibility limitations are documented; the chosen open-source license is present in the repository.
  • A release archive has been created, extracted again into a clean directory, and verified. It contains no tokens, the user's local worlds, or dependencies that must be downloaded separately.
  • The final report links to evidence for every mandatory criterion. Untested or blocked requirements are listed explicitly and are not called complete.

Items to clarify in CONTRACT.md during implementation

These decisions can be developed without stopping the first end-to-end milestone. Before accepting the corresponding part of the complete MVP, they must become explicit contracts and tests:

  • Protocol version, error identifiers, package/coordinate/string limits, client recovery after a missed revision, and switch_world semantics.
  • The point of durable acknowledgement, replay with different arguments, undo conflicts, the revision after reset, and history format and retention.
  • The exact 26.2 catalog source, shape and state schemas, the entity catalog and persistence, and additional block data.
  • Package format, dependency graph, server resource publication, module interfaces and execution limits, and launcher integration.
  • Arena settings, permitted actions, timers, draws, player disconnection, and match persistence policy.
  • Import/export formats and commands, preservation of unsupported data, and a machine-readable loss report.
  • The overall RAM budget, limits beyond the section cache, target load, and reproducible benchmark parameters.