HyCodeYourTale

Plugin Lifecycle

Plugin Lifecycle

Dokumentace k životnímu cyklu pluginu v Hytale.

Obsah

| Soubor | Popis |
|--------|-------|
| PLUGIN_PHASES.md | Fáze životního cyklu pluginu (setup, start, shutdown) |
| INITIALIZATION.md | Inicializace - registry, komponenty, eventy |

---

Rychlý Přehled

| Fáze | State | Metoda | Co dělat |
|------|-------|--------|----------|
| 1 | NONE | Konstruktor | super(init), withConfig() |
| 2 | SETUP | setup() | Registrace komponent, systémů, příkazů, eventů |
| 3 | START→ENABLED | start() | Logování, verifikace |
| 4 | SHUTDOWN | shutdown() | Sync uložení dat, cleanup |

---

Lifecycle Metody

Každý plugin dědí z JavaPlugin a implementuje tyto metody:

public class MyPlugin extends JavaPlugin {

private static MyPlugin instance;

// Konstruktor - POVINNÝ
public MyPlugin(JavaPluginInit init) {
super(init);
}

// Singleton pattern
public static MyPlugin get() {
return instance;
}

// 1. SETUP - Registrace komponent, systémů, příkazů, eventů
@Override
protected void setup() {
instance = this;

// Registrace komponent
// Registrace systémů
// Registrace příkazů
// Registrace eventů
}

// 2. START - Plugin je aktivní, svět je načtený
@Override
protected void start() {
getLogger().atInfo().log("Plugin started!");
}

// 3. SHUTDOWN - Server se vypíná
@Override
protected void shutdown() {
getLogger().atInfo().log("Plugin shutdown!");
// Uložení dat
// Cleanup
}
}

---

Pořadí Volání

1. Konstruktor (JavaPluginInit)

2. setup()
- Registrace komponent
- Registrace systémů
- Registrace příkazů
- Registrace event listenerů

3. [Načítání světů]

4. AllWorldsLoadedEvent
- Načtení konfigurace
- Načtení dat

5. start()
- Plugin je plně aktivní

6. [Server běží]

7. shutdown()
- Uložení dat
- Cleanup

---

setup()

V setup() registruješ vše co plugin potřebuje:

Komponenty

@Override
protected void setup() {
// Registrace vlastních komponent
this.myComponentType = getEntityStoreRegistry().registerComponent(
MyComponent.class,
MyComponent::new
);
}

Systémy

@Override
protected void setup() {
// Registrace ECS systémů
getEntityStoreRegistry().registerSystem(new MyBlockBreakSystem());
getEntityStoreRegistry().registerSystem(new MyDeathSystem());
}

Příkazy

@Override
protected void setup() {
// Registrace příkazů
getCommandRegistry().registerCommand(new MyCommand());
getCommandRegistry().registerCommand(new AnotherCommand());
}

Eventy

@Override
protected void setup() {
// Sync eventy
getEventRegistry().registerGlobal(PlayerReadyEvent.class, this::onPlayerReady);

// Async eventy
getEventRegistry().registerAsyncGlobal(PlayerChatEvent.class, future -> {
future.thenAccept(this::onPlayerChat);
});

// World eventy
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, event -> {
loadConfig();
});

getEventRegistry().registerGlobal(AddWorldEvent.class, event -> {
onWorldAdded(event.getWorld());
});
}

---

AllWorldsLoadedEvent

Tento event je ideální pro načítání dat která závisí na světech:

@Override
protected void setup() {
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, event -> {
// Všechny světy jsou načtené
loadWarps();
loadPlayerData();
initializeWorldSpecificData();
});
}

---

start()

Volá se když je plugin plně aktivní:

@Override
protected void start() {
getLogger().atInfo().log("MyPlugin started!");

// Verifikace že vše je správně načtené
if (warps.isEmpty()) {
getLogger().atWarning().log("No warps loaded!");
}

// Spuštění periodických tasků
startPeriodicTasks();
}

---

shutdown()

Volá se při vypínání serveru:

@Override
protected void shutdown() {
getLogger().atInfo().log("MyPlugin shutting down...");

// Uložení dat
saveAllData();

// Zastavení tasků
stopPeriodicTasks();

// Cleanup
cleanup();

getLogger().atInfo().log("MyPlugin shutdown complete.");
}

Důležité pro Shutdown

@Override
protected void shutdown() {
// Synchronní uložení - server čeká
try {
saveWarps();
savePlayerData();
} catch (Exception e) {
getLogger().at(Level.SEVERE).withCause(e).log("Failed to save data!");
}
}

---

Dostupné Metody z JavaPlugin

Registry

// Command registry
getCommandRegistry().registerCommand(command);

// Event registry
getEventRegistry().register(...);
getEventRegistry().registerGlobal(...);
getEventRegistry().registerAsync(...);

// Entity store registry
getEntityStoreRegistry().registerComponent(...);
getEntityStoreRegistry().registerSystem(...);
getEntityStoreRegistry().registerResource(...);

Logger

// Info
getLogger().atInfo().log("Message");
getLogger().atInfo().log("Message with param: %s", param);

// Warning
getLogger().atWarning().log("Warning message");

// Error s výjimkou
getLogger().at(Level.SEVERE).withCause(exception).log("Error occurred:");

Data Folder

// Složka pro data pluginu
Path dataFolder = getDataFolder();
Path configPath = dataFolder.resolve("config.json");

---

Singleton Pattern

Běžný vzor pro přístup k pluginu:

public class MyPlugin extends JavaPlugin {

private static MyPlugin instance;

public MyPlugin(JavaPluginInit init) {
super(init);
}

@Override
protected void setup() {
instance = this; // Nastav singleton
// ...
}

// Statický getter
public static MyPlugin get() {
return instance;
}

// Gettery pro ComponentType
public ComponentType getMyComponentType() {
return myComponentType;
}
}

// Použití kdekoliv v kódu
MyPlugin plugin = MyPlugin.get();
ComponentType type = MyPlugin.get().getMyComponentType();

---

Kompletní Příklad

public class ExamplePlugin extends JavaPlugin {

private static ExamplePlugin instance;
private ComponentType playerStatsType;
private final Map playerDataCache = new ConcurrentHashMap<>();

public ExamplePlugin(JavaPluginInit init) {
super(init);
}

public static ExamplePlugin get() {
return instance;
}

@Override
protected void setup() {
instance = this;

// Komponenty
playerStatsType = getEntityStoreRegistry().registerComponent(
PlayerStats.class,
PlayerStats::new
);

// Systémy
getEntityStoreRegistry().registerSystem(new DeathStatsSystem());

// Příkazy
getCommandRegistry().registerCommand(new StatsCommand());

// Eventy
getEventRegistry().registerGlobal(PlayerReadyEvent.class, this::onPlayerReady);
getEventRegistry().register(PlayerDisconnectEvent.class, this::onPlayerDisconnect);
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, e -> loadAllData());

getLogger().atInfo().log("ExamplePlugin setup complete");
}

@Override
protected void start() {
getLogger().atInfo().log("ExamplePlugin started! Loaded %d players", playerDataCache.size());
}

@Override
protected void shutdown() {
getLogger().atInfo().log("ExamplePlugin shutting down...");
saveAllPlayerData();
getLogger().atInfo().log("ExamplePlugin shutdown complete");
}

private void onPlayerReady(PlayerReadyEvent event) {
Player player = event.getPlayer();
loadPlayerData(player.getUuid());
}

private void onPlayerDisconnect(PlayerDisconnectEvent event) {
Player player = event.getPlayer();
savePlayerData(player.getUuid());
}

private void loadAllData() {
// Načti globální data
}

private void loadPlayerData(UUID uuid) {
// Async načtení
}

private void savePlayerData(UUID uuid) {
// Async uložení
}

private void saveAllPlayerData() {
// Sync uložení všech dat
}

public ComponentType getPlayerStatsType() {
return playerStatsType;
}
}

---

Shrnutí

| Metoda | Kdy | Co dělat |
|--------|-----|----------|
| setup() | Inicializace | Registrace komponent, systémů, příkazů, eventů |
| start() | Po načtení | Logování, verifikace, periodické tasky |
| shutdown() | Vypínání | Uložení dat, cleanup |

| Registry | Účel |
|----------|------|
| getCommandRegistry() | Registrace příkazů |
| getEventRegistry() | Registrace event listenerů |
| getEntityStoreRegistry() | Registrace ECS komponent/systémů |

Last updated: 20. ledna 2026