Flectone LogoFlectonePulse

Entry point

The FlectonePulse interface, dependency injection through Google Guice, project lifecycle and error handling

Work with the API starts from two classes

ClassWhat it is for
net.flectone.pulse.FlectonePulseAPIHolds the running instance and drives its lifecycle
net.flectone.pulse.FlectonePulseGives dependency injection, reload and access to the platform
import net.flectone.pulse.FlectonePulse;
import net.flectone.pulse.FlectonePulseAPI;

FlectonePulse flectonePulse = FlectonePulseAPI.getInstance();

FlectonePulseAPI

MethodReturnsWhat it does
getInstance()FlectonePulseGives the running instance, or null while the project has not loaded
isDisabling()booleanGives true while the project is shutting down
Information

While isDisabling() gives true, do not start new tasks and do not touch the database. The project is already winding down at that point


FlectonePulse

MethodReturnsWhat it does
get(Class<T>)TGives a component from Guice
isReady()booleanChecks whether the injector is ready
reload()voidRereads the configuration and throws ReloadException on failure
getLoader()ObjectGives the native plugin or mod object of the platform
hook(HookType, Object...)voidCalls a platform extension point
onLoad(), onEnable(), onDisable()voidInternal lifecycle, called by the platform
throwInitException(Exception)voidWraps an error into InitException

get(Class<T> type)

Gives a component from the injector. Almost every component is declared as an interface, and implementations are marked @Singleton, so repeated calls give you the same object

import net.flectone.pulse.dispatcher.MessageDispatcher;
import net.flectone.pulse.logging.FLogger;
import net.flectone.pulse.platform.registry.ListenerRegistry;
import net.flectone.pulse.service.FPlayerService;

FLogger fLogger = flectonePulse.get(FLogger.class);

FPlayerService fPlayerService = flectonePulse.get(FPlayerService.class);

MessageDispatcher messageDispatcher = flectonePulse.get(MessageDispatcher.class);

ListenerRegistry listenerRegistry = flectonePulse.get(ListenerRegistry.class);
Attention

Check readiness through isReady() before calling get(), otherwise you get InjectorNotInitializedException

Ask for the interface, not the implementation. Implementations live in closed modules and differ between platforms

// correct
FPlayerService service = flectonePulse.get(FPlayerService.class);

// wrong, there is no FPlayerServiceImpl class in the api artifact
FPlayerServiceImpl service = flectonePulse.get(FPlayerServiceImpl.class);

isReady()

Checks whether the dependency injector is up

if (flectonePulse.isReady()) {
    FLogger fLogger = flectonePulse.get(FLogger.class);
    fLogger.info("API is ready");
}

reload()

Reloads the configuration, the same thing the /flectonepulse reload command does

import net.flectone.pulse.exception.ReloadException;

try {
    flectonePulse.reload();
    getLogger().info("FlectonePulse reloaded");
} catch (ReloadException e) {
    getLogger().severe("Reload failed " + e.getMessage());
}
Warning

Reload drops every listener except those added through registerPermanent(). Details live on the event system page

getLoader()

Gives the native loader object of the current platform. Handy when you need a platform API that FlectonePulse does not abstract

PlatformObject type
Bukkit and Paperorg.bukkit.plugin.java.JavaPlugin
BungeeCordnet.md_5.bungee.api.plugin.Plugin
Velocitythe Velocity plugin object
Fabric and NeoForgethe mod container
Hytalethe Hytale mod loader
JavaPlugin pulsePlugin = (JavaPlugin) flectonePulse.getLoader();

hook(HookType type, Object... args)

Extension points through which the core calls the platform layer. The project calls them itself, and you need them by hand only for low level integration

HookTypeWhen it fires
CONFIGURE_SERIALIZATIONPlatform serialization setup
PRE_NEW_PLAYER_PLACEBefore a new player is placed in the world
ON_PLAYER_PRE_LOGINPlayer check before login
ON_PLAYER_LOGINPlayer login
POST_RESPAWNAfter a player respawns
INIT_PACKET_ADAPTERPacket adapter startup
TERMINATE_PACKET_ADAPTERNormal packet adapter shutdown
TERMINATE_FAILED_PACKET_ADAPTERAdapter shutdown after a failed startup
CLOSE_UISClosing every open interface
SIMPLEVOICE_ENTITY_SOUND_PACKETSimple Voice Chat entity sound packet
SIMPLEVOICE_MICROPHONE_PACKETSimple Voice Chat microphone packet
import net.flectone.pulse.constant.HookType;

// close every open FlectonePulse interface
flectonePulse.hook(HookType.CLOSE_UIS);

throwInitException(Exception e)

Wraps an error into InitException. In normal mode the message is cut down to 25 lines, and in debug mode it stays whole

try {
    // risky startup work
} catch (Exception e) {
    flectonePulse.throwInitException(e); // always throws InitException
}

Debugging

Debug mode turns on with a system property at server startup

java -Dflectonepulse.debug=true -jar server.jar

In this mode FlectonePulse keeps error messages whole and writes detailed startup logs


Exceptions

Every exception lives in the net.flectone.pulse.exception package

ExceptionWhen it arrives
InjectorNotInitializedExceptionget() was called before the injector was ready
InitExceptionFailure during project startup
ReloadExceptionFailure during a reload() call
LoadingExceptionFailure while loading the project
LibraryLoadExceptionA library could not be downloaded or attached
FileLoadExceptionFailure while reading the configuration
FileWriteExceptionFailure while writing the configuration
ListenerRegistrationExceptionA broken listener or @Pulse method
CacheRegistrationExceptionFailure while registering a cache
DatabaseNotInitializedExceptionThe database was used before it was connected
UnsupportedDatabaseOperationExceptionThe chosen database does not support the operation
ProxyMessageCreateExceptionFailure while building a proxy message
SchedulerTaskExceptionFailure inside a scheduler task
ReflectionExceptionReflection failure in the platform layer
Note

ReloadException and SchedulerTaskException extend Exception, so you have to handle or rethrow them. Every other one extends RuntimeException

Last update August 11, 2026
Edit on Github

On this page