Tags
Creators
Details
1.1.0
Compatibility
Required content
Changes
Changelog: v1.0.0...v1.1.0
Summary
Really Fast Paintings v1.1.0 focuses on baseline correctness, failure-safe migration and restoration boundaries, prevention of duplicate entities or orphaned helper parts, chunk-granular auditing, and regression test coverage.
๐ Bug Fixes
-
Anchor Coordinate Resolution Outside Origin:
- Fixed an issue in
PaintingPartBlock.findAnchorLookup(...)where search candidates were allocated without setting offset coordinates (defaulting to(0, 0, 0)). Multipart paintings placed away from origin now properly resolve their anchor across all 4 horizontal facings. - Implemented
AnchorLookupResult(Found,Unloaded,Orphan) to avoid treating part blocks adjacent to unloaded chunks as orphans, eliminating premature self-destruction or forced chunk loading.
- Fixed an issue in
-
Placement Order & Neighbor Updates:
- Fixed placement sequencing in
PaintingPlacementService.tryPlacePainting(...): the anchor block is placed and itsPaintingBlockEntityvariant initialized before placing part blocks, preventing neighbor-update cascades from destroying part blocks during placement.
- Fixed placement sequencing in
-
Multi-Tick Restoration Suppression Loop:
- Restored vanilla
Paintingentities are tagged withfastpaintings:restoredand tracked in an in-memory suppressed UUID set inPaintingConversionService, preventing automatic conversion listeners from immediately reconverting newly restored entities on the next server tick.
- Restored vanilla
-
Removal-Guard State Reset:
- Guaranteed that
PaintingBlockEntity.setRemoving(false)is properly reset during restoration rollback, preventing surviving anchor blocks from remaining permanently locked against future removal.
- Guaranteed that
๐ก๏ธ Safety & Recovery Improvements
-
Staged Restoration Recovery & Rollback Boundary:
- Expanded the recovery boundary in
PaintingConversionService.tryRestore(...)to begin prior to footprint removal. - Added pre-spawn footprint validation ensuring all cells are cleared of block representations before attempting entity insertion.
- Structured recovery into two distinct, independently guarded stages:
- Stage 1 (Entity Reconciliation & Cleanup): Cleans up attempted entities and clears suppression markers via
EntityCleaner. - Duplicate Representation Prevention: If entity cleanup fails and the attempted vanilla entity remains active in the level, footprint rollback is skipped to prevent duplicate representations (both active entity and block painting). Throws a location-bearing
RestorationExceptioncontaining the anchor position, preserving all failure causes. - Stage 2 (Footprint Rollback): Safely restores all footprint cells to their original block states and resets the anchor removal guard only when the entity is confirmed dead/absent from the level.
- Stage 1 (Entity Reconciliation & Cleanup): Cleans up attempted entities and clears suppression markers via
- Expanded the recovery boundary in
-
Suppression Preservation on Failed Operator Reconversion:
- Preserved restoration tags and UUID suppression when an operator explicitly runs
/fastpaintings convertand conversion fails due to an obstacle (such as custom entity data). Suppression markers are retained until conversion commits successfully.
- Preserved restoration tags and UUID suppression when an operator explicitly runs
๐ Migration & Diagnostic Commands
-
Section-Granular Chunk State Auditing:
- Implemented
PaintingMigrationCommand.scanChunk(LevelChunk)using palette prechecks (section.maybeHas(...)) and intra-section block iteration(0..15):- Counts actual
PAINTING_BLOCKstates directly (scan.anchorBlocks()). - Counts
PAINTING_PART_BLOCKhelper states (scan.helperParts()). - Separately counts instantiated
PaintingBlockEntitys (scan.anchorBlockEntities()).
- Counts actual
- Missing-BE orphan anchor states never report false clean (0 anchors).
/fastpaintings statsoutput displays:Block painting anchors: %d (BlockEntities: %d)alongside helper parts.- Guaranteed zero boundary-crossing reads into unloaded chunks during chunk scans.
- Implemented
-
Command Scope & Safe Uninstallation Documentation:
- Updated
README.mdand in-game feedback to clarify execution scopes:/fastpaintings convertevaluates loaded entities across all dimensions./fastpaintings statsand/fastpaintings restoreoperate strictly on loaded chunks around active players or world spawn.
- Added a step-by-step Safe Uninstallation Procedure to guide operators in backing up worlds, disabling conversion configs, restoring paintings in loaded chunks, and certifying 0 remaining anchors/helpers before removing the mod jar.
- Updated
๐งช Testing & Verification
-
New Unit Tests:
- Added
PaintingPartBlockUnitTest.java(5 tests), covering:- Anchor lookup candidate calculation within bounded planes.
- Strict avoidance of reads into unloaded chunks (
testAnchorLookupCandidateMakesNoReadsIntoUnloadedChunks). - Proven orphan detection when all candidates are loaded.
- Total unit test suite: 67 tests passing (0 failures).
- Added
-
Expanded GameTest Suite:
- Expanded
FastPaintingsGameTests.javafrom 5 to 22 mod tests (23 total GameTests passing):- All 4 horizontal facings (
NORTH,SOUTH,EAST,WEST) tested for placement and break. - Multipart anchor resolution and break verification outside origin with drop integrity assertions.
- Backing wall destruction via natural game physics block updates.
- Multi-tick restoration suppression survival.
- Atomic rollback on entity insertion failures, spawner crashes, and incomplete removals.
testRestorationCleanupFailurePreventsDuplicateRepresentations: Verifies rollback is skipped andRestorationExceptionraised if an entity remains active.testStatsCountsAnchorBlockWithoutBlockEntity: Verifies orphan anchor blocks without block entities are counted accurately.- Zero item drops in creative mode.
- All 4 horizontal facings (
- Expanded
๐ฆ Commits (v1.0.0...v1.1.0)
7baecfefix: separate cleanup and rollback recovery stages and enumerate anchor block states9219c07fix: harden restoration recovery boundary, chunk-granular stats, and regression test suite84c3faffix: harden restoration safety, uninstallation scope, and honest test harness105191dfix: address reproduced restoration safety failuresafa0d9etest: cover callback removal and multi-tick restoration6ccddc9fix: resolve multipart painting anchors outside world origin
Full Changelog: https://github.com/justbecauseph/really-fast-paintings/compare/v1.0.0...v1.1.0
Optional dependencies
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:8wqs2Gov:9xOnhjEM"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:8wqs2Gov:9xOnhjEM"
}

