Warring NationsWarring Nations MC 1.21.1.NEOFORGE.JAVA 21
Wiki/Developer/Architecture

Architecture

How Warring Nations is put together across its four mods, and where the extension points live, so you can decide where your addon should hook in rather than where it's forced to.

ADDON DEVS

The Four Mods

Warring Nations ships as one required base mod and three optional addons. Each addon consumes WN Core's public API and events rather than being tightly coupled to its internals.

WN Core client + server . required WN Siege server only . optional WN Discord server only . optional WN BlueMap server only . optional WnApi.get() WnApi.get() WnEvents Extension-point registries Solid = consumes Core's public API/events. Dashed = an addon registers into Core's extension-point registries (see below).
Mod
Client/Server
Role
Client + server
The base mod: nations, wars, claims, diplomacy, government. Every addon requires it.
Server-side, optional
Consumes WN Core's public API and events. Has a soft dependency on WN Discord for that specific integration.
Server-side, optional
Consumes WN Core's public API and events.
Server-side, optional
Consumes WN Core's public API and events.
i
Same pattern applies to your addon. A new addon consuming WN Core sits alongside WN Siege, WN Discord, and WN BlueMap: it calls WnApi.get() and subscribes to WnEvents rather than depending on WN Core's internal classes. See Core API Reference for the full consuming-side picture.

Extension Points

Where an addon needs to change WN's own behavior, not just read from or react to it, WN Core exposes the change as an open, addon-facing registry that starts empty. WN ships zero built-in entries in any of these; a server's behavior is unchanged until an addon registers something. This keeps the general mechanism in core while leaving the actual meaning of what gets registered entirely up to the addon.

ClaimEligibilityRegistry

An addon registers a claim-eligibility policy: a function taking the claim attempt's context (nation, tier, target chunk, neighboring claims) and returning either "allow" or a player-facing deny reason. WN's own built-in contiguity check runs first; every registered policy then runs afterward, and the first denial wins.

WnCustomData

Generic get/set/remove metadata storage keyed by a nation, war, or claim plus an addon-chosen namespace, so unrelated addons never collide. WN persists it through the same save machinery as its own data and automatically clears an owner's entries when that nation disbands, that war ends, or that claim is lost, so an addon gets correct cleanup for free instead of maintaining its own save file.

EffectHandlerRegistry

WN's composable war engine runs data-driven war-preset scripts against a fixed vocabulary of built-in effects. An addon can register a new named effect callable from any war-preset script exactly like a built-in one, extending that vocabulary without touching the built-ins or their existing behavior.

SubordinationRegistry

Lets an addon record a hierarchical political relationship between two independent nations (an addon-defined kind such as a vassal or colony) and, via a companion policy registry, define whether one side's wars expose the other's territory and whether an action needs the parent's approval. A kind with no registered policy behaves as fully independent.

Public API vs Internal

WN Core draws one clear line between what an addon can rely on and what it can't.

The supported surface

The dev.tacyeet.warringnations.api package, plus its .claim, .data, and .economy subpackages, is what an addon compiles and codes against: WnApi.get(), WnEvents.subscribe(...), and the extension-point registries above. Everything else in WN Core is internal and can change shape between releases without notice.

This boundary is also why compiling against WN Core's public API is safe across versions in both directions: newer accessors on WarringNationsAPI are added as default methods with a documented, safe fallback, so an addon built against an older core keeps working on a newer one, and an addon built against a newer core degrades gracefully on an older one. See Core API Reference for the full compatibility, error-handling, and threading rules that come with that guarantee.