Repository navigation
Releases: kgbcupcake/MariesLib
Release list
v0.1.2-beta.1
A ready-made in-game Item Editor with recipe previews, per-item diminishing returns, reusable Hub home pages, and the foundation for a unified config registry.
Highlights
- Item Editor: a ready-made window any MariesLib mod can open for players. It shows why an item resolved the values it did, lets you edit and save a per-item override on the spot, and applies it immediately with no reload.
- Recipe preview: the editor shows what crafts the targeted item, as a JEI/EMI-style recipe grid, with a slowly turning 3D model of the crafting station below it.
- Per-item diminishing returns: mods can give a single food its own diminishing-returns curve, or exempt it entirely, instead of only switching the whole system on or off.
Added
Item Editor
- Drag an item straight in from JEI or EMI to target it. The window can be dragged and resized, remembers its position, and has a gear button for Style options (background, border, Glow, Pulse) like every other box.
- It can open on top of whatever screen is already up, such as the inventory, so JEI's or EMI's list stays available to drag from.
- A small File/Info menu bar: Info shows the classification readout, and File switches between pages ? Values, plus any pages a mod adds.
- Save and Revert sit in the top-right corner, light up on hover, and flash a green "Saved ?" / "Reverted ?" when clicked.
- The recipe preview covers the crafting table, furnace, smoker, blast furnace, campfire and stonecutter, plus Farmer's Delight's cooking pot and cutting board and Dungeon's Delight's monster pot when installed. Hover an ingredient to see which mod it's from; slots that accept several items cycle through all of them. Items with no recipe show "No known recipe".
For addon developers
- Mods can add their own rows to the Item Editor, or whole pages of their own in its File menu (like Nourished's Options page), with the editor's shared Save/Revert.
- Pages can claim items dropped onto the editor (for multi-item lists like Nourished's Bulk Edit) and jump the editor to another item and page.
- Per-item diminishing returns: source-aware
trackingMemoryConfigProviderandclientMemoryConfigProvideroverloads onMarieContext.Builder, so the tooltip preview matches what eating actually does. enableDiminishingReturnsfeature flag: a master switch that turns diminishing returns off for every source at once.MarieContext.Builder#sourceExclusionFilter: your mod's own exclusion check is now consulted before a generic Item Editor override can grant values on eating.- Reusable Hub home page (
HubInfoPage,EntityPreviewBox,HubInfoSection): a 3D entity preview beside a scrollable summary. - Option panels gain decimal sliders (e.g. "293.15 K" or "0.050") and buttons whose label shows a live value.
- New
marie-configmodule: the foundation for a unified config registry with generic JSON export/import. Nothing uses it yet ? a Dynamic Config Editor builds on it later.
Changed
- The Item Editor matches the Hub Home page's look: a small item preview card on the left, with the value sliders in their own scrollable list on the right.
- The Info tab is readable: plain-English step names, color-coded by outcome, with a clear summary at the bottom.
- Opening an item with no saved override starts the sliders from the values it actually resolves to, instead of a blank 0%.
- Overrides are saved under
config//item_editor/, with a folder per value category. Existing overrides are moved there automatically, and only values you actually changed are written.
Fixed
- MariesLib's EMI support never turned on at all on NeoForge. It's now registered correctly, so EMI drag-and-drop works.
- JEI's and EMI's item lists now show up beside the standalone Item Editor, and dropping an item from EMI no longer adds it to EMI's favorites instead.
- JEI and EMI lists no longer vanish after the overlay editor closes.
- With several MariesLib mods installed, a mod that never declares which items it cares about no longer lets every item through other mods' scans.
- Per-item diminishing returns kept working only for the last-loaded mod; it now works regardless of load order.
- The Item Editor can no longer save its position off-screen, and tall pages scroll inside the window instead of spilling past its border.
- The File dropdown no longer draws under the item icon, and the rows can no longer overflow the window at small sizes.
- The Style popup opens centered above the inventory instead of hidden behind JEI's or EMI's list.
- No more empty placeholder override files created on launch.
Full notes on the wiki: https://marieswiki.kgbcupcake.workers.dev/mods/marieslib/changelog/0.1.2-beta.1/
v0.1.2-beta
This is a big beta. Module boxes get a full look-and-feel overhaul, mods that run side by side get a lot of fixes, and several datapack and API features that never worked now do.
⚠️ Beta. If your mod builds on MariesLib, read For addon developers below. Some UI classes moved into the newmarie-editormodule.
✨ Highlights
- New Glow and Pulse tabs on every box: text, border and bar glow with color and strength, plus a "breathing" border pulse (Smooth, Heartbeat or Flash) that stays in sync across boxes.
- More box styling: background and border opacity and shade, border shadow, header size, and a one-click Reset This Module button.
- More Hide options: Hide Window, Hide Text, Hide Bars and Hide Header, next to Hide Icons.
- Size snapping: resizing a box can snap it to the size of the boxes next to it.
- New Hub window: a resizable popup with a sidebar, used by editors such as Nourished's Diet Screen editor.
- Redesigned color picker: a round hue/saturation wheel, a brightness slider, saved favorites and hex entry.
🐛 Fixes
Gameplay and multiple mods
- If two or more mods use MarieLib, each mod now uses its own settings for decay, effects, tooltips, thresholds and tracking. Before, the most recently loaded mod's settings applied to all of them.
- Eating or using a source no longer counts its value gains more than once when several mods are installed.
- A mod using the default settings no longer makes other mods' tooltips and value guesses appear on every item.
- Respawning no longer wipes recent-source history for a mod set to keep values on death, and each mod resets to its own starting level.
- Profiles, milestones and synergies added by mods no longer disappear after a second
/reload. - Daily, weekly and monthly trackers now reset when you sleep through the night or use
/time. Periods cut short by moving time backwards record when they actually ended. - Item tooltips in single-player no longer show value info left over from the last multiplayer server you joined.
- Diminishing returns now count "free bites" correctly.
- Fixed full-screen black flashing on the HUD while eating.
Boxes and editor
- Icon size no longer follows text size where it shouldn't (Calories, Balance, Recent Meals, Eat More Of).
- Bar rows and legends now respect their own text, icon and bar size sliders and Hide Window.
- Moving boxes no longer feels sticky: they snap only when they're close to another box.
- Glow no longer squares off a box's rounded corners.
- Hub color pickers now work, and a custom title color applies to the sidebar.
- The move outline now covers a box's header, and icon boxes follow their icon.
- Only one size-settings window can be open at a time across all boxes.
- The toolbox scrollbar no longer covers hex values and slider percentages.
Datapacks and scripts
tracking_profiles/*.jsonfiles now load. Before, they were always skipped.- Compat entries with bulk item-to-value mappings now apply those mappings.
- A runtime tooltip message override now replaces only the message it names, not the whole item's tooltip.
- Mod scans: two scanners with similar names no longer overwrite each other's cached results.
- Removed the unused
mod_compat.jsonloader that logged a missing-resource warning on every launch.
🧩 For addon developers
- New module:
marie-editor. The layout editor, module settings, scale-config and toolbox systems moved out ofmarie-ui. Add the dependency if you use them. - API stability: every
dev.marie.frameworkpackage is now marked@Stable,@Experimentalor@Internal. Value tracking, events and definitions, compat, tag audit and resource sync are Stable. UI, datapack, scanner, command and config systems are Experimental. - New in the API:
MarieAPI.registerTrackerMilestone: use this instead ofTrackerMilestoneRegistrydirectly.MarieRequestChannelMarieModScanMarieWidgets,MarieToolbox,MarieModuleSettingsMariePulse,AnimatedFloatHubPanelBarRowComponent,TitleBarComponent,LegendComponentRenderContext#drawRoundedRect,#drawGlow,#drawEffectIconValueDefinition.iconand.tags
- Deprecated: the single-argument
registerExportResolver(ExportResolver)is nowforRemovaland will be removed in the next major version. Use the overload that takes a registry key. - Documented in
API.md:- The
marie_schema_versioncontract: one shared version, and a mismatch only warns. - Which registrations survive
/reload: profiles, milestones, tracker milestones and synergies do. Trackers and colors must be registered again.
- The
v0.1.1-beta.5
MariesLib 0.1.1-beta.5
Large release: reworks the recipe/keyword classification merge to actually let recipe data contest a keyword match, and adds a batch of new generic (domain-agnostic) UI, tracking, sync, and color subsystems that consumer mods like Nourished build on.
Classification / Scanner
RuntimeResolutionMergeand the scanner'sRecipeInheritanceStageno longer let a keyword match permanently lock its category recipe data can now dilute or (for opt-incontestable_valuescategories) outright override it.- Confidence is computed once over the combined keyword + recipe signal instead of being copied verbatim from the keyword winner, so items with disagreeing names/recipes can now be flagged UNCERTAIN.
scannerConfidenceSpreadThresholddefault raised from0f → 0.15f(was previously dead: UNCERTAIN flagging never fired at 0).CommunityTagResolutionStage's tag directory (c:foods/...) is now per-mod configurable viascanner_spec.jsoninstead of hardcoded.compositeRatioThresholddefault raised from0f → 0.5f— a stray secondary tag no longer silently attaches a second category to an item.SourceClassificationRegistryoverrides now actually reachSourceRegistry(they were silently ignored before), and an active override now fully locks out competing tag/API registrations for that item instead of letting them leak through.- Added a new
caloriesfield tosource_classifications.json, with corrected precedence so classifying an item no longer zeroes or miscalculates its calorie total. - Added
RecipeInheritanceResolver.collectContributions: walks the entire recipe tree instead of short-circuiting at the first confident match. Fixes the "calzone" bug class where a weak match on an intermediate ingredient hid a stronger match one level down.
New UI Subsystems (marie-ui)
- Command Center: pluggable sidebar + card dashboard screen for consumer mods to register content into. Now supports dragging/resizing, clipping/scrolling, and corrected chrome rendering (blur order, sizing, translation key).
- Notifications: generic client-side toast/notification stack above the XP bar, with merge-by-key support.
- Scale Config Panel: replaces the old
ContentScaleConfigScreen. Provides generic per-component text/padding scale adjustment and can be embedded as an overlay instead of requiring a fullScreen. - Edit Mode / Snap Registry — generalized double-click edit mode and cross-mod magnetic-edge snapping for draggable HUD components.
- Color System:
ColorKey/ColorDefinition/MarieColorslayer connectingColorRegistryoverrides to a real defaults/resolve API, pluswithOpacity/shadehelpers and a generic Cloth Config color-row widget. - Added the new
dev.marie.framework.ui.apifacade package, consolidating the public entry points for all of the above.
Tracking & Sync
-
Added a generic tracker/period-history framework (
MarieTracking) supporting daily, weekly, monthly, and custom periods. -
Added a parallel tracker-milestone system, both with datapack support.
-
Added two-tier client sync for trackers:
- Throttled dirty-flag sweep
- Full login snapshot
-
This fixes previously stale client-side tracker reads.
-
Added
MarieResourcesAPIfor generic config/registry synchronization, so mods no longer need to hand-roll their own sync payload/channel. -
Client caches now clear on disconnect (previously they never did).
Breaking Changes
-
dev.marie.framework.notification.MarieNotifications,ui.commandcenter.MarieCommandCenter, andui.edit.EditModeCoordinatormoved todev.marie.framework.ui.api.- Old import paths no longer exist.
-
Removed
MarieAPI.registerTracker,incrementTracker,getCurrentTrackerValue, andgetTrackerHistory.- Use
MarieTrackinginstead.
- Use
-
Deleted
ContentScaleConfigScreenandScaleSliderButton.- Use
ScaleConfigPanelinstead.
- Use
-
Nourished and any other direct consumer will not compile against this version without call-site updates to the above APIs.
Notable Fixes
- Reload/registration gap:
TrackerRegistryandColorDefinitionRegistryregistrations made at mod-init were being silently wiped on every world boot with no re-registration path. They are now correctly hooked into both/reloadand server startup. - Tracker milestone datapack entries were silently dropped due to a missing callback override.
- Login snapshots no longer miss tracker values in the CUSTOM-period, no-history-yet edge case.
- Swim-tick triggers no longer keep firing briefly after leaving water.
- Oversized-packet checks now happen pre-decode instead of after a full NBT round-trip, improving DoS hardening.
- Fixed several NPEs around item-agnostic triggers (block break, entity kill, and tick) passing
nullinstead ofItemStack.EMPTY.
Full Changelog: v0.1.1-beta.4...v0.1.1-beta.5
MariesLib_v0.1.1-beta.4
Scanner signal stages extracted into the ResolutionStageHandler cascade shape, ComponentClassifier wired into recipe-inheritance fallback, DeathNutritionBehavior renamed for domain-agnosticism, a marie-core/marie-ui/marie-commands audit for leftover food/nutrition-specific naming, tooltip message/color customization, excluded-item tooltip handling, a bundled-resource lookup fix, an excluded-items registry, and recipe-inheritance score merging for tagged items.
Added
CommunityTagResolutionStage/SuffixResolutionStage/KeywordResolutionStageRespawnValueBehavior(renamed fromDeathNutritionBehavior)TooltipMessageRegistry/TooltipColorRegistryExcludedItemsRegistry, wired intoMarieBootstrapDoubleClickRecognizer,ComponentState.contentScale, newDraggableResizableconstructor overload
Changed
- Several internal file splits (
MarieAPI,RuntimeResolver,ItemClassifier,ClassificationTraceFormatter) — no public API changes MarieTooltipHelpermoved packages (compat→tooltips)SourceClassificationRegistryoverride folder layout changed@ApiStatustier corrections for several previously-mislabeled classes
Fixed
SourceClassificationRegistry.parseEntry()no longer crashes on malformed entries- Removed unreachable bundled README resources
- Removed dead-code
ExportResolverRegistry MarieAPI.registerExportResolversingle-arg overload no longer silently no-ops
Full changelog: see CHANGELOG.md
MariesLib_v0.1.1-beta.3
[ MariesLib 0.1.1-beta.3 ] 2026-6-30
Source-pair synergy value buffs, source classification unification, tag-audit and export
command wiring, and player-logout state cleanup for the new synergy tracking.
Added
MarieAPI.registerConfigValidator(validator): now validates that thevalidator's
modId()is non-empty and matches a registered mod; throwsIllegalArgumentExceptionif notSourcePairSynergy.getValueModifier()/getModifierDurationTicks()(@ApiStatus.Stable),
with matchingBuilder.valueModifier(float)/Builder.modifierDurationTicks(int): an optional
temporary value-gain multiplier applied when the pair synergy fires, lasting the given number
of game ticksSynergyBuffTracker(tracking): per-player, per-value-key temporary modifier store keyed
offplayer.level().getGameTime();activate(playerId, valueKey, modifier, expiryTick)sets a
buff,getActiveModifier(playerId, valueKey, currentTick)reads it back and evicts it in place
once expired;clearPlayer(playerId)drops all buffs for a playerSynergyAbsorptionModifier(tracking, implementsAbsorptionModifier): stateless bridge
that appliesSynergyBuffTracker's active modifier during value absorption; registered in
MariesLibBootstrapviaMarieAPI.registerAbsorptionModifierSourceApplicationPipeline.clearPlayer(playerId): clears the per-player synergy last-fired
and value-synergy active-state maps; wired into the existingPlayerLoggedOutEventhandler
(MarieCommandSupport.onPlayerLoggedOut) alongside the newSynergyBuffTracker.clearPlayer
call, so synergy state no longer persists in memory after a player disconnects- Datapack schema keys
value_modifier/modifier_duration_ticks
(DatapackSchema.KEY_VALUE_MODIFIER/KEY_MODIFIER_DURATION_TICKS) for
data/<namespace>/<modid>/source_synergies/<id>.json, both optional (default1.0/0) MarieDataLoader.parseSynergy/parseSourcePairSynergy: datapack loading for
synergies/andsource_synergies/is now implemented (previously threw
UnsupportedOperationExceptionand skipped the file)CommandCapability/CommandCapabilityRegistry(@ApiStatus.Experimental):
consuming-mod-registered command handlers keyed by(modId, capability)resource locations,
viaMarieAPI.registerCommandCapabilityExportWriter.writeExport(resolverId)andRegistryExporter: runs a registered
ExportResolverover its target registry and writes
config/<modid>/<resolverId>_export.json; wired into/marieslib dump <resolverId>/
/marie dump <resolverId>TagAuditReportWriter: writes a fullTagReport(fromTagScanner.scan) to disk; wired
into a new/marieslib audit_tags <modid>command viaMariesLibCommand.runAuditTagsMariesLibCommand.runDump/runAuditTags: command handlers backing thedumpand
audit_tagssubcommandsSourceClassificationRegistryrewritten as a full config-backed registry (was previously a
thin read-only view overSourceRegistry):load()/reload()/loadFromDatapack()read
config/<modid>/source_classifications.json, auto-migrating existing
source_overrides.json+source_values.jsonon first run; addsget(sourceId),
getOverride(sourceId),getScore(itemId, valueKey), andsetOverride(itemId, values, enabled)RuntimeResolverclassification trace: when a live external/scanner override exists for an
item, a newEXTERNAL_CLASSIFICATIONtrace step is recorded explaining that gameplay uses the
cached override rather than the live inference result shown below it
Changed
SourceOverrideRegistryandSourceValueRegistryremoved, merged into the rewritten
SourceClassificationRegistry;MarieKubeBindings.registerClassificationand
MarieLibContextscanner-score lookups now callSourceClassificationRegistrydirectlyMarieAPI: registration methods reordered/regrouped (export resolvers, config validators,
tag audit, and the new command-capability registration now live together near the end of the
class); no functional change to existing methodsMariesLibconstructor: no longer auto-bootstrapsMariesLibBootstrapwhen
MarieLibContextis unregistered — this call was already removed fromMarieAPI's
fireSourceTrigger path in 0.1.1-beta.1's changelog notes but the constructor still had it;
consuming mods must callMariesLibBootstrap.attach/bootstrapexplicitlyRecipeInheritanceResolver.buildIndex(RecipeManager): now actually builds the ingredient
index (this.recipeIndex = buildIndex()) instead of only storing theRecipeManagerreferencePresetRegistry.PresetValues: replaced the fixed-field record (decayRate,
criticalThreshold,lowThreshold,excessThreshold,defaultEffectDurationTicks,
enableDecay,enableEffects) with a single opaqueJsonObject valuespassthrough, so
consuming mods can store arbitrary preset schemas instead of MariesLib-defined fieldsMarieValueColors.resolvedDefaultArgb(key): no longer an alias forbaseColorArgb; now
resolvesValueDefinition.getColorOverride()first, then falls back to the palette-only color,
bypassing transient UI overrides andColorRegistryas intended for "is this actually
customized" checksModCompatclasspath resource loading (loadTier1BuiltIn, tier-2 mod loop): reads
compat_registry.json/marie_compat.jsonvia the current thread's context class loader
first, falling back toModCompat.class.getResourceAsStream, matching the same fix already
applied toScannerSpecRegistryin 0.1.1-beta.1ScannerSpecRegistry.parseBundled(): also routes through the context class loader
Fixed
ColorRegistry.parseArgbString0x/0Xbranch: parses the hex portion via
Long.parseLong(hex, 16)with0xFF_FF_FF_FFmasking instead ofInteger.decode, avoiding
the same signed-decode inconsistency already fixed for other branches in 0.1.0-beta.5MarieDebugCommandtrace dump filename:analyze <item>writes to
trace_dump_<item>_<timestamp>.txtinstead of a single sharedtrace_dump.txt, so repeated or
concurrent analyses no longer overwrite each other's output
Notes
- Published artifact version is 0.1.1-beta.3 (
gradle.properties)
MariesLib_v0.1.0-beta.2
[ MariesLib 0.1.1-beta.2 ] 2026-6-27
Config validation framework, tag-audit system, curve grid math, command extensions, and scanner spec graceful-skip.
Added
ConfigValidator(@ApiStatus.Stable): consuming-mod hook that validates its own configuration and
returns a structuredValidationResult; registered viaMarieAPI.registerConfigValidatorConfigValidatorRegistry(@ApiStatus.Internal): keyed store ofConfigValidatorinstances;
supportsgetAllRaw()for internal runner iterationFinding(@ApiStatus.Stable): record carryingseverity,file,key, andmessagefor a
single validation issue within aValidationResultValidationResult(@ApiStatus.Stable): structured outcome of a config validator run; status is
one ofPASS,WARN, orFAIL, plus a list ofFindingitemsValidationRunner.runForMod(modId)(@ApiStatus.Stable): filters and runs only the validators
belonging to the given mod id; complementsrunAll()for per-consumer diagnosticsTagAuditContext(@ApiStatus.Stable): context interface passed to tag-audit rules; exposes
knownCategories(),itemsInCategory(category),categoriesForItem(itemId),
liveInferenceLookup(), andnamespacesPresent()TagRule(@ApiStatus.Stable): interface for pluggable tag-audit rules; implements
findIssues(context)andsuggestFixes(context, issues)TagIssue(@ApiStatus.Stable): record describing a single tag problem withseverity,category,
itemId, andmessageTagFixSuggestion(@ApiStatus.Stable): record carrying a corrective suggestion (category,
itemId,action,reason) produced by aTagRuleTagAuditSeverity(@ApiStatus.Stable): severity enum (ERROR,WARN,INFO) forTagIssueTagReport(@ApiStatus.Stable): result of a fullTagScanner.scanrun; includestimestamp,
rulesRun,issues, andsuggestionsTagScanner.scan(context)(@ApiStatus.Stable): iterates all registeredTagRuleinstances,
collects issues and fix suggestions, and returns a timestampedTagReportTagRuleRegistry(@ApiStatus.Internal): ordered store of registeredTagRuleinstancesTagAuditContextRegistry(@ApiStatus.Internal): per-modId store ofTagAuditContextinstancesCurveGrid(@ApiStatus.Stable): 2-D grid of float multipliers evaluated via bilinear
interpolation; axes are(intensity, confidence)both normalised to[0, 1];flat(xCells, yCells, value)constructs a uniform grid,evaluate(x, y)samples with clampingCurveGridJson(@ApiStatus.Internal): JSON serialisation / deserialisation forCurveGridSourceClassificationRegistry(@ApiStatus.Stable): public read-only view of external source
classifications registered viaSourceRegistry;getAll()returns an unmodifiable map of
ResourceLocation → SourceClassification(sourceId, values)MarieAPI.registerConfigValidator(validator)(@ApiStatus.Stable): public registration entry
point forConfigValidatorinstancesMarieAPI.registerExportResolver(resolver)andregisterExportResolver(key, registryKey, resolver)
(@ApiStatus.Stable): two overloads for wiringExportResolverinstances intoExportResolverRegistryMarieAPI.registerTagRule(rule)andMarieAPI.registerTagAuditContext(modId, context)
(@ApiStatus.Stable): public registration entry points for the tag-audit system/<modid> set_all <value> <player>(MarieConsumerCommandTree, permission 2): sets all
registered value keys for the target player to the given normalised level in a single command via
SourceApplicationPipeline.writeDirectValue/<modid> validate(MarieConsumerCommandTree): runs allConfigValidatorinstances
registered for the consumer mod and prints PASS / WARN / FAIL results with per-finding detail in
colour-coded chat; backed byMarieValidationCommands/<modid> analyze <item>(MarieConsumerCommandTree, permission 0): resolves a
ClassificationTracefor any food item viaRuntimeResolverand writes a full inspector dump to
config/<modid>/debug/analyze_<item>_<timestamp>.txt; suggests only food-bearing items via
DataComponents.FOODfilterMarieValidationCommands(@ApiStatus.Internal): internal command handler for thevalidate
subcommand; formatsValidationResultoutput withChatFormattingcolour codingSourceRegistry.getAllExternalClassifications(): returns a snapshot of all API- and KubeJS-
registered classifications for external inspection
Changed
MariesLibCommand: removed duplicateregisterLibraryTreecall underMariesLib.MOD_ID; the
library command tree is now registered only under the/mariealiasRecipeInheritanceResolver.getIngredients(): promoted topublicvisibility; addedbuildIndex(RecipeManager)
to set the active recipe manager for ingredient index constructionMarieValueColors: additional accessor method(s) to support tag-audit and export tooling
Fixed
ScannerSpecRegistry.writeBundledTo(): now returnsbooleaninstead ofvoid; the caller
(ensureLoaded) only logs a success message whentrueis returned and silently skips at
DEBUGlevel when no bundledscanner_spec.jsonexists for the active modId, eliminating
spurious warnings for mods that do not ship a bundled spec
Notes
- Published artifact version is 0.1.1-beta.2 (
gradle.properties)
MairiesHub v0.1.1-beta.1
[ MariesLib 0.1.1-beta.1 ] 2026-6-20
Generic registry-export framework, scanner spec loading fix, explicit bootstrap requirement, and registry frozen-state exposure.
Added
ExportResolver<T>(@ApiStatus.Stable): consuming-mod hook that resolves per-entry export
data for an entire registry; registered viaMarieAPI.registerExportResolverExportResolverRegistry(@ApiStatus.Internal): keyed store of export resolvers and their
targetResourceKey<? extends Registry<T>>; never frozen so resolvers can register throughout mod initRegistryExporter.run(resolverId)(@ApiStatus.Internal): iterates the resolver's target
registry viaBuiltInRegistries.REGISTRY, callsExportResolver.resolveper entry, and returns
non-empty results keyed by entry idExportWriter.writeExport(resolverId)(@ApiStatus.Internal): runsRegistryExporterand
writesconfig/<modid>/<resolverId>_export.jsonas a sorted JSON array of
{"id": "<resource location>", "data": {...}}objects; nestedMapvalues serialize as JSON objects/marieslib dump <resolverId>and/marie dump <resolverId>(MariesLibCommand): runs
ExportWriter.writeExportand reports the output path or a failure messageMarieAPI.registerExportResolver(resolverId, registryKey, resolver)(@ApiStatus.Stable):
public registration entry point withMarieAPIStatephase guard and blank-resolverIdvalidationValueRegistry.isFrozen()(@ApiStatus.Internal): exposes the underlying
AbstractRegistryfrozen state viaINSTANCE.isFrozen(), matching the existing
freezeInternal()/resetInternal()internal lifecycle surface
Changed
MariesLibconstructor: no longer auto-callsMariesLibBootstrap.bootstrap()when
MarieLibContextis unregistered; consuming mods must bootstrap explicitly via
MariesLibBootstrap.attach/bootstrap
Fixed
ScannerSpecRegistrybundled spec loading (parseBundled,writeBundledTo): reads
scanner_spec.jsonviaThread.currentThread().getContextClassLoader()(with the leading
/stripped from the resource path) instead ofScannerSpecRegistry.class.getResourceAsStream,
so specs packaged in the consuming mod's jar (e.g. Nourished) resolve correctly instead of
failing withBundled scanner_spec.json missing
Notes
- Published artifact version is 0.1.1-beta.1 (
gradle.properties)
v0.1.0-beta.5
[ MariesLib 0.1.0-beta.5 ] 2026-6-16
Color resolution and ARGB parsing fixes for value customization detection.
Added
MarieValueColors.resolvedDefaultArgb(String key): returns a value key's true default ARGB,
checkingValueDefinition.colorOverridethen the built-in palette, while bypassing transient
OVERRIDESandColorRegistry; use this (notpaletteOnlyArgb) when deciding whether an
edited color is an actual customizationIMarieLibConfig.decayRateFor(String valueKey)andMarieLibContext.Builder.decayRateFor(Function<String, Float>):
per-value decay rate resolver wired through config context; defaults to
ValueDefinition.getDefaultDecayRate()with0.001ffallback when the key is unknown
Fixed
ColorRegistry.parseArgbString0x/0Xbranch: parses hex viaLong.parseLongwith
0xFF_FF_FF_FFmasking instead ofInteger.decode, matching the#RRGGBBand bare 8-digit
branches and avoiding signed-decode inconsistencies on full ARGB literalsValueDecayListenerdecay tick rate: usesIMarieLibConfig.get().decayRateFor(key)instead
of always readingValueDefinition.getDefaultDecayRate(), so consuming-mod overrides take effectMarieCommandSource/MariePlayerCommandsdecay display: report and value-detail commands
route decay rates throughIMarieLibConfig.decayRateFor(key)instead of hard-coded definition
defaultsSourceRegistry.clearExternalClassifications(): API/KubeJSregisterClassification()
entries are tracked inAPI_REGISTERED_CLASSIFICATIONSand re-applied after each clear, so
classifications registered at mod construction surviveTagsUpdatedEventreload passes
(datapack-sourced entries are still cleared and reloaded normally)CriticalValueToastvalue name: falls back to the rawvalueKeywhen the tracking-bar
translation key is missing, instead of showing the untranslated key path in the toast
title/subtitle
Notes
- Published artifact version is 0.1.0-beta.5 (
gradle.properties)
v0.1.0-beta.4
Fixed
SourceRegistryregistration logs dropped from INFO to DEBUG, no more per-item classification spam on every reload- External classification cap warnings now log once per item per server session instead of repeating on every reload
Requires Minecraft 1.21.1, NeoForge 21.1.x, Java 21.
MariesLib_v0.1.0-beta.3
Milestone tracking release. Cumulative intake milestones are now tracked at runtime,
fired as events, loadable from datapacks, and exposed to KubeJS.
Added
MilestoneTriggeredEventinMarieEvents, fired after a player completes a cumulative
intake milestone and configured rewards are appliedMilestoneProgressData, per-player cumulative intake totals and one-shot completion
bookkeeping, serialized separately fromTrackingDataMilestoneProgressAttachment, NeoForge data attachment (milestone_progress) with
copyOnDeath(), gated byFeatureFlagCache.enableMilestones()MilestoneTracker, accumulates positive value intake, detects first-time completions,
grants mob-effect and advancement rewards, then postsMilestoneTriggeredEventMarieDatapackCallbacks, defaultMarieDataLoader.Callbacksimplementation that delegates
datapack registrations toMarieAPI(values, effects, synergies, milestones, profiles, compat,
source families, module locks)- Datapack milestone parsing in
MarieDataLoaderfor
data/<namespace>/<modid>/milestones/<id>.json(valueKey,cumulativeGoal, optional
rewardEffectId,amplifier,rewardDuration,advancementId) - Bootstrap wiring in
MariesLibBootstrap: registersMilestoneProgressAttachmentand sets
MarieDataManager.setCallbacks(MarieDatapackCallbacks.INSTANCE)on standalone bootstrap advancementIdonMarieKubeBindings.registerMilestone, optional KubeJS spec key mapped to
MilestoneDefinition.Builder.advancement()
Architecture
- Pipeline hook:
SourceApplicationPipelinecallsMilestoneTracker.onValueApplied(player, key, finalDelta)after each positive per-valueKey delta is applied andSourceAppliedEventis
posted - Reward flow:
MilestoneTrackerapplies optional mob effects viaBuiltInRegistries.MOB_EFFECT,
awards advancements through the server advancement manager, and logs warnings for unknown
effect/advancement IDs - Feature gating: milestone progress reads and writes are no-ops when
FeatureFlagCache.enableMilestones()is false
API
MarieEvents.MilestoneTriggeredEvent:getPlayer(),getMilestone(),getValueKey(),
getCumulativeIntake()
Integrations
- KubeJS
milestoneTriggeredevent:MarieKubeEvents.MILESTONE_TRIGGERED/
MarieMilestoneTriggeredEventexposesplayerId,milestoneId,valueKey,cumulativeIntake,
andcumulativeGoal; bridged throughKubeEventBridgewithKubeGuardlistener short-circuit
Notes
- Published artifact version is 0.1.0-beta.3 (
gradle.properties) - Milestones datapack loader from 1.0.0 is now fully wired (previously threw
UnsupportedOperationExceptionat parse time)