Meritum Engine - v1.2 [ 26.30+ ]
What's new
Meritum Engine β Changelog v1.1 β v1.2
Target version: Minecraft 1.26.30+ | Script API 2.7.0 (was 1.21.100 / API 2.1.0 on v1.1)
ποΈ Project structure
- Full script reorganization:
engine.js,command.js, andutils.jswere moved into acore/folder, signaling they're the "core" and shouldn't be touched. main.jsgot slimmed down (92 β 53 lines): it now only handles the external registration listener (meritum_engine:register_achievement).- New
achievements.js: the internal example achievements (first_join, play_1_hour, play_5_hours, play_10_hours) were moved out ofmain.jsinto this file β meant to be the one file devs should edit, without touching the core. - New
ui.js: all menu/interface logic (previously insideengine.js) was extracted here, including the new Settings screen. manifest.json(Beh and Res): version 1.1.0 β 1.2.0,min_engine_version1.21.100 β 1.26.30, Script API 2.1.0 β 2.7.0, and the CurseForge URL was added to the Beh Pack manifest.
βοΈ Engine changes (engine.js, 435 β 825 lines)
Category indexing (performance)
- New
indexAchievement/unindexAchievement: each achievement is now indexed by category (eventual,mining, etc.) in a Set, so detection loops only iterate the achievements relevant to that category β previously the loop went through every registered achievement on every tick/event, even ones from other categories. - New
unregisterAchievement(id, options).
New achievement categories
- Interaction (interacting with a block or entity) β didn't exist in v1.1.
- Breeding (offspring born from bred parents, with
playerRadiusto credit nearby players) β also new.
logic system ("and"/"or")
- v1.1 had no such concept β each category was checked independently and unlocked on its own.
- v1.2 introduces
logic: "and" | "or"to control whether all of an achievement's categories must be satisfied, or just one.
Mining / Combat / Interaction β durability
- v1.1: durability comparison was exact-match only (
currentDurability != target.itemStack.durabilityβ a bug, practically never matched). - v1.2: supports a range (
{ min, max }) or a comparison with operator ({ value, operator },<,<=,>,>=,==,!=). - Mining and Interaction also gained the
exceptionfield (a list of substrings to exclude variants, e.g. ignoringstripped_logs).
Combat β more granularity
- New fields:
projectileandprojectileSource(enables achievements like "kill the ghast with its own reflected fireball"). originis more robust now: if omitted, it credits the attacker and falls back to the victim (e.g. fall damage with no clear attacker).
Obtaining β reworked
itemnow accepts a list of{ id, min }entries (withiditself able to be an array of alternatives) β simpler before.armorgainedlogic: "and"/"or"per slot.- New
accumulate: instead of checking a minimum count, it permanently tracks which items in the list the player has ever held (even briefly), for achievements like "collect every type of ore." - Checks now run against an incremental inventory cache (updated via change events instead of a full rescan on every check) β another performance improvement that didn't exist in v1.1.
Eventual β the category that grew the most
In v1.1, eventual only supported beforeTime, dimension, and nextEntity. v1.2 adds:
layer(Y-height range)weather(reserved, but disabled β depends on the beta APIdimension.getWeather())biome(as a filter, or as a tracking flag when combined withaccumulate)riding(any mount, or a specific one)timeOfDayeffects(multiple simultaneous potion effects)volume(fixed cuboid region)nextBlock(nearby block within a radius, for POIs with no fixed location)distanceTraveled(cumulative odometer-style distance, persisted across sessions)accumulate(persistent "collect every X" set, with a built-inuniverse:all_biomes,overworld_biomes,nether_biomes,end_biomes, or a custom array, andrequire: "all"or a specific number)
Storage and flushing
- New dedicated
flushPlayerandgetAchievementCollectionProgress(progress like "5/64 biomes visited," meant for UI/commands). - Brand-new distance-traveled cache (
clearDistanceStateForPlayer,loadDistanceState,trackDistanceTraveled).
π§° utils.js (105 β 561 lines)
Almost all of the content is new:
- Per-slot inventory cache (
readSlotData,getOrCreateSlotCache,rescanInventory,ensureInitialized,updateInventorySlot,clearInventoryCache,getInventorySlotData) β backs the new incremental Obtaining system. - Per-player UID system (
generateUUID,createUID,getUID,setUID,playerFromUID,cachePlayerUID,ensureUID) β persistence across sessions for data like distance traveled. matchAdaptiveNumber(reusable min/max/operator comparisons) andmatchBiome.formatNameIdnow accepts a secondnameSpacesparameter (namespace-prefix-to-lang-key mapping) β tied to the newnameSpacesblock inconfig.js.- The entire
accumulatesystem (resolveUniverse,clearAccumulateCache,loadAccumulateSet,saveAccumulateSet,recordAccumulateAndGetProgress,recordAccumulate,evaluateCollectionProgress,getCollectionProgress).
π₯οΈ Interface (ui.js β new file, extracted from engine.js)
- New per-player Settings screen: sort by default/rarity/status/name, reverse order, and show-only-unlocked toggle.
- Preferences are kept per player in memory (reset on leave/game close β a deliberate design choice, not a bug).
- Rarity sort weight (
rarityWeight) is automatically derived from the key order inconfig.rarity, so it doesn't need manual updates when a new rarity tier is added.
πΉοΈ command.js
- The
showAchievementsimport moved fromengine.jsto../ui.js(reflects the UI extraction). - All
.replace(...)calls became.replaceAll(...)β fixes placeholders that appeared more than once in the same string and weren't all being substituted. - Fixed a bug in
/achsearch: a reference toText.errors.listSearch(theTextvariable didn't exist) βTextCMD.errors.listSearch. - Fixed
/achgive: it usedTextCMD.success.give, which didn't exist in v1.1'sconfig.js(the command had neither the config entry nor the lang key for its success message) β now it exists (success.givein config +MeritumEngine.cmd.success.givein lang).
π§ config.js
- New
nameSpacesblock (item-prefix-to-lang-key mapping, includingeternitys_reforged:,more:,theUltimate:). - New
colorsblock (color code aliases: bold, reset, italic, gray, gold, red, white, yellow). - New
textUiSettingsblock for the Settings screen (title, sort labels, etc.), with asortOptionsgetter that derives the dropdown list directly fromsortLabels. - Added
success.givetotextCmd(missing in v1.1). - Added
settingstotextUi.
π Localization β key cleanup
- Removed the custom key
MeritumEngine.message.achievements("Achievement Unlocked:" message) β replaced with the vanilla key%achievement.get. - Added new keys for the Settings screen (
MeritumEngine.ui.settings.*β sortBy, reverseOrder, onlyUnlocked, and the 4 sort labels) across all 10 of the addon's languages. - Added
MeritumEngine.cmd.success.giveacross all languages.
π Example achievements (achievements.js)
MeritumEngine.first_join: the welcome reward (5x oak_log) was removed β the achievement now grants no reward at all (rewards: {}).- The other three (play_1_hour, play_5_hours, play_10_hours) remain unchanged.
π Quick summary
| Area | v1.1 | v1.2 |
|---|---|---|
| Supported categories | Mining, Combat, Obtaining | + Interaction, Breeding |
| Multi-category logic | Doesn't exist | logic: "and"/"or" |
| Eventual β fields | beforeTime, dimension, nextEntity | +layer, weather (disabled), biome, riding, timeOfDay, effects, volume, nextBlock, distanceTraveled, accumulate |
| Obtaining β accumulate | Doesn't exist | Yes |
| Durability | Exact match only | Range/operator |
| Category indexing | No | Yes (performance) |
| Inventory cache | Full rescan | Incremental, per slot |
| Settings UI | Doesn't exist | Yes (sort/reverse/only unlocked) |
| Collection progress (X/Y) | Doesn't exist | getAchievementCollectionProgress |
| File structure | Everything together | core/ (engine) + editable achievements.js + ui.js |
All Relations
- All Relations
- Embedded Library
- Optional Dependency
- Required Dependency
- Tool
- Incompatible
- Include
This mod has no related projects

