# Plugin Integration How another plugin depends on NetworkCore and uses it. ## 1. Declare the dependency In your plugin's `src/main/resources/manifest.json`: ```json { "Group": "yourgroup", "Name": "YourPlugin", "Version": "1.0.0", "Main": "your.package.YourPlugin", "Dependencies": { "kewwbec:NetworkCore": "*" }, "OptionalDependencies": {}, "DisabledByDefault": false } ``` The dependency string is `kewwbec:NetworkCore`. Hytale's plugin loader uses this to load NetworkCore before your plugin and to refuse to load your plugin if NetworkCore isn't installed. If your plugin can run without NetworkCore (degraded), use `OptionalDependencies` instead and null-check before calling. ## 2. Get a reference Two access patterns. Use whichever fits. ### Singleton (most common) ```java import net.kewwbec.networkcore.NetworkCore; NetworkCore core = NetworkCore.getInstance(); core.getMessageBus().publish("party.invite", invite); ``` This is the same pattern MinigameCoreV2 uses (`MinigameCore.getInstance()`). ### Service registry (when you want loose coupling) ```java NetworkCore core = NetworkCore.getInstance(); MetricsService metrics = core.getService(MetricsService.class); ``` `getService` throws `IllegalStateException` if nothing is registered. Convenience getters like `getMetrics()` / `getMessageBus()` / `getServerRegistry()` / `getRpc()` return null instead, which is what you want for graceful degradation. ## 3. When to resolve services Resolve in your plugin's `start()`, not `setup()`. The order is: ``` NetworkCore.setup() -> instance assigned, MetricsService registered [your plugin].setup() -> NetworkCore.getInstance() works, getMetrics() works, but getMessageBus() / getServerRegistry() / getRpc() return null NetworkCore.start() -> Redis connects, MessageBus / ServerRegistry / RpcClient registered [your plugin].start() -> everything is available ``` So: ```java public final class YourPlugin extends JavaPlugin { private MetricsService metrics; private MessageBus bus; @Override protected void setup() { // Safe: MetricsService is registered during NetworkCore.setup() this.metrics = NetworkCore.getInstance().getMetrics(); } @Override protected void start() { // Safe here: NetworkCore has finished start() this.bus = NetworkCore.getInstance().getMessageBus(); if (bus != null) { bus.subscribe("party.invite", PartyInvite.class, this::onInvite); } } } ``` ## 4. Contributing your own service If your plugin offers an API other plugins might want to consume through the same registry: ```java @Override protected void start() { NetworkCore.getInstance().registerService(PartyService.class, new MyPartyService()); } ``` Other plugins do `core.getService(PartyService.class)`. There's no requirement to do this - plugins can also expose their own singleton. But registering with the central registry is useful when you don't want consumers to import your plugin's classes directly. ## 5. Verify the integration In-game, run `/networkcore status`. You should see the local server id, role, known servers count, and metrics endpoint. If any of those are missing, NetworkCore failed to start (check the log). `curl http://127.0.0.1:9100/metrics` should return Prometheus output that includes `players_online` and JVM memory gauges.