Troubleshooting & Debugging
Common issues and how to solve them.
Debugging Mindset
When something doesn't work, the first instinct is "the API is broken" or "this shouldn't work this way". Usually it's a small detail - wrong event name, forgot to subscribe, typo. Use logging (console.log) to understand what's actually happening.
Script Not Loading
Problem: Your add-on doesn't run or errors appear
Error: Failed to load script
Solutions:
- Check manifest.json has correct entry point
- Verify script file is in correct folder
- Enable world logging to see errors
- Check console for syntax errors
// Add debug logging to track execution
console.log("Script loading..."); // Add at top of file
world.afterEvents.worldInitialize.subscribe(() => {
console.log("World initialized - script is working!");
});
Events Not Firing
Problem: Player events or block events aren't triggering
Common mistake: Using the wrong object. Events are on world, not on the player or block:
// Wrong - won't work (players don't have event subscriptions)
player.afterEvents.playerJoin.subscribe(() => {
console.log("Player joined");
});
// Correct - use world (server-wide events)
world.afterEvents.playerJoin.subscribe((event) => {
console.log("Player joined: " + event.player.nameTag);
});
Why? world is the server object that tracks everything. Individual players don't emit events - the world does.
Permission Errors
Problem: "Player lacks permission" error
Error: Entity does not have permission to run command
Solution: Check player permissions in world settings
- Creator mode disabled → Limited permissions
- Enable Creator mode or use alternative methods
- Don't use commands in survival mode scripts
// Instead of runCommand, use direct API
// Wrong:
player.runCommand("say hello");
// Right:
player.sendMessage("hello");
Null Reference Errors
Problem: "Cannot read property of undefined"
This happens when you assume something exists but it doesn't:
// Wrong - crashes if no players online (getAllPlayers returns empty array)
const player = world.getAllPlayers()[0];
player.sendMessage("Hello"); // ERROR: player is undefined
// Right - check first
const players = world.getAllPlayers();
if (players.length > 0) {
players[0].sendMessage("Hello");
}
// Or use optional chaining (?. skips if null)
world.getAllPlayers()[0]?.sendMessage("Hello");
Why? Always assume things might be null. An empty query, a deleted entity, a player who left - these happen. Defensive coding prevents crashes.
Performance Issues
Problem: Game lags when script runs
// Bad - runs every tick on all players
world.afterEvents.entityTick.subscribe((event) => {
if (event.entity.typeId === "minecraft:player") {
// Heavy computation here
calculateComplexPath(event.entity);
}
});
// Better - use intervals instead
let lastCheck = 0;
const checkInterval = 1000; // 1 second
world.afterEvents.entityTick.subscribe((event) => {
const now = Date.now();
if (event.entity.typeId === "minecraft:player" &&
now - lastCheck > checkInterval) {
lastCheck = now;
calculateComplexPath(event.entity);
}
});
Data Not Saving
Problem: SuperDB data disappears
// Make sure to save data
const playerDB = new SuperDB({ name: "players", immediateWrite: true });
// Wrong - data not saved
const player = playerDB.get("player_id");
player.level = 10; // Changed but not saved!
// Right - save after changes
const player = playerDB.get("player_id");
player.level = 10;
playerDB.set("player_id", player); // Save it
Item Not Appearing
Problem: Items given to players don't show up
// Wrong - wrong syntax
const item = new ItemStack("diamond_sword");
player.addItem(item);
// Right - use container
const item = new ItemStack("diamond_sword", 1);
player.container.addItem(item);
// Check if inventory is full
const success = player.container.addItem(item);
if (!success) {
player.sendMessage("§cYour inventory is full!");
}
Command System Issues
Problem: Custom chat commands not working
// Make sure to cancel the event
world.beforeEvents.chatSend.subscribe((event) => {
if (event.message.startsWith("!help")) {
// Without this, command shows in chat
event.cancel = true;
event.sender.sendMessage("§6=== Help ===");
}
});
Block Breaking Not Prevented
Problem: Can't prevent players from breaking blocks
// Wrong - doesn't work
world.afterEvents.blockBreak.subscribe((event) => {
event.cancel = true; // This event can't be canceled
});
// Right - restore the block
world.afterEvents.blockBreak.subscribe((event) => {
const block = event.block;
const player = event.player;
if (block.typeId === "minecraft:obsidian") {
// Restore the block
world.getDimension("overworld").setBlockType(
block.location,
"minecraft:obsidian"
);
player.sendMessage("§cYou cannot break obsidian!");
}
});
Teleport Not Working
Problem: Players won't teleport
// Make sure player has update tick
world.afterEvents.playerSpawn.subscribe((event) => {
const player = event.player;
// Teleport after a tick to ensure chunks are loaded
system.run(() => {
player.teleport({ x: 0, y: 64, z: 0 });
});
});
Memory Leaks
Problem: Game slows down over time
// Bad - interval never stops
const interval = setInterval(() => {
// Code here
}, 1000);
// Good - stop when needed
const intervals = [];
function startMonitoring() {
const id = setInterval(() => {
// Code here
}, 1000);
intervals.push(id);
}
function stopMonitoring() {
intervals.forEach(id => clearInterval(id));
intervals.length = 0;
}
// Or use system.run for one-time execution
system.run(() => {
// Runs once per tick, no memory leak
});
Debugging Tips
Add logging everywhere:
console.log("Starting script");
console.log("Player joined: " + player.nameTag);
console.log("Current level: " + playerData.level);
Check types:
console.log(typeof entity); // "object"
console.log(entity.typeId); // "minecraft:player"
console.log(entity instanceof Entity); // true/false
Use conditional logging:
const DEBUG = true;
if (DEBUG) {
console.log("Debug info: " + value);
}
Test in isolation:
// Test just your function
function testDamageCalculation() {
const damage = calculateDamage(10, 2);
console.log("Damage: " + damage);
// Should log: Damage: 20
}
testDamageCalculation();