T-MiniGameAPI - feedback


Feedback score
Hey, I created the library to make creating minigames simpler. I want to get feedback about my library.
I would like to get to know your opinion about the systems and add-on concepts. Is the system implementation good or not? What can I improve in these systems?
Finally, I have a question for you, do you want to create a minigame with this library, why or why not?

GitHub: https://github.com/timsixth/MinigameAPI
Resource page: https://builtbybit.com/resources/t-minigameapi-minigame-library.40833/
Documentation: https://timsixths-plugins.gitbook.io/minigameapi-docs/
JavaDocs: https://timsixth.pl/javadocs/minigame_api/1.2.0/
Support discord server: https://discord.com/invite/zKmMy8bK56

Do you want to help me with developing this library?
Create a fork of this repository on github and create a pull request or join to discord server.

About library:
The library has a lot of features, I plan to add more interesting features, maybe a countdown to game start, kill streaks, and more

Basic features:
The common systems are important to work with this library. The most important system is configuration and configurators. I modeled this on the Spring configuration system, maybe security. In this system, I used a Builder design pattern to create a friendly configuration. What do you think about these concepts? Is it good or not?
The command system is provided by the API but, the library requires us to use this command system because add-on commands will not work. Thanks to this system you can create parent commands and subcommands.
The simple ORM system provides saving, updating, and deleting data from files or databases without the use of Bukkit YAML API, and writing SQL queries. Of course, it allows you to override methods and create your implementation. The latest of common systems is loading system, This system loads all data from file or database.

MiniGames features:
The first system is arena system is already implemented and it uses Bukkit serialization to store data in YAML. You can save the arena in one file, or a single arena has its own file. The file name is an arena name.
The second system is the game system, the system has teams, players which currently playing, and game states.
The third system is the coins system, which saves data in YAML or SQL database (you choose which type of storage you want). The system manages user coins, you can add, remove, and set user's coins.
The fourth system is a cosmetic system, which has two types of cosmetics, the first is a simple cosmetic, in this type, you can create what you want, and in the second you define particles that will be displayed when a player is walking or doing other actions, this type is called particle cosmetic. All cosmetics must be registered in the main class.
The fifth system is the statistic system, in my opinion, this system is the most advanced, it saves stats in YAML or SQL database, and the stats are saved to a single arena. The library provides a default stats system, this system saves only wins and loses in storage.

Addon in this context is a simple Java plugin which adds features which are not implemented in the main library. What do you think about this? Is it good or not and why?
May be addon can be for developers only and it will be added to the project. What concept is better ?
The best feature of addon is that can be installed by command or put in the addons directory in the T-MiniGameAPI directory.

All Library features:
  • Arena management system
  • Game management system
  • Game cosmetics system
  • Teams in-game
  • Advanced loading system from SQL databases (MySQL or SQLite) or YAML files
  • Game statistics system
  • Coins system
  • Simple minigame configuration
  • Integration with T-DataBasesAPI (Thanks to this plugin management of SQL databases is simple)
  • Simple saving, deleting, and updating system (You don't have to write queries to a database or use YAML spigot API to execute these actions)
  • Commands API (You can create parent commands and subcommands in separate classes)
  • Addons system (You can create an addon that will work with every game that uses this library)
Example of usages:

What is configuration?
Configuration is a set of settings that are necessary to build a minigame.
Default values for these settings are set in configurators.
The library has three types of configuration:
  1. PluginConfiguration - This configuration contains settings about plugin configuration
  • useDatabase (true|false) - enables or disables integration with SQL database (Not supported yet - disables only loading from database)
  • tablesPrefix (string) - prefix of every table in SQL database
  • useDefaultStatsSystem (true|false) - enables or disables using default stats system
  • arenaSaveType - (SINGLE_FILE | MANY_FILES) - sets arena save type (SINGLE_FILE - this type means arenas will be loaded from single file, MANY_FILES - every arena has single file)
  1. GameConfiguration
  • blockBreaking (true|false) - enables or disables breaking blocks during the game
  • blocksPlacing (true|false) - enables or disables placing blocks during the game
  • droppingItems (true|false) - enables or disables dropping itmes during the game
  1. CommandConfiguration
  • doNotHavePermissionMessage (string)- sets a message which will be displayed when player don't have permission
  • onlyPlayersMessage (string) - sets a message which will be displayed when a command is not for player
How to override the configurator?

Configurator defines default settings necessary to minigame work.
You can override the default configuration.

public class MyPluginConfigurator extends DefaultPluginConfigurator {

    public PluginConfiguration configure() {
        return PluginConfiguration.builder()
The model represents one object in YAML or database.
The model is updatable, savable, and deletable.
Every model must have a field that will be annotated Id or IdSection annotation. These methods are saving, updating and delating your data immediately.
Object save(); //Saves new model to database or file
boolean delete(); //Deletes model from file or table
Object update(); //Updates new model to database or file

//For example
User user = new User();
See more: https://timsixths-plugins.gitbook.io/minigameapi-docs/basic-features/models

Minigame features:
Arena is saved into a YAML file by default.
Every arena system functions are provided by the library.
You can create your arena loader, the default loader loads data from YAML file.
The arena system uses Bukkit serialization to store data.


The arena has a lobby location, name as arena ID, and a Map of locations.
How to create a new instance of Arena?
The first parameter is an arena's name.
The second parameter is the lobby location.
The third parameter is a map of locations.

ArenaFactory arenaFactory = MiniGame.getArenaFactory()
Arena arena = arenaFactory.createArena("arenaName", player.getLocation(), new HashMap<>());

Arena arena = arenaFactory.createArena("arenaName", player.getLocation());

How to manage arena locations?
void addLocation(name, location); //Adds new location
Map<String, Location> getLocations(); //Gets map of locations
void removeLocation(name); //Removes location from map
Location getLocationByName(name) //Gets location by name
Optional<Location> getLocation(name); //Gets location by name
The game system has methods to manage teams, game states, and rounds in the game.
The game class has methods:

Arena getArena(); //Gets arena which is using to play this game
List<UserGame> getPlayingUsers(); //Gets list of game users
GameState getState(); //Gets current game state
void setState(GameState gameState); //Sets new game state
Optional<UserGame> getUserGame(UUID uuid); //Gets UserGame by player's uuid
void sendMessage(String message); //Sends message to everyone who is playing on this game
int getRounds(); //Gets rounds amount
void setRounds(int rounds); //Sets rounds amount
void addRound(); //Adds one round to rounds
List<Team> getTeams(); //Gets list of teams
Optional<Team> getTeamByName(String name); //Gets team by name
Optional<Team> getTeamByPlayer(Player player); //Gets team by player
void addUserGame(UserGame userGame); //Adds a player to playing users
void removeUserGame(UserGame userGame); //Removes a player from playing users

How to create a new game instance?
Game game = new GameImpl(arena); //creates new game instance

UserGame userGame = new UserGameImpl(player.getUniqueId());

//create the first player who joined this game

game.addUserGame(userGame); //adds this player to list
gameManager.addGame(game); //adds this game to list

The game state is the state of the game that is currently running, maybe playing, starting .etc.

How to set a new game state?
game.setState(new MyState());
This state runs immediately after setting a new game state.

How to create a new GameState?
public class MyGameState implements GameState {

  public void run() {
     //define your logic

This class represents the user's coins.
In the class, the coins are saved in int type. In the future, this will be changed to double type.
How to create a new instance of the user?

UserCoinsFactory userCoinsFactory = MiniGame.getUserCoinsFactory();

UserCoins userCoins  = userCoinsFactory.createUserCoins(player.getUniqueId());

//or with default coins

UserCoins userCoins = userCoinsFactory.createUserCoins(player.getUniqueId(), 100.0);

UserCoins methods:

double getCoins(); //Gets coins
void setCoins(double coins); //Sets coins
void addCoins(double coins); //Adds coins
void removeCoins(double coins); //Removes coins
boolean hasCoins(double coins); //Chceks when player has coins

The default statistics system by default saves data in the database in the table users_stats.
Statistics are saved for an arena.
The library has a default statistics system, but you can implement your own.
The default statistics system saves only wins and loses.

How to enable the default stats system?
Set useDefaultStatsSystem to true in your PluginConfiguartion.


How to add stats to users?
UserStats userStats = statisticsManager.getUserStatsOrCreate(player, arena);
In the cosmetics system, there are two different types of cosmetics.
  • Cosmetic
  • ParticleCosmetic
Cosmetics must be registered in the main class.

How to create your cosmetics?
public class MyCosmetic implements Cosmetic {

public String getName() {

public void show(Player player) {
   //your logic

How to register comsetic?
getCosmeticsManager().addCosmetic(new MyCosmetic());
How to register more than one cosmetics?
getCosmeticsManager().addCosmetics(new MyCosmetic(), new MyParticleCosmetic());
How to unregister cosmetic?
getCosmeticsManager().removeCosmetic(new MyCosmetic());


Optional<UserCosmetics> userCosmeticsOptional = userCosmeticsManager.getUserByUuid(player.getUniqueId());

if (!userCosmetics=Optional.isPresent()) return;

UserCosmetics userCosmetics userCosmeticsDbModelOptional.get();

userCosmetics.addCosmetic(new MyCosmetic());
userCosmetics.enableCosmetic(new MyCosmetic());

boolean hasCosmetic(Cosmetic cosmetic); //Checks having cosmetic
void removeCosmetic(Cosmetic cosmetic); //Removes cosmetic
void addCosmetic(Cosmetic cosmetic); // Adds cosmetic
boolean isCosmeticEnable(Cosmetic cosmetic); //Checks that cosmetic is enabled
void enableCosmetic(Cosmetic cosmetic); //Enables cosmetic
void disableCosmetic(Cosmetic cosmetic); //Disables cosmetic