• v0.3.0-beta.7 6df57fecc1

    Piratecraft 0.3.0-beta.7
    Some checks failed
    buildbot/nix-eval Build done.
    buildbot/nix-build gitea:matt/piratecraft#checks.x86_64-linux.client Build done.
    buildbot/nix-build gitea:matt/piratecraft#checks.x86_64-linux.client-compatibility Build done.
    buildbot/nix-build gitea:matt/piratecraft#checks.x86_64-linux.fleet-assembly Build done.
    buildbot/nix-build Build done.
    buildbot/nix-build gitea:matt/piratecraft#checks.x86_64-linux.server Build done.
    Pre-release

    mage released this 2026-08-04 15:12:53 -04:00 | 173 commits to master since this release

    Piratecraft 0.3.0-beta.7 WIP handoff

    Status refreshed 2026-08-04. This is the authoritative fresh-session handoff for
    the local Forge 0.3.0-beta.7 playtest build. Real-client
    playtesting now proves that production steering works; do not change production
    Sails force code to satisfy the still-red automated torque/steering probes.

    The manual playtest runtime is disposable. Do not spend engineering time
    protecting its world, chunks, player data, or inventory: stop it and recreate or
    wipe it when that is the smallest safe recovery. Preserve only reproducible
    source, checks, release artifacts, and logs needed to diagnose a current bug.

    Beta.6 fleet worldgen watchdog fix

    Addon 0.1.4 deadlocked during partial worldgen after scheduling Deep Sea Moray
    at (-240,61,-656). The watchdog report is
    /var/lib/hermes/workspace/minecraft/piratecraft-playtest/crash-reports/crash-2026-08-04_14.47.09-server.txt.
    The server thread held the synchronized FleetAssemblyState while a direct
    block read waited for an incomplete chunk; Worker-Main-2 needed that state
    monitor to finish template scheduling and the same chunk generation.

    Beta.6 gates each queued request with SRG ServerChunkCache.m_7131_(int, int)
    (getChunkNow) across its bounds and ocean-sampling margin. This API checks the
    completed FULL-status future with getNow and neither requests nor waits for a
    chunk. Incomplete requests retain their QUEUED key and are reconsidered once per
    tick; no source assembly scan starts until this gate passes.

    Deferred test: schedule a fleet template while one bounds chunk is in partial
    worldgen, assert the addon makes no blocking chunk request and triggers no
    watchdog, then complete/load all bounds chunks and assert one eventual accept
    attempt with exactly-once assembly.

    Beta.6 then preserved a static Phantom Leviathan because its actual ship set has
    two connected components. Earlier successful evidence already recorded this
    template as exactSetComponents=2; connectivity is therefore informational,
    not a conversion gate. Beta.7 removes that final rejection while retaining the
    nonempty-set and helm/controller/sails/buoy/ballast checks.

    Latest playtest incident and fixed boundary

    The public v0.3.0-beta.1 playtest server crashed when SolarHorizon
    teleported to the located pirates_sails:ship at [-608, ~, -1376]. Vanilla
    jigsaw generation loaded the official Anetum Contatum helm into a proto-chunk,
    then called BaseHelmBlockEntity.setChanged() while its level was intentionally
    null. Sails 0.3.2 dereferenced that null before the addon's existing
    StructureTemplate RETURN injection could schedule assembly.

    The beta.2 source fixes that boundary with a scoped redirect in
    StructureTemplatePlacementMixin: skip only the final setChanged() call for
    an unbound Sails helm in one of the addon's 11 known fleet templates, and
    forward every other call unchanged. No template bytes, helm NBT, ordinary live
    helm behavior, or upstream JAR are changed.

    Current evidence:

    • packages.x86_64-linux.pirates-sails-compat passed in 8.970 seconds.
    • New checks.x86_64-linux.sails-worldgen forced real fixed-seed jigsaw chunk
      generation and passed in 33.968 seconds. It reached scoped-template and
      post-placement scheduling markers with no NPE, tick crash, or mixin failure.
    • The beta.1-era runtime addon 0.1.0, SHA-256
      efdc75bf126d6046cefc6f455a223146b91415ebcdc60b2a332725fd0ceb2dce, was
      deployed to the disposable playtest server with fleet worldgen restored.
    • The same natural structure at [-608, 61, -1376] completed as ship ID 12:
      1,248 blocks, 41 block entities, 149 sails, six crew spawners, one helm,
      20 stable physics ticks, clean staging, and exactly-once assembly.
    • The server remained healthy after generation and is running on port 25565.

    This closes the helm proto-chunk crash only. It does not resolve the independent
    automated P0 rotational torque discrepancy. After the fixed runtime deployment,
    the user joined with a real client, visited the naturally generated Anetum
    Contatum, confirmed that the ship works, and reported that it steers perfectly.
    Treat production natural steering as a manual pass and the red steering probes
    as a harness/control discrepancy, not as authority to alter working gameplay.
    The published v0.3.0-beta.1 .mrpack predates the worldgen fix and remains
    unsafe for single-player natural fleet worldgen until a replacement artifact is
    built and published; its existing client is compatible with the fixed remote
    server at that incident checkpoint because no protocol, registry, mod version,
    or client behavior had changed.

    Deferred regression: VS entity-section mutation crash

    Manual beta.2 testing reproduced a client crash twice near an assembled ship:

    • Initial crash log: https://mclo.gs/j7077Fb.
    • Immediate reconnect crash: https://mclo.gs/qEtazXA.

    Both fail on the render thread with ConcurrentModificationException while
    Minecraft iterates an EntitySection list modified by Valkyrien Skies' shipyard
    entity path. The first occurred during crosshair raycasting through
    ProjectileUtil/GameRenderer. The second occurred while a dropped
    ItemEntity used VS ship collision during its tick. No Sails unfurl method
    appears in either stack; unfurling was incidental or only an external trigger.

    Beta.3 addon 0.1.2 adds EntitySectionSnapshotMixin. It redirects the exact
    iterators in both SRG entity-query overloads, m_260830_ and m_188348_, to an
    ordered ArrayList snapshot. Consumer ordering, AABB/type filtering, and abort
    semantics remain unchanged, while reentrant section mutations affect only the
    next query. The addon build and client startup smoke pass; manual in-world
    reproduction is the current validation.

    Beta.3 snapshot construction still failed because it iterated the live
    collection; beta.4 uses backing-list toArray() before iterating the snapshot.

    Beta.5 removes exact runtime block/BE/set validation and destructive rollback by
    user direction. Future fleet tests must assert that pre-assembly failure leaves
    the complete static structure intact and produces no item drops.

    Deferred automated test: construct an EntitySection query whose consumer
    adds/removes or moves an entity in the same backing section while iteration is
    active. Exercise both untyped and typed overloads, require no CME, verify the
    query sees the pre-mutation snapshot in source order, and verify immediate
    ABORT behavior. Also cover the dropped-item collision and client raycast call
    sites if a small in-world fixture is practical. Do not replace this with a
    title-screen-only test.

    Current baseline: zero-override layered control

    This is the current controlling evidence and supersedes custom-pack or Antelope
    results as the first diagnostic boundary. Every run used an exact fresh game
    root with upstream JAR bytes and generated defaults. No tracked or supplied
    config, defaultconfigs, Paxi, policy datapack, custom addon, Sails bridge,
    content mods, client mods, operations mods, or production world entered any
    test root.

    Exact reached roots:

    • Layer A decisive root:
      /tmp/piratecraft-baseline/roots/layer-a-pass.
    • Layer B initial timing root: /tmp/piratecraft-baseline/roots/layer-b.
    • Layer B post-freeze root:
      /tmp/piratecraft-baseline/roots/layer-b-post-freeze.
    • Layer B decisive active-fixture root:
      /tmp/piratecraft-baseline/roots/layer-b-active.

    Layer results:

    • Layer A PASS: Forge 47.4.10 only reached Done (21.705s), accepted
      stop, saved all dimensions, and exited cleanly in 53 seconds.
    • Layer B FAIL: exact official VS 2.4.11 plus mandatory KFF 4.12.0
      successfully assembled one connected 2x2x2 stone cube through
      ShipAssembler.assembleToShip(ServerLevel, Set<BlockPos>, 1.0) before the
      rotational control failed.
    • The assembled ship remained stable in all/loaded/PhysShip, dynamic and
      awake, with server mass 20000.0, physics mass 20000.0, finite centers of
      mass, and all 8/8 source blocks removed.
    • After the generated five-second ship-load freeze, the dimension-aware
      physics-thread listener made exactly 12 bounded pure-Y torque calls with
      (0,5000,0). Observed quaternion angle, yaw change, and Y angular velocity
      remained exactly qAngle=0.0, yawChange=0.0, and omegaY=0.0.
    • No VS config was supplied or changed. Generated defaults included
      synchronizePhysics=false, physicsTicksPerGameTick=3,
      physicsBackend=KRUNCH_CLASSIC, and shipLoadFreezeSeconds=5.0. The VS
      generated config hashes were identical across all three fresh Layer B roots.
    • Layers C, D, and E were not run by design. Do not test Eureka, Sails, or
      Pirates until minimal VS stone torque control is understood.

    Exact artifact SHA-256 values:

    • Forge 47.4.10 universal:
      bb2f67fc423f09c30ac3d83ab629fa5cc6743a0ce1c2febae46602530f17c8f1.
    • Forge 47.4.10 server:
      1dcf74ad4961877f5c79d29b361596fd4222c8849f6db31fbcf663d1ba5ff072.
    • VS 2.4.11:
      f99f24de62015451a047f90484cf9d25970cac350105b581c22b2d5247ebfd53.
    • KFF 4.12.0:
      6a66c6a68ec09f8717cdbf06883394f0ee24d7cd826b7134a0f81839e8e720ae.
    • Check-only torque instrumentation:
      d0b410fc2179ff8f5b5eb232a0cf994afd13fd4d135e3f0b3e6a38905703804c.

    The complete concise evidence, method signatures, generated-default snapshots,
    and hashes are at /tmp/piratecraft-baseline/logs/README.md.

    This zero-override result proves only that the check-only minimal control does
    not observe rotation through its current invocation/observation path. Real-client
    production play now contradicts using that result as a gameplay blocker. It does
    not prove VS or production steering is broken: the check-only torque
    invocation, listener lifecycle, and observation method must be compared with the
    working natural path before assigning any upstream conclusion.

    The next exact action is one isolated diagnostic with only
    synchronizePhysics=true. If rotational response remains unchanged, prepare a
    minimized upstream report. In the same P0 investigation, verify the
    ShipPhysicsListener attachment and call lifecycle, including torque enqueue
    and drain timing, before blaming VS.

    Stop rule: do not change working production force/steering behavior to make
    the minimal control green. Continue manual gameplay validation. Investigate the
    automated discrepancy only in check-only code with bounded runs.

    Goal and hard gameplay requirements

    The release is a pirate RPG built around real physics ships. All of these are
    hard requirements, not optional polish:

    • Players must have free movement on ships rather than being locked into a
      vehicle seat.
    • Ships must be customizable and block-built, or at minimum substantial
      prefabs that players can materially alter.
    • Non-builders must be able to purchase useful ship templates through the
      progression/economy loop.
    • Ships need NPC or presentational crew. Players must be able to substitute for
      crew at meaningful stations rather than merely ride as passengers.
    • Technology is sailing-era only. Steam engines, propellers, powered airships,
      and other modern propulsion are forbidden.
    • Boarding, fighting aboard moving ships, and commandeering captured ships are
      mandatory.
    • Repair must be inexpensive enough that players use ships and accept naval
      combat instead of treating every damaged hull as a total loss.
    • The pack needs substantial ship, encounter, route, and progression variety.
    • A hostile PvE pirate fleet is mandatory. Decorative stationary wrecks or
      player-only ships do not satisfy this.
    • Cargo transport and a meaningful progression loop are mandatory.
    • Custom code remains a last resort. It is now authorized narrowly for Sails
      fleet assembly because the shipped Pirates/VLib path does not reliably admit
      the Sails templates as active VS physics ships. Do not expand the addon into
      unrelated gameplay or replace upstream behavior without a separately proven
      need.

    Subjective economy, repair cost, progression speed, cannon balance, encounter
    density, and ship-handling feel remain the user's decisions. Automation should
    report measurements and candidate values, not silently choose the balance.

    Architecture decision

    This branch is migrating away from the released public 0.2.0-beta.2 stack on
    Minecraft 1.21.1, NeoForge 21.1.228, and Sable 2.0.3. The WIP target is
    Piratecraft 0.3.0-beta.2 on Minecraft 1.20.1, Forge 47.4.10, and Java 17.

    The exact pinned core stack is:

    Component Version
    Valkyrien Skies 2.4.11
    Eureka 1.6.3
    Valkyrien Sails 0.3.2
    Valkyrien Pirates 1.9.3
    VLib 0.1.1
    Kotlin for Forge 4.12.0
    Create 6.0.8
    Create Big Cannons 5.11.4
    Ritchie's Projectile Library 2.1.1

    The progression and prefab direction is FTB Quests/Teams/Library, Bountiful,
    Lightman's Currency, Building Gadgets 2, MineColonies, Stylecolonies,
    Structurize, Domum Ornamentum, BlockUI, Multi-Piston, and TownTalk. These
    provide quest/progression, contracts, currency, construction assistance, and
    substantial settlement prefabs. Purchasable ship-template economy and final
    quest content are not implemented yet.

    Retained pirate and world content includes Treasures of the Dead, Illager War
    Trireme, Dungeons and Taverns, Tectonic/Lithostitched, Lootr, Better Combat,
    Farmer's Delight, Ocean's Delight, Create Big Cannons, MineColonies cove
    content, JEI, Jade, Xaero's maps, Controlling, and Mouse Tweaks. Chunky and
    spark remain server-only operations tools.

    Removed from the WIP stack are Sable, Create Aeronautics, Jade Sable Compat,
    and the top-level Cloth Config metafile. Cloth Config may still appear as a
    nested upstream JarJar dependency; that is different from restoring the removed
    top-level mod.

    Repository constants currently assert:

    • 46 upstream Packwiz mod metafiles.
    • 39 upstream server-applicable mods and 44 upstream client-applicable mods.
    • The only upstream server-only mods are
      mods/Chunky-1.3.146.jar and mods/spark-1.10.53-forge.jar.
    • 84 indexed static policy/config files.
    • The first-party addon is pirates-sails-compat version 0.1.1 for beta.2,
      artifact pirates-sails-compat-0.1.1.jar.
    • Runtime totals after adding the addon are 40 server JARs and 45 client JARs.
      The client smoke adds HMC-Specifics as a 46th top-level test JAR.
    • The addon packages exactly 11 unmodified official Sails fleet templates and
      redirects Pirates worldgen to those templates. It is not yet integrated into
      every distribution surface; that is P4.

    Git and release state

    • Repository: /var/lib/hermes/workspace/minecraft/piratecraft.
    • Branch: master, tracking origin/master.
    • master and origin/master are synchronized at 315e675.
    • v0.2.0-beta.2 remains the last Sable release. Forge WIP prerelease
      v0.3.0-beta.1 is public at
      https://git.matt.you/matt/piratecraft/releases/tag/v0.3.0-beta.1.
    • The public Forge asset SHA-256 is
      923f990f0d142ec8c8aeec3a5b472aadf9727de526e0d9eba8a6c890f412fdd4.
      It predates the beta.2 helm worldgen fix above; do not present it as
      fixed or production-ready.
    • v0.3.0-beta.2 is being prepared and has not been published. The validated
      Prism artifact SHA-256 is
      ec393e8e1fe9e5af00334d35bfa6794808094450990d212ddbf5b9607dd98a72;
      do not invent a release commit ID before the commit exists.
    • Current intentional source changes include the scoped placement redirect, the
      sails-worldgen regression in flake.nix, and beta.2 release metadata.
      .tmp-psc/ is generated research and must not be staged.

    Forge migration commits now pushed to origin/master:

    Commit Purpose
    dcadb2f WIP Forge migration and sailing-era policy
    ece671a WIP Sails compatibility layer
    7b5e6ca WIP Sails fleet conversion prototype
    d2800a2 WIP production fleet assembly through VS ShipAssembler
    e6ce6c7 WIP isolated Sails steering blocker
    315e675 Recorded zero-config VS baseline

    The helm worldgen fix and its regression check are included in the beta.2
    release candidate. Read git log -1 and the remote release state for the exact
    commit/publication status rather than embedding a self-referential commit ID.

    Evidence status

    Evidence classifications matter:

    • Current green means it applies to the implementation captured by this
      checkpoint or to unchanged migration inputs with a current source-dependent
      check.
    • Focused boundary means a current focused check stops at one documented
      assertion after its earlier assertions pass. For beta.2, fleet-assembly
      currently stops at wind propulsion before reaching steering.
    • Historical, rerun required means a prior result was useful research but
      later addon/probe/harness changes invalidate it as release evidence.
    • Generated evidence under .tmp-psc/, logs, and result links is deliberately
      excluded from Git. Paths below identify local research only and are not
      release artifacts.

    Artifact integrity and packaging

    • Current green: official VS and HMC artifacts are used without class/JAR
      rewriting. VS is fetched as official
      valkyrienskies-120-2.4.11.jar, Packwiz SHA-512
      6a0d959ed4bf76f08dcad0e6a360bda842d85386a05f510069eafbcc6b46b4216cdcfd9e377f82e4266b0f07e6b74118d8382af0bafcbdd65712f8a92f16e146
      and Nix SHA-256 sha256-+Z8k3mIBVFGgR/kEhM+dJZcMrDUBBbWBwistUkfr/VM=.
    • Current green: HMC-Specifics is the official Forge 1.20.1 1.2.2 artifact,
      Nix SHA-256 sha256-APWQ+CAvNQ36NUKxiwsxs0C115v6KB2uDulBKrsnhMw=.
      HeadlessMc launcher 2.10.0 is pinned at
      sha256-Ur1QBvR4N3s4kwEdRYVil304xl6tbSsxCJvrTWFPE80=. The harness normalizes
      HeadlessMc's generated Forge version directory/JSON ID, but does not patch VS,
      HMC-Specifics, Minecraft classes, or any runtime mod JAR.
    • HMC-Specifics 2.4.0 is not the Forge 1.20.1 artifact. Its relevant release is
      for Minecraft 1.20.6/Forge 50 and Java 21, so it is loader/game/JVM
      incompatible with this Minecraft 1.20.1/Forge 47.4.10/Java 17 stack. Use the
      exact hmc-specifics-forge-1.20.1-1.2.2.jar pin.
    • Current green from local exact-Forge evidence: the 1.20.1 Forge client reached
      net.minecraft.client.gui.screens.TitleScreen under Xvfb and Mesa llvmpipe,
      with HMC-Specifics 1.2.2, and exited cleanly. The harness checks the
      Multiplayer button, exact title-screen class, shader loading, software
      renderer, clean quit, and exit zero. A representative generated path is
      .tmp-psc/admission-run-5/client-output/startup.log; do not commit it.
    • Current constants: serverPackHash is
      sha256-yU5n/OpDBZFPCI/iVGlSJXw/0vZCxtmWoDJnd5Ks7W8=, clientPackHash is
      sha256-3BOs9US7k6Mm9gZZ0yuktHfhK1gBsAAZHqcG4W8OzyE=, the prepared Forge
      server hash is sha256-Hj0aUhxqbiKWd9xl+p4ojRS3gLlTduCYUxbYN+aHlfs=, the
      prepared client-files hash is
      sha256-/yMfyCEoMln+Nlv5+cduXOWJBdXuVxphfjz//XshsEQ=. The beta.2 Prism
      recursive output hash is
      sha256-dber1qNs0zlnCgtsVkXJz9cNkvMcmAhW1/Ws4TB2BnY=.
    • Current green: checks.x86_64-linux.metadata and
      checks.x86_64-linux.module have valid outputs for the current source. The
      metadata check verifies pack.toml, all 46 metafiles, and all 84 static
      files. The module check proves consumer EULA gating, consumer override
      precedence, TCP-only firewall behavior for Forge, the exact runtime symlink
      map, and forced world-local Eureka policy materialization.
    • Current packaging contract in source: Packwiz/Prism resolves all 46 upstream
      downloads, marks exactly Chunky and spark unsupported on clients, includes 84
      static overrides, embeds only the deterministic first-party addon JAR, and
      rejects embedded third-party JARs, duplicate/unsafe paths, missing/extra
      manifest sources, and check-only probe assets. The addon is injected into the
      Nix server/client runtime and .mrpack; P4 must rerun Prism and verify the
      Packwiz site and all distribution surfaces after final addon integration.
    • Historical, rerun required: old beta.2 Prism, compatibility, and full-flake
      results describe 37 mods/four overrides on NeoForge and do not validate this
      migration. Do not cite those old counts as Forge green.

    Forge startup and dependency behavior

    • Current migration runtime evidence: Forge 47.4.10 starts cleanly, reaches
      Done, accepts stop, saves worlds, and reports All dimensions are saved.
      Representative exact Antelope admission evidence is
      .tmp-psc/admission-run-9/server.log: startup Done (8.270s), clean stop,
      and complete save. Generated logs are excluded from Git.
    • The Forge package copies 58 direct launcher-argument JARs plus required
      extras and asserts exactly 65 library JAR files. It runs Java 17 through the
      prepared official Forge server arguments.
    • Production runtime count is 40 top-level server mods including the addon.
      A check-only run adds one probe for 41. Current generated server evidence has
      Forge/JarJar discovering 31 nested dependencies. Production client runtime is
      45 top-level JARs; HMC-Specifics makes 46 in the smoke, and generated client
      evidence discovered 26 nested JarJar dependencies.
    • The static client-compatibility checker parses Forge JarJar metadata,
      resolves intersected ranges and one selected candidate per coordinate,
      rejects conflicts and unavailable candidates, verifies FML language
      providers/dependencies and Java 17 class compatibility, and reports exact
      top-level, selected nested, mod-ID, and class counts. Its exact latest output
      was not retained after the final steering edits, so rerun this short static
      check before release rather than inventing selected-candidate counts.
    • Current green release-candidate evidence includes the addon, client, client
      compatibility, client smoke, metadata, module, Prism, sails-worldgen, and
      standalone policy surfaces. server and fleet-assembly are red at their
      wind-movement gates, so do not describe a full current nix flake check as
      green.

    Sailing-era policy

    • Current policy denies every Eureka engine recipe and every balloon color/base
      recipe, Create's steam engine and propeller, CBC autocannon/modern shell
      paths, and selected modern Lightman's machines. It retains Eureka helms,
      floaters, and anchors; basic Create shafts/cogwheels/fans/schedules; sailing-
      era CBC cast-iron/bronze cannon manufacture, solid shot, grapeshot, powder
      charges, loaders, and fixed mounts; and low-tech currency items.
    • Physical enforcement is not recipe-only. World-local Eureka policy forces
      enginePowerLinear=0, enginePowerLinearMin=0, massPerBalloon=0,
      maxBalloonsPerEngine=0, and
      allowFloatersAndBalloonsOnNonEurekaShips=false. Water floaters remain
      available. Sails uses wind, disables aerodynamic wind on unsailed ships,
      keeps ballast buoyancy at 0, water buoy strength at 0.125, and currently
      tracks realistic-rudder=true in production config. The focused check also
      proved the blocker persists with realistic-rudder=false.
    • The recipe probe asserts both denied and allowed controls. Lightman's denied
      recipes use exact-ID forge:conditional wrappers containing forge:false,
      whose serializer returns no recipe. Do not add a broad
      lightmanscurrency namespace pack filter: namespace filtering also removes
      unrelated low-tech currency recipes and cannot express the desired selective
      policy safely. The exact conditional override per denied recipe ID is the
      working solution.

    Historical custom-pack ship assembly and Sails registration

    • Historical custom-pack finding, not the current zero-override baseline: a
      check-only minimal stone control calls
      ShipAssembler.assembleToShip(ServerLevel, Set<BlockPos>, 1.0). It removed
      all 8 source blocks and reached active, loaded, finite-inertia PhysShip
      admission. Generated run 7 observed a maximum stable span of 22 ticks and
      passed.
    • Historical custom-pack finding, not current green: an unchanged official
      52x39x14 Sails Antelope with exactly
      1,594 non-air blocks was submitted as one exact set to the same API and
      reached active, loaded, finite-inertia PhysShip admission. Generated run 9
      passed all 40 observation ticks with all 1,594 blocks unchanged.
    • Historical custom-pack finding, not current green: FleetAssemblyState
      queues duplicate scheduling exactly once,
      places into a bounded checked ocean staging volume, validates every expected
      transformed block, invokes VS ShipAssembler, cleans staging, waits for 20
      stable physics ticks, and persists completion. It suppresses a completed
      duplicate and rolls an obstructed request back without deleting or mutating
      the valid ship.
    • Exact generated assembly evidence from fleet wrapper run 4: 1,594 blocks, 45
      block entities, mass 842729.0299998736, one connected exact set, one helm,
      533 sails, 10 crew spawners, compat 1, zero staging residue, then an
      obstruction rollback with zero world blocks, zero block entities, zero
      pending entries, one valid completed ship, and the valid 1,594-block/45-BE
      ship unchanged. The focused runtime completed in 2,606 ms. This run predates
      later natural-steering assertions but remains assembly evidence because that
      implementation path is preserved in this checkpoint.
    • Historical custom-pack Sails census for Antelope: 533 functional sail blocks,
      168 square sails, 283 fore-and-aft sails, 82 unclassified sail blocks, 37
      buoys, 24 ballast blocks, 1 magic ballast, 1 Sails helm with wheel block
      entity, and exactly one Pirates motion controller with compat=1.
    • Historical custom-pack boundary evidence: natural Sails wind, with no
      synthetic test force,
      moves the Antelope by more than 0.5 blocks cumulative, net, and maximum
      displacement. The focused probe disables aerodynamic wind, supplies a
      deterministic natural Sails wind rule, requires nonzero wind, observes real
      physics samples, and proves the sail force path before enabling Pirates AI.
    • Historical custom-pack boundary evidence: Pirates AI creates a
      SeatedControllingPlayer,
      emits exact forward impulse 1 and discrete nonzero steering impulse, and the
      Sails helm wheel changes after the impulse. There are no players and no probe-
      generated control impulses in this phase.
    • Historical custom-pack focused failure: one earlier run reached emitted AI
      controls and helm-wheel response before observing zero yaw and Y angular
      velocity. The current beta.2 fleet-assembly run does not reach that
      assertion: it fails earlier at NATURAL_WIND_PROPULSION_WITHIN_180_TICKS.
      The current server probe likewise times out in its natural crew/AI movement
      phase after only 0.157 blocks of cumulative movement. Both conflict with the
      successful real-client movement and steering result and remain red harness
      discrepancies.

    Historical integration results that are not current green

    The two-boot server probe contains assertions for natural crew spawn, cargo
    barrel/block-entity state, natural capture/disarm, cannons, movement, exact ship
    ID, Sails/controller persistence, staging cleanup, and bounded orphan scans.
    Those behaviors passed in earlier iterations, but later assembly, connected-
    client, wind-bridge, and steering-harness changes invalidate the results as a
    current release claim. Treat them as test design already present, not current
    evidence. P2 must rerun them naturally after P0/P1 and must not weaken their
    assertions merely to regain green.

    Current blocker and stop rationale

    The current production-release blocker is reliable automated movement/steering
    coverage, not a demonstrated gameplay failure. Real-client natural Anetum
    movement and steering pass, while the current integrated probes observe too
    little wind movement and the zero-override Layer B stone control observes no
    rotation. Keep investigation check-only and reconcile those observation paths
    with working gameplay before assigning an upstream or production-code defect.

    The following are historical custom-pack findings. They motivated the minimized
    baseline but are not evidence that the custom pack is the current failure cause:

    • Production realistic-rudder=true did not rotate.
    • Focused realistic-rudder=false did not rotate.
    • Multiple Sails rudder force-pair capture/replay experiments did not rotate.
    • Replaying force pairs through direct PhysShipImpl model-force methods did
      not rotate.
    • Replaying through GameToPhysicsAdapter did not rotate.
    • Final independent control bypassed Sails calculations entirely: direct
      PhysShip.applyWorldTorque and GameToPhysicsAdapter.applyWorldTorque, with
      torque (0, 100000, 0) for four physics samples, rotated neither the minimal
      stone ship nor Antelope.

    The zero-override result now independently places the research boundary below
    Sails. More Sails coordinate, rudder-power, force-pair, AI, or Antelope runs
    would repeat the same unproven backend and listener-lifecycle assumptions.

    The exact next research boundary is check-only instrumentation:

    1. Run one fresh-root diagnostic with only synchronizePhysics=true; change no
      other generated default or runtime input.
    2. Verify the check-only ShipPhysicsListener attachment and official
      successful listener/call lifecycle on the minimal stone ship.
    3. Trace PhysShipImpl.applyWorldTorque through applyQueuedForces, including
      exact ship, world/dimension, queue insertion, queue drain, and observation
      ordering, without changing production behavior.
    4. If synchronized physics still yields zero response, prepare a minimized
      upstream report with the zero-override evidence.
    5. Only after minimal stone rotation passes, return to Sails coordinate frames,
      model/world force positions, and the server-to-physics bridge.

    Do not add a production synthetic torque, kinematic yaw target, teleport-based
    steering, or custom autopilot to hide the failure.

    Ordered next steps and exit criteria

    P0: Zero-override VS torque lifecycle

    • Reclassified after manual production steering passed: this is a check-harness
      discrepancy, not a proven gameplay or release blocker. Keep all investigation
      check-only and lower priority than manual gameplay failures.
    • Work only in check-only probe/instrumentation code first.
    • First run exactly one fresh-root diagnostic with only
      synchronizePhysics=true; do not add Eureka, Sails, Pirates, policy, config
      beyond that one diagnostic value, or the custom addon.
    • Attach and verify a ShipPhysicsListener on the admitted 2x2x2 stone control,
      and compare its lifecycle with an official successful force/torque caller.
    • Trace PhysShipImpl.applyWorldTorque through applyQueuedForces, including
      ship ID, listener lifecycle, queue insertion, queue drain, physics sample,
      angular velocity, and yaw.
    • Pass: bounded pure-Y torque samples are observed entering and leaving
      the correct backend queue, and the minimal stone ship produces finite,
      nonzero Y angular velocity followed by measurable yaw while remaining loaded
      and dynamic.
    • Fail: the call is absent, attached to the wrong ship/world, queued after the
      drain, discarded, or consumed without angular response. Stop at the first
      failed layer and investigate that layer only.
    • Exit: a deterministic focused control passes repeatedly within 60 seconds,
      the listener/call lifecycle is explained, and no production addon behavior
      changes. If the synchronized-only result is unchanged, prepare the minimized
      upstream report before any broader run.

    P1: Natural steering

    • Manual pass: a real client steered the naturally generated production Anetum
      Contatum successfully after the worldgen fix. Preserve that working path.
    • Repair or replace the automated natural-steering observation only after
      comparing it with the manually working path; do not gate further manual
      playtesting on the minimal stone control.
    • Validate Sails force coordinate frames and the server/physics bridge; use
      normal Pirates AI controls and Sails helm/rudder behavior, not a synthetic
      steering force.
    • Pass: AI emits nonzero steering, wheel response follows, Antelope translation
      remains greater than 0.5, nonzero angular response follows the impulse, yaw
      changes in the expected direction, and the focused
      fleet-assembly check passes within 60 seconds.
    • Fail: any synthetic production force is required, yaw precedes input, rotation
      is unstable/non-finite, the ship loses blocks/BEs, or assembly/rollback
      regressions appear.
    • Exit: restore the production realistic-rudder=true test path and prove it;
      do not ship a check-only false substitution as the fix.

    P2: Natural crew, capture, cargo, and two-boot persistence

    • Run the integrated server probe with a real connected fixture client.
    • Require naturally spawned hostile crew, natural helm-controller linkage,
      kill/removal-driven capture and controller disarm, intact player-substitutable
      Sails helm, cargo marker in a real container block entity, cannon BE presence,
      clean save/stop, same ship ID and exact contents on boot 2, and bounded orphan
      absence.
    • Pass: every current boot-1 and boot-2 marker in flake.nix passes under the
      180-second integrated deadline with no duplicate fleet, orphan, loss,
      non-finite state, or probe-only production asset leak.
    • Fail: scripted state mutation substitutes for natural behavior, cargo or
      capture state is lost, IDs duplicate/change unexpectedly, or the test passes
      only by weakening assertions.
    • Exit: one fresh two-boot world passes from an exact staged snapshot.

    P3: Production worldgen and all variants

    • Current partial pass: natural Anetum Contatum jigsaw generation now crosses
      the former unbound-helm crash point and completes exactly once as a stable
      physics ship. The dedicated sails-worldgen check covers placement and
      scheduling; the disposable live runtime additionally reached assembly
      completion. This is evidence for one variant, not completion of P3.
    • Exercise the redirected Pirates structure set and all 11 supported unmodified
      Sails templates: Anetum Contatum, Antelope, Barnacle Hopper, Deep Sea Moray,
      Hispaniola, Midnight Barracuda, Queen Anne's Revenge, Revenge, The Heart
      Attack, The Phantom Leviathan, and Whydah.
    • Include negative controls for Eye of Horus, Whydah Ghost, Eureka template
      requests, unrelated templates, obstructed staging, duplicates, and non-ocean
      placement.
    • Pass: naturally generated supported variants each assemble once as stable
      physics ships with sails, buoyancy, helm, crew/controller, cargo/cannon BEs,
      clean staging, and no unsupported generation.
    • Fail: any supported variant is stationary/decorative, malformed, missing
      required stations/content, duplicated, or able to bypass sailing-era policy.
    • Exit: exactly 11 supported variants and every negative control are proven.

    P4: Exact addon distribution integration

    • The addon is present in the published server/client/Prism surfaces, but the
      public v0.3.0-beta.1 bytes predate the helm worldgen fix. Repeat exact-byte
      integration checks for a replacement artifact after the source fix is
      committed.
    • Integrate the deterministic addon exactly once into server runtime, client
      runtime, .mrpack, Packwiz site/update delivery, and any production module or
      hosted installation path. Keep check-only probes absent.
    • Pass: fresh source-dependent metadata, client compatibility, Prism validator,
      module, standalone policy, client smoke, server, and addon isolation checks
      pass; the addon bytes are identical on every surface; no third-party JAR is
      embedded; 46 upstream sources/39 server/44 client/84 static counts remain
      exact unless deliberately reviewed and updated.
    • Fail: a distribution path lacks the addon, contains two copies, contains
      generated probes/logs, leaks official third-party JARs, or depends on a local
      Nix store path at recipient install time.
    • Exit: validate from a fresh checkout/source NAR and a native Prism import, not
      only an existing local runtime tree.

    P5: Documentation, version, release, and CI

    • Keep public README, technical status, configuration, and playtest docs honest
      about the Forge/VS/Sails WIP and the still-red automated wind-movement
      boundary.
    • Prepare v0.3.0-beta.2 with addon 0.1.1 as the replacement prerelease, but
      do not describe it as published before the fix is committed and packaged.
      Keep broken historical artifacts and Sable beta.2 accurate.
    • Update CI/check discovery for the ten current checks: client,
      client-compatibility, client-smoke, fleet-assembly, metadata,
      module, prism, sails-worldgen, server, and standalone-policy.
    • WIP prerelease pass: the crash fix, client startup, packaging, policy, and
      worldgen regression are green; the artifact has a reviewed hash; and release
      notes explicitly disclose red automated checks and incomplete manual gates.
    • Production pass: full local flake check and CI pass from the release commit,
      all objective/manual gates pass, and every supported delivery surface contains
      the exact addon bytes.
    • Fail: docs claim stale green evidence, CI skips or conceals red checks, hashes
      are guessed, or an incomplete WIP is presented as production-ready.

    P6: Manual gameplay and balance

    • Complete the manual gates below, then tune economy/templates, ship variety,
      repairs, cannons, cargo rewards, crew presentation/stations, encounter
      spacing, and progression under user direction.
    • Pass: every hard gameplay requirement at the top of this file has observed
      multiplayer evidence and the user accepts subjective handling/economy.
    • Fail: automation chooses subjective balance, PvE fleet is decorative, repair
      discourages use, templates make building irrelevant, or forbidden propulsion
      remains obtainable/effective.
    • Exit: user signs off on balance after objective gates pass.

    Stop rules and diagnostic budgets

    • Manual Sails/Pirates gameplay may continue because real-client production
      steering passed. Do not make production force changes based only on the red
      minimal stone or automated steering controls.
    • Focused diagnostics have a hard per-run timeout of 60 seconds.
    • Integrated/two-boot tests have a hard per-run timeout of 180 seconds.
    • There is no arbitrary attempt-count limit. Continue while each run produces
      meaningful new top-level evidence.
    • Stop when repeated runs make no meaningful top-level progress, when the same
      unproven assumption is being exercised through cosmetic variants, or when a
      lower-layer independent control fails. Write the new boundary before trying
      another implementation.
    • Never weaken an exit criterion to turn red into green. Separate a smaller
      control instead.
    • Do not run Minecraft, long tests, releases, or pushes merely to inspect code.

    Known upstream and data issues

    • Sails 0.3.2 BaseHelmBlockEntity.setChanged() assumes a non-null level,
      unlike vanilla BlockEntity.setChanged(). Vanilla jigsaw worldgen can validly
      call it on a proto-chunk block entity before level assignment. Piratecraft's
      compatibility redirect is deliberately limited to unbound Sails helms in the
      11 scoped fleet templates; retain the sails-worldgen regression if this
      integration changes.
    • VS 2.4.11 emits one
      InvalidInterfaceMixinException for the non-public sculk/vibration
      destWorldPos interface mixin. Current harnesses require exactly that known
      signature and treat it as non-fatal. Any additional mixin exception or
      accompanying behavior failure is new.
    • Pirates' Eureka templates can spawn as decorative/stationary structures under
      the no-engine/no-balloon policy. They do not satisfy the mandatory PvE fleet.
      Worldgen is redirected to Sails templates instead.
    • Pirates controller compat=0 has an upstream NaN path. Do not use compat 0 as
      a neutral fallback. Supported Sails fleet templates are audited at
      compat=1; their Eureka counterparts are compat 2.
    • Pirates bundles 13 Sails ship templates, but its bundled Sails data is
      inactive/mispackaged for this runtime path. Eye of Horus has no Sails helm and
      is excluded. Whydah Ghost contains malformed loot table
      pirates:/barrels/cartographer and is omitted without mutating upstream NBT.
      Exactly 11 variants are supported.
    • VLib 0.1.1's immediate direct ship-creation path races finite mass/inertia.
      Prior observer logic also produced a false cross-dimension observation. The
      addon therefore does not copy VLib code or call VLib direct ship creation; it
      stages an exact set, calls the same public VS ShipAssembler path as Sails'
      Dedication Bottle, waits for stable admission, and checks the exact physics
      dimension.
    • Lightman's selective recipe removal cannot be implemented with a broad pack
      namespace filter without suppressing retained currency content. Use exact
      same-ID forge:conditional/forge:false overrides for denied recipes.
    • Building Gadgets logs an unrelated malformed book recipe in current upstream
      data. Do not confuse it with the Lightman's conditional skip messages; review
      separately before release if it affects gameplay.
    • Forge/Mojang prepared client and server closures have licensing/cache risk.
      Fixed-output/local-builder preferences are not publication controls. CI and
      cache operators must exclude Mojang/Forge prepared client/server closures and
      smoke runtime closures from public binary-cache upload. They must never enter
      Git or release archives.

    Commands and workflow

    Always inspect the exact tree first:

    git status --short --branch
    git diff --stat
    git diff --cached --stat
    git diff --check
    git diff --cached --check
    git log --oneline --decorate -10
    nix flake show --all-systems
    

    Use explicit path:$PWD flake references so an accidental parent flake or
    registry entry is not tested. Remember that a working-tree path: test and a
    staged-index test are different. Before claiming a checkpoint, inspect
    git diff --cached and test an exact index snapshot when practical:

    snapshot="$(mktemp -d /tmp/piratecraft-staged.XXXXXX)"
    git checkout-index --all --prefix="$snapshot/"
    nix build "path:$snapshot#checks.x86_64-linux.fleet-assembly" --builders '' --print-build-logs
    rm -rf "$snapshot"
    

    The current focused target remains red at its wind-propulsion observation and
    does not reach steering, while manual production movement and steering pass.
    Use it only to investigate the harness discrepancy:

    timeout --signal=TERM --kill-after=10s 60s \
      nix build "path:$PWD#checks.x86_64-linux.fleet-assembly" \
      --builders '' --print-build-logs
    

    The focused natural-jigsaw regression for the fixed helm lifecycle is green and
    must remain independent of steering:

    timeout --signal=TERM --kill-after=10s 60s \
      nix build "path:$PWD#checks.x86_64-linux.sails-worldgen" \
      --builders '' --print-build-logs
    

    Static/focused checks that do not launch Minecraft:

    nix build "path:$PWD#checks.x86_64-linux.metadata" --builders '' --print-build-logs
    nix build "path:$PWD#checks.x86_64-linux.client-compatibility" --builders '' --print-build-logs
    nix build "path:$PWD#checks.x86_64-linux.module" --builders '' --print-build-logs
    nix build "path:$PWD#checks.x86_64-linux.standalone-policy" --builders '' --print-build-logs
    

    Full checks, only after focused checks are green:

    timeout --signal=TERM --kill-after=10s 180s \
      nix flake check "path:$PWD" --builders '' --print-build-logs
    

    Client smoke, Prism, updater, and formatting:

    nix run "path:$PWD#client-smoke"
    nix build "path:$PWD#prism" --builders '' --print-build-logs
    nix run "path:$PWD#update-mods"
    nix run "path:$PWD#update-mods" -- --hashes-only
    nix fmt "path:$PWD"
    

    The updater runs packwiz refresh, fixed-output hash refreshes, exact output
    builds, and a full flake check; it is not a focused diagnostic. Do not run it
    until implementation is stable. After formatting or updater runs, re-inspect
    both staged and unstaged diffs because those commands operate on the working
    tree, not the Git index.

    Use local builders (--builders '') for focused runtime/research so remote
    substitution or builders cannot hide local source and generated-fixture
    differences. Never broadly grep /nix/store; inspect a named derivation, named
    JAR, source checkout, or captured log only.

    Generated research and evidence must remain uncommitted: .tmp-psc/,
    .forge-research/, .vs-tuple-research/, .ruff_cache/, logs/, result
    links, Minecraft worlds, crash reports, generated JARs/classes, Nix tool
    outputs, credentials, tokens, and secrets. logs/ and /result are currently
    Git-ignored; .packwizignore excludes .tmp-psc/ and TODO.md from .mrpack,
    but the research directories are still visible as untracked and must be
    excluded explicitly when staging. Never use git add -A here.

    Manual gates still required

    No automated result replaces these release gates:

    • Native Prism import of the exact .mrpack, with no Packwiz bootstrap or
      custom launcher command.
    • Real-GPU launch and rendering, not only Xvfb/llvmpipe.
    • Two real clients with normal authentication joining the production server.
    • Production TCP connectivity, authentication, DNS, and normal host behavior.
    • Free movement while sailing, station substitution, boarding, melee combat,
      cannons, commandeering/capture, inexpensive repair, and cargo handling.
    • Purchasable templates and progression for non-builders without eliminating
      meaningful block-built customization.
    • Hostile PvE fleet variety and all 11 supported production variants.
    • Clean restart persistence and a backup restored into a separate writable
      server root, including world data, VS ship data, addon SavedData, cargo,
      Lootr/MineColonies state, and operational state.
    • A continuous two-hour, two-player soak covering sailing, combat, unload/load,
      disconnect/reconnect, capture, cargo, save, restart, and continued use.
    • Recipe and physical enforcement proving no craftable/effective airships,
      balloons, engines, steam engines, or propellers, including negative attempts
      with commands/loot/preexisting blocks where appropriate.

    Any NOT RUN or FAIL manual gate blocks a production release. A public WIP
    playtest prerelease may remain incomplete only when the user explicitly requests
    it and every known failure or untested gate is disclosed in its release notes.

    Downloads