forked from Kweebec_Network/core-vitals
66 lines
3.2 KiB
Markdown
66 lines
3.2 KiB
Markdown
# Overview
|
|
|
|
## What NetworkCore is
|
|
|
|
A single Hytale plugin that every other KweebecNet plugin depends on. It owns three concerns that don't belong in any individual gamemode or feature plugin:
|
|
|
|
1. **Metrics** - counters, gauges, and timers exposed over a Prometheus-compatible HTTP endpoint
|
|
2. **Cross-server messaging** - Redis pub/sub with a small JSON envelope, plus a request/response RPC layer on top
|
|
3. **Server presence** - every server in the network heartbeats to Redis, every other server learns about it within a few seconds and is notified via local Hytale events
|
|
|
|
## Why it's split out
|
|
|
|
If every gamemode plugin opened its own Redis connection, registered its own metrics, and rolled its own service-discovery, you'd have N copies of the same logic, N config blocks to keep in sync, and N places to add TLS when the time comes. Putting it in one plugin means:
|
|
|
|
- Plugins don't carry Redis as a dependency. They depend on NetworkCore's `MessageBus` interface.
|
|
- A single config file owns Redis + network secrets.
|
|
- When we add TLS, an audit log, or a different backend, only NetworkCore changes.
|
|
|
|
## What lives in NetworkCore (and what doesn't)
|
|
|
|
**In:**
|
|
- The MessageBus, ServerRegistry, MetricsService, RpcClient
|
|
- Auth-token verification on inbound messages
|
|
- The /networkcore admin command
|
|
- Built-in metrics (player count, JVM memory)
|
|
|
|
**Out:**
|
|
- Player profiles, stats, currency - those belong in a separate plugin (probably backed by MySQL)
|
|
- Chat, parties, queues - separate plugins that *use* the MessageBus
|
|
- World/match management - the existing MinigameCore-style plugins keep that role
|
|
|
|
The rule of thumb: if it's something every plugin should be able to use, it's in NetworkCore. If it's a feature you'd ship to players, it's its own plugin.
|
|
|
|
## How plugins use it
|
|
|
|
Two access patterns, both backed by the same internal service registry:
|
|
|
|
```java
|
|
NetworkCore core = NetworkCore.getInstance();
|
|
|
|
// Convenience getters for the bundled services
|
|
core.getMetrics().counter("matches_started", Map.of("game", "bridge_duel")).inc();
|
|
core.getMessageBus().publish("party.invite", invite);
|
|
|
|
// Generic lookup for anything (including services other plugins contribute)
|
|
MetricsService metrics = core.getService(MetricsService.class);
|
|
```
|
|
|
|
A plugin that wants to contribute its own service to the registry can do:
|
|
|
|
```java
|
|
core.registerService(MyPartyService.class, new MyPartyServiceImpl());
|
|
```
|
|
|
|
Other plugins then resolve it via `core.getService(MyPartyService.class)`. No DI framework, just a typed map.
|
|
|
|
## Lifecycle
|
|
|
|
NetworkCore uses the standard Hytale plugin lifecycle:
|
|
|
|
- `setup()` - load config, generate or read the server id, register the admin command, register MetricsService (built-ins included). Singleton becomes available here.
|
|
- `start()` - open the Redis connection, bind the Prometheus HTTP server, start the heartbeat, publish a hello to the network.
|
|
- `shutdown()` - publish a goodbye, stop the heartbeat, close Redis and the HTTP server.
|
|
|
|
Dependent plugins should resolve services in their own `start()`, not `setup()`. Hytale's dependency ordering guarantees we finish `setup()` before any dependent plugin's `start()` runs, but it does not guarantee we finish `start()` first - so a `getMessageBus()` call from another plugin's `setup()` may return null.
|