This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
AbstractMenus is a GUI plugin for SpigotMC/PaperMC Minecraft servers (1.20.6+) that allows creating custom inventory-based menus. Written in Java 21, it uses Gradle with PaperMC Paperweight userdev and Shadow plugin.
./gradlew build # Compile and run tests
./gradlew shadowJar # Create fat JAR with bundled dependencies (output: build/libs/AbstractMenus-<version>.jar)
./gradlew test # Run JUnit 5 tests onlyTests are in src/test/java/ using JUnit 5 (Jupiter). There are currently 4 test classes. Run a single test with:
./gradlew test --tests "ru.abstractmenus.TestValueComparator"ru.abstractmenus.AbstractMenus extends JavaPlugin. Initialization order in onEnable():
- Load
MainConfigfrom HOCON config - Initialize core services (VariableManager, BungeeManager, MenuManager, etc.)
- Register external provider handlers (Vault, LuckPerms, PlaceholderAPI, SkinsRestorer)
- Register type registries:
ItemProps→Activators→MenuActions→MenuRules→Catalogs - Load menus from disk, register event listeners
The plugin uses a centralized type registry (Types from the API module) where actions, rules, item properties, activators, and catalogs are registered by name. Each type has a corresponding NodeSerializer for HOCON deserialization. Registration happens in static init() methods:
MenuActions.init()— registers ~50 action types (e.g.,"openMenu"→ActionMenuOpen)MenuRules.init()— registers ~25 rule types (e.g.,"permission"→RulePermission)ItemProps.init()— registers ~25 item property types (e.g.,"material"→PropMaterial)Activators.init()— registers ~15 activator types (e.g.,"command"→OpenCommand)Catalogs.init()— registers catalog types
Menu (API interface)
├── AbstractMenu (base with title, size, items, rules, actions)
│ ├── SimpleMenu (standard inventory GUI)
│ ├── AnimatedMenu (frame-based animations)
│ └── GeneratedMenu (dynamic layout via Matrix)
data/— Largest package (~164 files). Contains all action, rule, activator, item property, and catalog implementations. Each has an innerSerializerclass.services/— Core managers:MenuManager(menu lifecycle, 20-tick update loop),BungeeManager,HeadAnimManager,ProfileStoragehandlers/— Abstraction layer over external plugins (Economy, Permissions, Levels, Placeholders, Skins). Accessed viaHandlersstatic facade.serializers/— HOCON deserialization:ItemSerializer,LocationSerializer, type adapterscommands/—/am,/var,/varpcommands and subcommandscommand/— Command framework (parsing, arguments, context)variables/— Global/player variable system with SQLite persistenceplaceholders/— PlaceholderAPI integration and built-in placeholder handlersmenu/— Menu classes, items, frameslisteners/— Bukkit event listeners (inventory clicks, chat, player join, WorldGuard regions)nms/— NMS code for ActionBar, Title, Book via reflectionextractors/— Context extractors (Block, Entity, NPC, ItemStack, Region, World)datatype/— Type wrappers (TypeBool, TypeInt, TypeLocation, TypeMaterial, etc.)
Menus and config use HOCON format (not YAML). The internal HOCON library is at ru.abstractmenus.hocon.
- API module:
com.github.AbstractMenus:api(separate repo, pulled via JitPack) - Lombok: Used throughout for
@Getter/@Setter/@AllArgsConstructor - Kyori Adventure + MiniMessage: Rich text component API
- FoliaLib: Thread-safe task scheduling (Folia compatibility)
- Paperweight userdev: NMS access with Mojang mappings
- Create class in the appropriate
data/subpackage - Add an inner
Serializer extends NodeSerializerclass for HOCON deserialization - Register it in the corresponding
init()method (e.g.,MenuActions.init()) viaTypes.registerAction(name, class, serializer)
External plugins are accessed through handler interfaces in handlers/. The Handlers class holds static references. Provider detection and registration happens in AbstractMenus.registerProviders(). Soft dependencies are declared in plugin.yml.