CC2 Phase 1: deep-slot storage engine - #215
Merged
rubensworks merged 15 commits intoOct 3, 2026
Merged
Conversation
Rename the mod to colossalchests2 (mod id, package, resources, group, update URLs) and remove all CC1 gameplay content so the branch builds with only the loader entrypoints, proxies and Cyclops Core wiring. - Enable JUnit in the common module against vanilla classes. - Add the data-driven table schema (materials, depth by size, upgrade values) with shipped defaults and a loader stub. - Keep one game test per loader via the shared GameTestsCommon. - Add dev/clientdevbridge with launch instructions and a mod list check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Pure-logic storage model with no block, block entity or menu references. - DeepSlot: immutable slot record (prototype, long count, locked, compression form). - CapacityProfile: uniform depth with Depth upgrades, non-stackable capacity from Bundling and Depth, technical per-slot cap and the acceptNonStackables switch, all with saturating math. - ChestStorage: insert/extract per slot and by type, locks, derived extract-only state, non-mutating resize validation, forced profile changes for re-forming smaller, dirty-slot tracking, change listeners, a state counter for inventory-state capabilities, and sparse codec serialization that never drops entries on load. - CompressionFamily/CompressionFamilies: ordered forms with base-unit conversion math and lookup by item. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Drop the dev/clientdevbridge files, keep the CC1 project IDs, display and update URLs, restore the README and .gitignore, and use the suggested mod description. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
…21-lts-v2-phase1-storage
rubensworks
marked this pull request as draft
September 28, 2026 17:42
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Each material is now its own file under data/<namespace>/colossalchests2/material/, so mods and datapacks can add materials without overwriting each other. Chest-wide values move to data/colossalchests2/colossalchests2/chest.json. Every field is optional with a default, so adding fields later never breaks existing datapacks. The global upgrade table and max_depth_upgrades are dropped: upgrade values and per-material limits will be declared by each upgrade in data/<namespace>/colossalchests2/upgrade/ when upgrades are added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
The profile now only holds resolved values (depth, non-stackable capacity, technical cap, acceptNonStackables). A builder collects modifiers: the structure sets the base depth and each installed upgrade applies its own (multiply depth, multiply or add non-stackable factors), so new upgrades, including from other mods, need no profile changes. The D-2 rules are covered by tests expressing Depth and Bundling as modifiers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Base slots, max slots and stacks per slot by structure size are now config options instead of a datapack file. They are a fixed set owned by this mod, so per-entry data files are not needed; materials stay data-driven because other mods add entries. Getters clamp the values, since config ranges are not enforced on load. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
rubensworks
marked this pull request as ready for review
October 3, 2026 14:53
rubensworks
commented
Oct 3, 2026
- Store a slot's compression form as an item instead of an index into the compression family, so it survives datapack changes to the family. Unknown form items load as the default form. - Skip storage entries that cannot be decoded, such as items of a removed mod, instead of failing to load the whole storage. - Move nonStackableCapacity to the last CapacityProfile component. - Reword the ChestStorage javadoc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of the Colossal Chests 2 plan (D-2, D-3). Phase 0 (#214) is merged, so the diff only contains Phase 1.
Summary
Everything is in
org.cyclops.colossalchests2.storage. It usesItemStackand components only, with no blocks, block entities or menus.DeepSlot: an immutable slot holding a prototype (count 1), alongcount, alockedflag and an optional compression form. The form is the item the player picked to extract in, stored as an item rather than an index into the compression family so it survives datapack changes to the family. It normalizes itself: a type with count 0 only survives while locked.CapacityProfile: only resolved values: depth (stacks per slot), non-stackable capacity, technical capmaxItemsPerSlot(defaultInteger.MAX_VALUE) andacceptNonStackables. ABuildercollects modifiers: the structure sets the base depth, and each installed upgrade applies its own (multiplyDepth,multiplyNonStackable,addNonStackableFactor). The profile knows nothing about upgrade types, so new upgrades, including third-party ones, need no changes here. The D-2 rules (stackablesdepth * maxStackSize, non-stackables2^bundling * (1 + depthUpgrades)) are tested by expressing Depth and Bundling as those modifiers. All math saturates instead of overflowing.ChestStorage:lockTo,lockAllFilled,clearLocks.count > capacity), never stored. That makes "re-formed smaller" and "config lowered" one code path, and loading can never delete items.validateSlotCount/validateProfilereturn aResizeResultlisting the offending slots.setSlotCount/setProfileonly change anything when that result is ok.forceProfilealways applies and returns the slots that became extract-only.drainDirtySlots,markAllDirty) and change listeners (slot index, or -1 for layout or capacity changes).getState(): a counter that changes on every mutation. This backs the CommonCapabilitiesIInventoryStatecapability you asked for; Phase 2 exposes it.CompressionFamily/CompressionFamilies: ordered forms with base units, conversion math (toBaseUnits,fromBaseUnits,remainderBaseUnits,convert) and lookup by item. Stacks with components never compress. There's no tag loading yet; tests use a hardcoded iron family.Validation
All unit tests are in
loader-common/src/test/.../storage(94 tests including Phase 0's). JaCoCo reports 100% line coverage and every method covered for the storage package.TestChestStorage.testInsertInto*,testInsertPartiallyFits,testInsertDistinctComponentsAreDistinctTypesTestChestStorage.testExtract*TestCapacityProfile.testCapacityNonStackable,testNonStackableCapacityIgnoresBaseDepth,testNonStackableSaturates,TestChestStorage.testNonStackableCapacityWithUpgradesInteger.MAX_VALUEand one above it in extract-only modeTestChestStorage.testSerializationRoundTrip(NBT),testSerializationJson,testContentsAreSparse,testLoadContentsNeverDropsEntries,testUndecodableEntrySkipped,testUnknownCompressionFormLoadsAsDefaulttestValidateSlotCount,testSetSlotCount*,testValidateProfileBothDirections,testSetProfile,testForceProfileTestCompressionFamily.testConversionAcrossThreeForms./gradlew buildand./gradlew runGameTestServerpass on all three loaders. There are no new game tests or clientdevbridge checks because nothing touches a level or GUI yet.Design deviations
🤖 Generated with Claude Code
https://claude.ai/code/session_01RSz5r6eowhjNuANBjZE2v6
Generated by Claude Code
Generated by Claude Code