Production-Grade JavaScript Scripting Framework for Minecraft Paper Servers
Features • Installation • Quick Start • Documentation • Examples • Contributing
ScriptsLab is a powerful, production-ready plugin framework for Paper/Spigot servers that enables server administrators and developers to create custom gameplay features using JavaScript. Built on GraalVM, it provides a clean, modern API with full access to the Bukkit/Paper API.
| Feature | Description |
|---|---|
| 🚀 Zero Restart Required | Hot-reload scripts without restarting your server |
| 🎯 Clean Architecture | Modular design with dependency injection |
| ⚡ High Performance | Powered by GraalVM JavaScript engine |
| 🔒 Thread-Safe | Automatic synchronization for Bukkit API calls |
| 🎨 Rich API | Commands, events, items, storage, scheduler, and more |
| 📦 Module System | Organize code into reusable modules |
| 🛠️ Developer Friendly | Modern JavaScript with full IDE support |
- 🎮 Command System - Register custom commands with permissions
- 📡 Event System - Listen to any Bukkit/Paper event
- ⚔️ Custom Items - Create items with custom abilities and attributes
- 💾 Storage System - YAML-based persistent data storage
- ⏰ Task Scheduler - Sync/async task scheduling
- 📊 Metrics Collection - Built-in performance monitoring
- 🔌 Module System - Hot-loadable plugin modules
- Thread-Safe API - Automatic main-thread scheduling for Bukkit calls
- Dependency Injection - Clean service architecture
- Event Bus - Internal plugin communication
- Script Hot-Reload - Update scripts without restart
- Unrestricted Mode - Full Java API access (configurable)
| Requirement | Version |
|---|---|
| Minecraft Server | Paper 1.21.8+ (or compatible Spigot fork) |
| Java | 17 or higher |
| Memory | Minimum 2GB RAM (GraalVM included in JAR) |
-
Download the latest
ScriptsLab-1.0.0.jarfrom Releases -
Install the plugin:
cp ScriptsLab-1.0.0.jar /path/to/server/plugins/
-
Start your server:
java -Xmx2G -jar paper.jar
-
Verify installation:
[ScriptsLab] ✓ Script Engine initialized [ScriptsLab] ✓ Loaded X scripts
Create a file plugins/ScriptsLab/scripts/hello.js:
Commands.register('hello', function(sender, args) {
sender.sendMessage('§aHello, ' + sender.getName() + '!');
}, 'scriptslab.hello');
Console.log('Hello command registered!');That's it! The script loads automatically. Use /hello in-game.
Commands.register('fly', function(sender, args) {
if (!sender.isPlayer()) {
sender.sendMessage('§cOnly players can fly!');
return;
}
var flying = !sender.getAllowFlight();
sender.setAllowFlight(flying);
if (flying) {
sender.sendMessage('§aFlight enabled!');
} else {
sender.sendMessage('§cFlight disabled!');
}
}, 'scriptslab.fly');API.registerEvent('PlayerJoinEvent', function(event) {
var player = event.getPlayer();
var Bukkit = Java.type('org.bukkit.Bukkit');
event.joinMessage(null);
player.sendMessage('§6§l⚡ Welcome to the server!');
player.sendMessage('§7Online: §a' + Bukkit.getOnlinePlayers().size());
});Commands.register(name, handler, permission);
Commands.register('heal', function(sender, args) {
sender.setHealth(sender.getMaxHealth());
sender.sendMessage('§aHealed!');
}, 'scriptslab.heal');API.registerEvent(eventName, handler);
API.registerEvent('PlayerDeathEvent', function(event) {
var player = event.getPlayer();
Console.log(player.getName() + ' died!');
});Items.registerItem(id, material, displayName, ...lore);
Items.giveItem(player, itemId, amount);
API.addAttribute(meta, 'GENERIC_ATTACK_DAMAGE', 'modifier_name', 10.0, 'ADD_NUMBER', 'HAND');Scheduler.runLater(function() {
Console.log('Delayed task!');
}, 20);
Scheduler.runTimer(function() {
Console.log('Every second!');
}, 0, 20);
Scheduler.runAsync(function() {
// Heavy computation
});var repo = Storage.getRepository('mydata');
repo.set('player.uuid', playerData);
repo.save();
var data = repo.get('player.uuid');API.addPotionEffectSync(player, effectType, duration, amplifier, ambient, particles);
API.strikeLightningSync(location);
API.removePotionEffectSync(player, effectType);Console.log('Info message');
Console.warn('Warning message');
Console.error('Error message');Complete example of a custom weapon with abilities:
var Material = Java.type('org.bukkit.Material');
var ItemStack = Java.type('org.bukkit.inventory.ItemStack');
Commands.register('getlightningsword', function(sender, args) {
if (!sender.isPlayer()) return;
var player = org.bukkit.Bukkit.getPlayer(sender.getName());
var sword = new ItemStack(Material.DIAMOND_SWORD);
var meta = sword.getItemMeta();
meta.setDisplayName('§6§l⚡ LIGHTNING SWORD ⚡');
meta.setUnbreakable(true);
API.addAttribute(meta, 'GENERIC_ATTACK_DAMAGE', 'lightning_damage', 10.0, 'ADD_NUMBER', 'HAND');
API.addAttribute(meta, 'GENERIC_ATTACK_SPEED', 'lightning_speed', 0.8, 'ADD_NUMBER', 'HAND');
sword.setItemMeta(meta);
player.getInventory().addItem(sword);
player.sendMessage('§6⚡ You received the Lightning Sword!');
});
API.registerEvent('EntityDamageByEntityEvent', function(event) {
var Player = Java.type('org.bukkit.entity.Player');
if (!(event.getDamager() instanceof Player)) return;
var attacker = event.getDamager();
var item = attacker.getInventory().getItemInMainHand();
if (item && item.getType() === Material.DIAMOND_SWORD) {
var meta = item.getItemMeta();
if (meta && meta.hasDisplayName() &&
meta.getDisplayName().indexOf('LIGHTNING SWORD') !== -1) {
var location = event.getEntity().getLocation();
API.strikeLightningSync(location);
event.setDamage(event.getDamage() + 5.0);
attacker.sendMessage('§6⚡ Lightning strikes!');
}
}
});More examples in the scripts/ directory!
ScriptsLab follows Clean Architecture principles:
┌─────────────────────────────────────┐
│ JavaScript Scripts │
│ (User-defined functionality) │
└─────────────────┬───────────────────┘
│
┌─────────────────▼───────────────────┐
│ Script API Layer │
│ (ScriptAPIImpl, Thread-Safety) │
└─────────────────┬───────────────────┘
│
┌─────────────────▼───────────────────┐
│ Core Services Layer │
│ (Commands, Events, Items, etc.) │
└─────────────────┬───────────────────┘
│
┌─────────────────▼───────────────────┐
│ Bukkit/Paper API Layer │
│ (Minecraft Server Platform) │
└─────────────────────────────────────┘
| Component | Description |
|---|---|
| GraalScriptEngine | GraalVM JavaScript execution |
| CommandManager | Dynamic command registration |
| EventBus | Event handling and distribution |
| ItemManager | Custom item management |
| StorageManager | Persistent data storage |
| TaskScheduler | Async/sync task scheduling |
| DI Container | Dependency injection |
- Java 17 JDK
- Maven 3.8+
- Git
git clone https://github.com/yourusername/ScriptsLab.git
cd ScriptsLab
mvn clean package -DskipTestsOutput: target/ScriptsLab-1.0.0.jar (~50MB with GraalVM)
mvn test # Run tests
mvn javadoc:javadoc # Generate documentation
mvn clean # Clean buildWe welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing code style
- Add tests for new features
- Update documentation
- Keep commits atomic and descriptive
This project is licensed under the MIT License - see the LICENSE file for details.
- GraalVM Team - For the amazing JavaScript engine
- Paper Team - For the excellent Minecraft server platform
- Bukkit/Spigot Community - For the plugin API foundation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Wiki: Documentation Wiki
Made with ❤️ for the Minecraft community
⭐ Star us on GitHub if you find this useful!