@Overrideprotected void onPluginStart() { // Startup logic Common.log("MyPlugin has started!");}@Overrideprotected void onPluginStop() { // Shutdown logic Common.log("MyPlugin is stopping...");}
Foundation occupies onEnable() and onDisable() to perform automatic registration and cleanup, so you must use onPluginStart() and onPluginStop() instead.
3
Update getInstance() method
If you use a static getInstance() method, update it to use Foundation’s instance management:Before:
// Remove the instance field and initialization// private static MyPlugin instance; ❌ DELETE THIS// instance = this; ❌ DELETE THISpublic static MyPlugin getInstance() { return (MyPlugin) SimplePlugin.getInstance();}
Foundation automatically manages the plugin instance, so you don’t need to store it yourself.
4
Verify shading configuration
Before proceeding, double-check your pom.xml or build.gradle has the proper shading configuration as described in the installation guide.Your maven-shade-plugin should include:
Let’s create a simple command without using plugin.yml:
1
Create command class
Create a new class extending SimpleCommand:
import org.mineacademy.fo.command.SimpleCommand;import org.bukkit.entity.Player;public class HelloCommand extends SimpleCommand { public HelloCommand() { super("hello"); setDescription("Say hello to the player"); setUsage("/<command> [player]"); } @Override protected void onCommand() { checkConsole(); // Ensure only players can run this Player player = getPlayer(); if (args.length == 0) { tell("Hello, " + player.getName() + "!"); } else { Player target = findPlayer(args[0]); tell("You said hello to " + target.getName() + "!"); } }}
Notice there’s no plugin.yml configuration needed. Foundation automatically registers the command.
2
Register the command
In your main plugin class, register the command in onPluginStart():
import org.bukkit.Material;import org.bukkit.entity.Player;import org.bukkit.inventory.ItemStack;import org.mineacademy.fo.menu.Menu;import org.mineacademy.fo.menu.button.Button;import org.mineacademy.fo.menu.model.ItemCreator;import org.mineacademy.fo.remain.CompMaterial;public class WelcomeMenu extends Menu { private final Button infoButton; public WelcomeMenu() { setTitle("Welcome Menu"); setSize(9 * 3); // 3 rows // Create a button this.infoButton = new Button() { @Override public void onClickedInMenu(Player player, Menu menu, ClickType click) { player.sendMessage("You clicked the info button!"); } @Override public ItemStack getItem() { return ItemCreator.of( CompMaterial.BOOK, "Information", "", "Click me for info!" ).build().make(); } }; } @Override public ItemStack getItemAt(int slot) { if (slot == 13) // Center of the menu return this.infoButton.getItem(); return null; }}
Foundation provides auto-updating configuration with comments:
1
Create settings class
import org.mineacademy.fo.settings.YamlStaticConfig;public class Settings extends YamlStaticConfig { public static String WELCOME_MESSAGE; public static Integer MAX_PLAYERS; public static Boolean DEBUG_MODE; @Override protected void onLoad() { loadConfiguration("settings.yml"); } private static void load() { setPathPrefix("Settings"); WELCOME_MESSAGE = getString("Welcome_Message", "Welcome to the server!"); MAX_PLAYERS = getInteger("Max_Players", 100); DEBUG_MODE = getBoolean("Debug_Mode", false); }}
2
Create default config file
Create src/main/resources/settings.yml:
# Main plugin settingsSettings: # Message shown to players on join Welcome_Message: "Welcome to the server!" # Maximum number of players Max_Players: 100 # Enable debug logging Debug_Mode: false
3
Use settings in your code
@Overrideprotected void onPluginStart() { // Settings are automatically loaded Common.log("Welcome message: " + Settings.WELCOME_MESSAGE); if (Settings.DEBUG_MODE) { Common.log("Debug mode is enabled"); }}
import org.mineacademy.fo.Common;// Send colored messagesCommon.tell(player, "&aThis is green text!");// Broadcast to all playersCommon.broadcast("&6Server announcement!");// Log to consoleCommon.log("This appears in console");
import org.mineacademy.fo.Common;// Run task later (in ticks, 20 ticks = 1 second)Common.runLater(20, () -> { player.sendMessage("This runs after 1 second!");});// Run task repeatedlyCommon.runTimer(20, 20, () -> { // Runs every second player.sendMessage("Tick!");});
import org.mineacademy.fo.PlayerUtil;// Kick player with a messagePlayerUtil.kick(player, "You have been kicked!");// Get player's pingint ping = PlayerUtil.getPing(player);// Check if player has permissionif (PlayerUtil.hasPerm(player, "myplugin.admin")) { // Do something}