Skip to main content

The stable API

GrayCore is a core that other plugins depend on. This page says what they may rely on.

A class is part of the API when it is annotated @StableApi. Everything else is internal: it can change or disappear in any release, even if it is public. (Java needs it public so the modules and the plugin can share it; that does not make it a promise.)

The promise​

For a @StableApi class:

  • What exists keeps working: signatures, behaviour and documented contracts do not change in an incompatible way.
  • Something that must go is marked @Deprecated (with the replacement in its Javadoc) for at least one release before it is removed.
  • New methods and classes can be added at any time.
  • Anything you subclass or implement (GCModule, GrayCoreEvent...) may gain methods, with a default where possible.

Breaking a @StableApi class is a decision to write down in the pull request, not a side effect.

What is in it​

AreaClassesFor
Entry pointGrayCoreApi, GrayCorePaperApiRegister modules, data keys and services; read player data.
ModulesGCModule, ModuleContext, ModuleConfig, ConfigSectionWrite a module (see Writing a module).
Player dataDataKey, GCData, SerializableData, GCPlayer, PlayerSettingsStore and read what belongs to a player.
Storage helpersEntryStore, ConfigurationSerializableOne file per entry, for catalogs (kits, warps).
TextsLocaleServiceMessages with the server owner's translations.
PermissionsGrayCorePermissionsThe core's permission nodes.
EventsGrayCoreEvent, PlayerPostLoadEvent, PlayerPreSaveEvent, PlayerUnloadEvent, ServerPreStopEventReact to the player lifecycle (read the thread rules in Writing a module).
Text utilitySanitizeUtilsClean a name typed by a player.
KitsKitsApi, GCKit, GCPlayerKits, KitUnderCooldownException, NoKitPermissionExceptionOffered by the kits module through GrayCoreApi.getService(KitsApi.class).
WarpsWarpsApi, GCWarpOffered by the warps module through GrayCoreApi.getService(WarpsApi.class).

The list above is a summary: the annotation is the truth. To see it all, search for @StableApi.

A module must stay inside it​

The modules shipped with GrayCore are written like those of any other plugin. A test (ModulesUseOnlyTheStableApiTest, in paper-dist) fails when a shipped module imports a core class that is not @StableApi. When it fails:

  • the module is reaching into the core's internals: use the API instead; or
  • the class really belongs to the API: mark it @StableApi, which is the decision to support it from now on.

Adding to the API​

  1. Keep the class small and documented: what it is for, what thread it may be used from, what it throws.
  2. Add @StableApi.
  3. Add it to the table above if it opens a new area.

Do not mark a class only to silence the test.