Meritum Engine — v1.1
A modular achievement system designed for Minecraft Bedrock Script API add-ons.
Compatible with Minecraft 1.21.100+ Script API: 2.1.0


Overview
Meritum Engine is a script-based achievement system built for Minecraft Bedrock add-ons using the Script API.
It allows developers to register and manage custom achievements programmatically, while the engine automatically handles:
- Player progress storage
- Achievement detection
- Notification display
- Rewards
- Administrative control
The engine was designed to be reusable and modular, allowing other add-ons to integrate with it and register their own achievements without needing to modify or rewrite the core system.
Why Use Meritum Engine
Meritum Engine allows add-on developers to implement complex achievement systems without needing to build event tracking, persistence systems, or user interface logic from scratch.
By using the engine, developers only need to define the conditions for their achievements while the system automatically manages:
- Event detection
- Achievement validation
- Player data storage
- Notifications
- Rewards
This makes the engine suitable as a shared achievement layer across multiple add-ons.
How the Engine Works
The engine maintains an internal achievement registry where each achievement is registered using a unique identifier.
There are two ways to register achievements:
Method 1 — Internal (modify the engine)
Call registerAchievement directly inside the engine's own files:
registerAchievement("example.mine_block", {
name: "Stone Breaker",
description: "Break a stone block.",
rarity: "common",
category: {
mining: {
target: {
block: "minecraft:stone"
}
}
}
});
Method 2 — External (no engine modification required)
Other add-ons can register achievements at runtime by sending a script event. The engine listens for meritum_engine:register_achievement and processes the payload automatically.
import * as MC from "@minecraft/server";
const achievements = {
"myaddon.my_achievement": {
name: "My Achievement",
description: "Do something.",
rarity: "common",
category: {
eventual: { target: { beforeTime: 3 } }
}
}
};
MC.world.afterEvents.worldLoad.subscribe(() =>
MC.system.sendScriptEvent(
"meritum_engine:register_achievement",
JSON.stringify(achievements)
)
);
The payload must be a valid JSON object where each key is the achievement ID and each value is its configuration. No imports from the engine are required.
Once an achievement is registered and its condition is met:
- The achievement is unlocked.
- The player receives a notification.
- Rewards (if configured) are granted.
- The achievement is stored permanently.
Achievement Storage System
Player progress is stored using Dynamic Properties.
Each player has a serialized JSON object saved under:
meritum:achievements
Example stored structure:
{
"example.mine_block": true,
"example.kill_zombie": true
}
The engine uses an in-memory cache to avoid repeatedly reading dynamic properties during gameplay.
Changes are periodically written back to the player.
This design improves performance while maintaining persistent data.
Achievement Detection System
The engine monitors several gameplay events to determine when achievements should be unlocked.
Supported categories include:
- Mining Achievements
- Combat Achievements
- Item Obtaining Achievements
- Eventual Achievements
Each achievement can belong to one or more categories simultaneously. When multiple categories are defined, the logic field controls the unlock behavior:
"or" (default) — unlocks when any category condition is met.
"and" — unlocks only when all category conditions are met.
registerAchievement("example.warrior", {
name: "Warrior",
description: "Wear iron armor and kill a zombie.",
rarity: "uncommon",
logic: "and",
category: {
obtaining: {
target: {
armor: { head: "minecraft:iron_helmet", chest: "minecraft:iron_chestplate",
legs: "minecraft:iron_leggings", feet: "minecraft:iron_boots" }
}
},
combat: {
target: { origin: "attacker", attacker: "minecraft:player",
victim: "minecraft:zombie", isDead: true }
}
}
});
Mining Achievements
Triggered when a player breaks a block.
Conditions may include:
- Block type (single ID or list)
- Block exceptions (exclude subtypes by substring)
- Tool used
- Tool durability
Example:
category: {
mining: {
target: {
block: ["minecraft:diamond_ore", "minecraft:deepslate_diamond_ore"]
}
}
}
Combat Achievements
Triggered when an entity takes damage.
Conditions may include:
- Victim entity type
- Attacker entity type
- Which entity owns the achievement (
origin: "attacker" or "victim")
- Minimum damage dealt
- Weapon used
- Whether the victim died
Example:
category: {
combat: {
target: {
origin: "attacker",
victim: "minecraft:zombie",
attacker: "minecraft:player",
isDead: true
}
}
}
Item Obtaining Achievements
Triggered when the player has specific items in their inventory or equipment slots.
Conditions may include:
- Inventory items (single or multiple)
- Minimum item counts
- Equipped armor pieces
Both item and armor can be required simultaneously within the same obtaining target.
Example:
category: {
obtaining: {
target: {
item: [
{ id: "minecraft:diamond", min: 3 }
]
}
}
}
Eventual Achievements
Triggered after the player remains in a certain condition for a set amount of time. Checked every 5 ticks.
Conditions may include:
beforeTime — time in seconds the player must remain in the condition
dimension — restricts detection to a specific dimension (e.g. "minecraft:nether")
nextEntity — requires a specific entity type within a radius; resets the timer if the entity moves out of range
Example use cases:
- Joining the world for the first time
- Staying in a dimension for a period of time
- Remaining near a specific entity
Example:
category: {
eventual: {
target: {
beforeTime: 30,
dimension: "minecraft:nether",
nextEntity: {
entity: "minecraft:elder_guardian",
radius: 5
}
}
}
}
Rarity System
Achievements are categorized using configurable rarity tiers.
Each rarity defines:
- Display color
- Unlock sound
- Sound pitch
- Sound volume
Default rarity tiers included:
- Common
- Uncommon
- Rare
- Epic
- Legendary
- Divine
Example configuration:
rare: {
color: "§e",
sound: "random.levelup",
volume: 1,
pitch: 0.9
}
When an achievement is unlocked, the rarity determines how the notification is displayed.
โ ๏ธ Rarity does not affect the difficulty of an achievement. It only changes visual and sound effects.
Achievement Notifications
When a player unlocks an achievement, the engine:
- Sends a formatted global message.
- Plays a rarity-based sound effect.
- Stores the achievement in player data.
Example notification format:
The formatting can be customized in the engine configuration.
Rewards System
Achievements may optionally grant rewards.
Supported reward types include:
- Items
Item rewards are spawned at the player's location.
Example:
rewards: {
give: [
{ item: "minecraft:diamond", quantity: 2 }
]
}
- Experience
Experience points are granted gradually over multiple ticks.
Example:
rewards: {
xpReward: 5
}
XP rewards are internally multiplied by 5 and delivered as individual experience increments, one per tick.
Command System
Meritum Engine includes a modular command system designed for both players and administrators.
Commands are separated by purpose and use a shared internal command builder, making the system easier to maintain and extend.
Several commands support built-in pagination to prevent chat overflow when listing large numbers of achievements.
Player Commands
- /achmenu
Opens the achievements interface menu.
- /achlist [page]
Displays a paginated list of all registered achievements.
- /achsearch <keyword> [page]
Searches achievements by name or identifier.
- /achinfo <achievementId>
Displays detailed information about a specific achievement.
- /achprogress [player]
Shows how many achievements a player has unlocked.
Administrative Commands
- /achgive <player> <achievementId>
- /achrevoke <player> <achievementId>
- /achreset <player>
User Interface
The engine includes a UI panel that allows players to:
- Browse achievements
- View descriptions
- Check unlock status
- See reward information
The interface also supports pagination (configurable in the files).
UI text and formatting can be customized in the configuration file.
Performance Considerations
To reduce performance overhead, the engine:
- Uses cached player achievement data
- Writes data to dynamic properties periodically (~every 10 seconds)
- Runs detection checks at controlled intervals
The system is designed to remain lightweight even when handling large numbers of achievements.
However, developers should avoid registering extremely large numbers of achievements with complex detection conditions.
Important Considerations
- This project is currently under active development.
- Features may change and occasional bugs may occur while the engine evolves.
- Achievements are not connected to Xbox Live achievements.
- The system operates independently within the add-on environment.
- Achievement IDs must remain unique across all add-ons using the engine.
- The add-on can also be configured directly through the config.js file.
- Multi-category progress using
logic: "and" is not persisted between sessions — if the player disconnects before completing all categories, progress resets.
Usage & Redistribution
Allowed
- Using Meritum Engine as a dependency in your own add-ons or projects.
- Configuring the engine for personal or project use.
- Distributing your own add-on that uses Meritum Engine.
Not Allowed
- Reuploading or redistributing the engine itself without permission.
- Publishing modified versions of the engine or its configuration without permission.
- Reposting this project on other platforms instead of linking to the official page.
Credits
- If you use Meritum Engine in a public project, giving credit to the original author is highly appreciated.
- When sharing the engine, please link to the official project page instead of reuploading the files.
Languages & Credits
- ๐บ๐ธ English
- ๐ง๐ท Português (BR)
- ๐ต๐น Português (PT)
- ๐ช๐ธ Español
- ๐ซ๐ท Français
- ๐ท๐บ ะ ัััะบะธะน
- ๐ฎ๐ฉ Bahasa Indonesia
- ๐ฏ๐ต ๆฅๆฌ่ช
- ๐ฐ๐ท ํ๊ตญ์ด
- ๐จ๐ณ ไธญๆ
Leave your feedback so that the engine can continue improving in the future ;)