🌐 Store πŸ“€ Submit Extension

Build Extensions for TitanLogin

Create powerful addons that extend TitanLogin's functionality. No complicated setup β€” just Java, a JAR, and your creativity.

β˜• Java πŸ“¦ Simple JAR ⚑ Hot-Reload πŸ”Œ Full API Access

πŸ“‹ Overview

TitanLogin extensions are simple Java JAR files that get dropped into the plugins/TitanLogin/extensions/ folder. They can add new features, commands, GUIs, listeners β€” anything you can do with the Bukkit API.

πŸ’‘

It's like making a Bukkit plugin, but simpler. Just like how Bukkit plugins have a plugin.yml inside the JAR, your extension has an extension.yml inside the JAR. You write the code, build one .jar file, and that single file is everything.

How Extensions Work

  1. You create a Java project and extend TitanExtension
  2. You add an extension.yml file in your source code (at src/main/resources/)
  3. You build it β†’ Maven/Gradle automatically packages everything into one .jar file
  4. Server admins drop that single JAR into plugins/TitanLogin/extensions/
  5. TitanLogin reads extension.yml from inside the JAR and loads it automatically!
⚠️

Server admins only need the .jar file! The extension.yml is NOT a separate file β€” it lives inside your JAR. When you build with Maven, everything in src/main/resources/ is automatically included in the JAR.

πŸ”§ Requirements

πŸš€ Quick Start (5 Minutes)

1

Create Your Project

Create a new Java project in your IDE. Name it something like my-titanlogin-extension.

2

Add TitanLogin as a Dependency

Add the TitanLogin JAR and Spigot API as dependencies to your project:

<!-- pom.xml (Maven) -->
<dependencies>
    <!-- TitanLogin API - add as local JAR -->
    <dependency>
        <groupId>com.titanlogin</groupId>
        <artifactId>TitanLogin</artifactId>
        <version>1.5</version>
        <scope>provided</scope>
    </dependency>

    <!-- Spigot API -->
    <dependency>
        <groupId>org.spigotmc</groupId>
        <artifactId>spigot-api</artifactId>
        <version>1.20.4-R0.1-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
πŸ“Œ

Set scope to provided β€” TitanLogin and Spigot are already on the server, you don't want to include them in your JAR.

3

Create Your Main Class

package com.example.myextension;

import com.titanlogin.extensions.TitanExtension;

public class MyExtension extends TitanExtension {

    @Override
    public void onEnable() {
        getLogger().info("My Extension is now active! πŸŽ‰");
    }

    @Override
    public void onDisable() {
        getLogger().info("My Extension disabled.");
    }
}
4

Create extension.yml (in your source code)

Create a file called extension.yml in your project's src/main/resources/ folder. This file gets automatically packaged inside your JAR when you build β€” you don't need to distribute it separately:

name: "My Extension"
version: "1.0"
author: "YourName"
main: "com.example.myextension.MyExtension"
description: "A cool extension that does something awesome!"
api-version: 1
category: "Utility"
πŸ“¦

Think of it like plugin.yml in Bukkit plugins β€” it's part of your project, and Maven puts it inside the JAR automatically. Server admins never see or touch this file.

5

Build & Install

Build your project (mvn package) β†’ this creates one single JAR file containing your code + extension.yml. Drop that JAR into plugins/TitanLogin/extensions/ and run /tl extensions reload. That's it!

🎯

What goes where:
β€’ MyExtension.jar β†’ plugins/TitanLogin/extensions/ (the ONLY file needed!)
β€’ Your code + extension.yml are INSIDE the JAR β€” nothing else to copy!

πŸ“ Project Structure

A typical extension project looks like this:

my-extension/
β”œβ”€β”€ pom.xml (or build.gradle)
└── src/main/
    β”œβ”€β”€ java/com/example/myextension/
    β”‚   β””── MyExtension.java
    β””── resources/
        β””── extension.yml  β† Required!

πŸ“ extension.yml Reference

This file tells TitanLogin about your extension. Place it at src/main/resources/extension.yml in your project β€” Maven/Gradle will automatically include it in the root of your JAR when you build.

# Required fields
name: "Login Rewards"          # Unique name
version: "1.0"                  # Your version
author: "YourName"              # Your name
main: "com.example.Rewards"     # Full class path

# Recommended fields
description: "Daily login rewards!"
api-version: 1                  # TitanLogin API version
category: "Gameplay"            # Authentication, Security,
                                  # Visual, Gameplay, Utility

# Optional
icon: "DIAMOND"                 # Minecraft material name
dependencies:                   # Other extensions needed
  - "Some Other Extension"

πŸ—οΈ Main Class β€” TitanExtension

Your main class must extend TitanExtension. Here's what you get access to:

public class MyExtension extends TitanExtension {

    @Override
    public void onEnable() {
        // Called when your extension is enabled
        // Register listeners, commands, etc. here

        // Access the main TitanLogin plugin
        getTitanLogin().getServer().broadcastMessage("Extension loaded!");

        // Your extension's data folder
        // plugins/TitanLogin/extensions/MyExtension/
        getDataFolder().mkdirs();

        // Load/save config
        getConfig().set("enabled", true);
        saveConfig();

        // Logging
        getLogger().info("Hello from my extension!");
    }

    @Override
    public void onDisable() {
        // Cleanup when extension is disabled
    }
}

πŸ“š API Reference

Methods Available in TitanExtension

Method Returns Description
getTitanLogin() TitanLogin Main plugin instance β€” access everything
getDataFolder() File Your extension's private data folder
getConfig() FileConfiguration Your extension's config.yml
saveConfig() void Save config to disk
reloadConfig() void Reload config from disk
getLogger() Logger Logger with your extension's name prefix
getName() String Extension name from extension.yml
getVersion() String Extension version
isEnabled() boolean Whether extension is currently enabled

πŸ“¦ Example: Login Rewards

Give players items when they log in daily:

package com.example.rewards;

import com.titanlogin.extensions.TitanExtension;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;

public class LoginRewards extends TitanExtension
    implements Listener {

    @Override
    public void onEnable() {
        // Register this class as an event listener
        getTitanLogin().getServer().getPluginManager()
            .registerEvents(this, getTitanLogin());
        getLogger().info("Login Rewards enabled!");
    }

    @Override
    public void onDisable() {
        HandlerList.unregisterAll(this);
    }

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        // Give a diamond on login
        player.getInventory().addItem(
            new ItemStack(Material.DIAMOND, 1)
        );
        player.sendMessage("§a⚑ Daily reward: §b1 Diamond!");
    }
}

And the extension.yml:

name: "Login Rewards"
version: "1.0"
author: "YourName"
main: "com.example.rewards.LoginRewards"
description: "Give players daily rewards when they log in!"
category: "Gameplay"
api-version: 1

⌨️ Example: Custom Commands

Register a command that players can use:

package com.example.welcome;

import com.titanlogin.extensions.TitanExtension;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;

public class WelcomeExtension extends TitanExtension
    implements Listener {

    @Override
    public void onEnable() {
        getTitanLogin().getServer().getPluginManager()
            .registerEvents(this, getTitanLogin());
        // Load welcome message from config
        if (!getConfig().contains("message")) {
            getConfig().set("message", "&b⚑ Welcome to the server!");
            saveConfig();
        }
    }

    @Override
    public void onDisable() {
        HandlerList.unregisterAll(this);
    }

    @EventHandler
    public void onCommand(PlayerCommandPreprocessEvent e) {
        if (e.getMessage().equalsIgnoreCase("/welcome")) {
            e.setCancelled(true);
            String msg = getConfig().getString("message");
            e.getPlayer().sendMessage(
                org.bukkit.ChatColor.translateAlternateColorCodes('&', msg)
            );
        }
    }
}

πŸ–₯️ Example: Custom GUI

Create an inventory GUI:

package com.example.infogui;

import com.titanlogin.extensions.TitanExtension;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;

public class InfoGUI extends TitanExtension
    implements Listener {

    @Override
    public void onEnable() {
        getTitanLogin().getServer().getPluginManager()
            .registerEvents(this, getTitanLogin());
    }

    @Override
    public void onDisable() {
        HandlerList.unregisterAll(this);
    }

    @EventHandler
    public void onCmd(PlayerCommandPreprocessEvent e) {
        if (e.getMessage().equalsIgnoreCase("/serverinfo")) {
            e.setCancelled(true);
            openInfoGUI(e.getPlayer());
        }
    }

    private void openInfoGUI(Player player) {
        Inventory gui = Bukkit.createInventory(null, 27,
            ChatColor.translateAlternateColorCodes('&',
                "&b⚑ Server Info"));

        // Add items with info
        ItemStack info = new ItemStack(Material.BOOK);
        ItemMeta meta = info.getItemMeta();
        meta.setDisplayName("Β§bΒ§lServer Rules");
        meta.setLore(Arrays.asList(
            "Β§71. Be respectful",
            "Β§72. No griefing",
            "Β§73. Have fun!"
        ));
        info.setItemMeta(meta);
        gui.setItem(13, info);

        player.openInventory(gui);
    }
}

πŸ”¨ Building Your JAR

With Maven

Run mvn package β€” your JAR will be in the target/ folder.

With Gradle

Run gradle build β€” your JAR will be in build/libs/.

Without Build Tools

If you just want to compile manually:

# Compile
javac -cp TitanLogin.jar;spigot-api.jar -d out src/com/example/*.java

# Package (include extension.yml in JAR root)
jar cf MyExtension.jar -C out . -C resources .
⚠️

Important: Make sure extension.yml is in the root of your JAR file, not inside a subfolder. TitanLogin looks for it at the top level.

πŸ“€ Submitting to the Store

  1. Open the TitanLogin Extension Store
  2. Click "πŸ“€ Submit Extension"
  3. Fill in the details:
    • Name β€” your extension's display name
    • Version β€” current version number
    • Author β€” your name or team name
    • Description β€” what your extension does
    • Download URL β€” link to your .jar file (use GitHub Releases, Dropbox, Google Drive, etc.)
    • Category β€” best fitting category
  4. Submit! PRINCExd will review your extension
  5. Once approved, it appears in the store for everyone to download
βœ…

To get the Verified badge, your extension must be well-tested, have good documentation, and follow the guidelines below.

πŸ“ Extension Guidelines

βœ… Do

❌ Don't

🚫

Extensions that violate these guidelines will be rejected from the store. Repeated violations may result in a ban from submitting.

Ready to build? πŸš€

Create your extension and submit it to the store!

πŸ“€ Submit to Store