---
title: Plugin Lifecycle
type: docs
weight: 4
---

Understanding the plugin lifecycle is essential for properly initializing and cleaning up your plugin resources.

## Lifecycle States

A plugin goes through several states during its lifetime:

```
NONE → SETUP → START → ENABLED → SHUTDOWN → DISABLED
```

| State | Description |
|-------|-------------|
| `NONE` | Initial state before any initialization |
| `SETUP` | Plugin is in the setup phase |
| `START` | Plugin is starting |
| `ENABLED` | Plugin is fully operational |
| `SHUTDOWN` | Plugin is shutting down |
| `DISABLED` | Plugin has been disabled |

## Lifecycle Methods

### Constructor

The constructor is called when the plugin is instantiated. Use this for:

- Registering configuration files with `withConfig()` (recommended)
- Storing the init reference if needed

```java
import com.hypixel.hytale.server.core.util.Config;

private Config<MyConfig> config;

public MyPlugin(JavaPluginInit init) {
    super(init);
    // Register config in constructor - loaded asynchronously during preLoad()
    config = withConfig(MyConfig.CODEC);
}
```

{{< callout type="info" >}}
Registering configs in the constructor ensures they are loaded asynchronously during `preLoad()`, before `setup()` is called. This is the recommended approach.
{{< /callout >}}

### setup()

Called during the initial setup phase, after configs are loaded. Use this for:

- Preparing resources that don't depend on other plugins
- Early initialization logic
- Accessing loaded configuration values

```java
import java.util.logging.Level;

@Override
public void setup() {
    // Config is already loaded and available
    getLogger().at(Level.INFO).log("Setup complete!");
}
```

{{< callout type="info" >}}
To create configuration classes with `CODEC`, see the [Codecs documentation]({{< ref "core-concepts/codecs#buildercodec" >}}).
{{< /callout >}}

{{< callout type="warning" >}}
Do not register commands or events in `setup()`. Other plugins may not be loaded yet.
{{< /callout >}}

### start()

Called after all plugins have completed setup. Use this for:

- Registering commands
- Registering event listeners
- Registering entities
- Interacting with other plugins

```java
import com.hypixel.hytale.server.core.event.events.player.PlayerConnectEvent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import java.util.logging.Level;

@Override
public void start() {
    // Register commands
    getCommandRegistry().registerCommand(new MyCommand());

    // Register events
    getEventRegistry().register(PlayerConnectEvent.class, this::onPlayerConnect);

    getLogger().at(Level.INFO).log("Plugin started!");
}

private void onPlayerConnect(PlayerConnectEvent event) {
    // See PlayerRef documentation for thread-safe player references
    PlayerRef playerRef = event.getPlayerRef();
    getLogger().at(Level.INFO).log("Player connecting: " + playerRef.getUsername());
}
```

{{< callout type="info" >}}
See the [Registries documentation]({{< ref "core-concepts/registries" >}}) for a complete list of available registries and their usage.
{{< /callout >}}

### shutdown()

Called when the plugin is being disabled or the server is stopping. Use this for:

- Saving data
- Cleaning up resources
- Canceling scheduled tasks

```java
import java.util.logging.Level;

@Override
public void shutdown() {
    // Save any pending data
    savePlayerData();

    getLogger().at(Level.INFO).log("Plugin shutdown complete!");
}
```

{{< callout type="info" >}}
Registries are automatically cleaned up after `shutdown()`. You don't need to manually unregister commands or events.
{{< /callout >}}

## Lifecycle Flow Diagram

{{< steps >}}

### Plugin Loading
The server discovers your plugin JAR and reads `manifest.json`

### Constructor Called
`MyPlugin(JavaPluginInit init)` is instantiated

### preLoad()
Configuration files registered with `withConfig()` are loaded asynchronously

### setup()
Your `setup()` method is called

### start()
Your `start()` method is called after all plugins are set up

### Running
Plugin is now in `ENABLED` state and fully operational

### shutdown()
Called when server stops or plugin is disabled

### Cleanup
All registries are automatically cleaned up

{{< /steps >}}

## Checking Plugin State

You can check if your plugin is enabled:

```java
if (isEnabled()) {
    // Plugin is running
}

if (isDisabled()) {
    // Plugin is not running
}

// Get current state
PluginState state = getState();
```

## Next Steps

Learn how to [Build and Run](../building-and-running) your plugin.
