promotional bannermobile promotional banner

Towns And Nations

Towns And Nations is a Hytale plugin that lets players create, manage, and expand towns and nations with territory control, alliances, and strategic warfare.
Back to Files

TownsAndNations-0.1.3.jar

File nameTownsAndNations-0.1.3.jar
Uploaded
Aug 11, 2026
Downloads
13
Size
579.0 KB
File ID
8625678
Type
R
Release
Supported game versions
  • Early Access

What's new

# πŸ“‹ CHANGELOG - TownsAndNations

 

> πŸ‡«πŸ‡· Version franΓ§aise : [CHANGELOG.fr.md](CHANGELOG.fr.md)

 

## Version 0.1.3 (Current Release)

 

> ⚠️ **Breaking change for API consumers**: several `TownService` methods now take the acting
> player's UUID and return typed results instead of booleans. See *Typed Results* below.

 

### πŸ”§ Hytale API Compatibility

 

The plugin no longer compiled against Hytale server `0.5.7` (24 compile errors). Fixed:

 

- πŸ“¦ **Vector classes moved to JOML** β€” `com.hypixel.hytale.math.vector.Vector3d/3f/3i` and
  `math.matrix.Matrix4d` are gone, replaced by `org.joml.*`. Accessors changed too: JOML exposes
  `.x` / `.x()`, never `.getX()`. (`Transform` and `Rotation3f` remain in `math.vector`.)
- πŸ”’ `Matrix4d.asFloatData()` no longer exists β†’ `matrix.get(new float[16])`
- 🎨 `DisplayDebug` now expects `org.joml.Vector3fc` instead of `protocol.Vector3f`
- πŸ’¬ `Player.sendMessage(Message)` removed β€” message delivery lives on `PlayerRef`

 

### πŸ’Ύ Storage β€” Crash Safety

 

- πŸ›‘οΈ **New `StorageUtils`** β€” writes can no longer corrupt your data
  - Atomic writes: unique `.tmp` file β†’ SHA-256 checksum verified by reading back β†’ previous
    version kept as `.bak` β†’ atomic rename (falls back to a plain move on filesystems that
    reject `ATOMIC_MOVE`)
  - `readWithRecovery()` falls back to the `.bak` when the target is missing **or empty** β€” an
    empty file being the signature of an interrupted write
  - `WriteResult` sealed interface: `Success(file, checksum)` / `Failure(file, error, cause)`
- πŸ”Œ **Wired into all 5 JSON load/save pairs** β€” towns, nations, wars, war invitations,
  diplomatic relations. A crash mid-save no longer destroys your towns.

 

### πŸ›‘οΈ Protection

 

- πŸ› **Fixed plot detection** β€” protection resolved plots at a fake position in the *centre* of
  the chunk (`chunk*32+16`, y=64) while the ECS listeners already had the exact block position
  and discarded it. Any plot not covering the chunk centre was invisible to protection.
  - New `PermissionService.BlockPosition` record carries the real position through
  - New `Plot.intersectsChunk()` and `Town.getPlotInChunk()` as the fallback for callers that
    only know the chunk β€” preferring an **owned** plot, since returning a free one would
    silently widen permissions on a chunk that also holds someone's private plot
- πŸ’¬ **Denial messages with debounce** β€” blocked actions were cancelled *silently* (except PVP,
  which spammed one message per damage event). All four protection systems now explain the
  refusal, with a 2s cooldown per player+action pair. `DamageBlockEvent` (which fires on every
  mining tick) shares its cooldown key with `BreakBlockEvent` to avoid duplicates.
- πŸ”‘ **`townsandnations.bypass`** now short-circuits territory protection, alongside
  `townsandnations.admin`
- ♻️ **Deduplication** β€” the three near-identical `canBreak`/`canPlace`/`canInteract` internals
  merged into a single method (~120 duplicated lines removed)

 

### πŸ” Permissions

 

- ⛓️ **Provider chain** replacing the single LuckPerms lookup (new `permissions/` package)
  - `PermissionProvider` returns `Optional<Boolean>`: a provider answering `false` for a player
    it has never heard of would shadow every provider behind it
  - `LuckPermsPermissionProvider` β€” maps LuckPerms `Tristate` (`UNDEFINED` β†’ *no opinion*,
    not *denied*)
  - `HytaleNativePermissionProvider` β€” since `PermissionsModule` offers no tri-state, it is
    probed twice with opposite defaults: same answers β‡’ node explicitly set, differing answers
    β‡’ the module is just echoing the default
  - `PermissionManager` β€” wildcard resolution from most to least specific: `a.b.c` β†’ `a.b.*` β†’
    `a.*`, so a precise deny beats a broad grant
- 🏷️ **`Permissions.java`** centralises the nodes. The four existing `command.*` nodes remain
  authoritative and the new fine-grained nodes fall back onto them by wildcard β€” **existing
  server configurations keep working unchanged**
- πŸ”’ **Authorization moved into the service** β€” the GUI checked the mayor *role* but never the
  *permission node*, so a mayor whose `townsandnations.command.mayor` had been revoked could
  still act through the interface. Both checks now live in `TownService.authorizeTownAction()`,
  used by commands and GUI alike.

 

### πŸ‘” Deputies

 

Deputies are assistants: they handle day-to-day territory, never what would let them drain or
dismantle the town.

 

| Action | Mayor | Deputy |
|--------|:-----:|:------:|
| claim / unclaim | βœ” | βœ” **(new)** |
| togglePvp, togglePublic, setcolor | βœ” | ✘ |
| bank withdrawal | βœ” | ✘ |
| add / remove deputy | βœ” | ✘ |
| disband, invite, kick, sethome | βœ” | ✘ |

 

- Expressed by an explicit `RoleRequirement { MAYOR_ONLY, MAYOR_OR_DEPUTY }` rather than an
  implicit boolean
- Deputies can now open `/town mayor gui` for the claim map; the page hides settings and the
  danger zone from them. Security still comes from the service β€” hiding buttons is only comfort.
- ℹ️ Deputies need the `townsandnations.command.mayor` node (or the fine-grained
  `...mayor.claim` / `...mayor.unclaim`) for the commands to pass the command-level check.

 

### 🧩 Public API (new)

 

Other mods can now query, observe and veto TownsAndNations actions. See [docs/API.md](docs/API.md).

 

- πŸ“‘ **`EventBus`** β€” `register` / `unregister` / `publish` / `publishCancellable` / `clearAll`.
  Listener exceptions are logged and isolated; the listener list is copied before iteration so a
  listener may (un)register another without breaking the loop.
- πŸ“¨ **7 post-events**: `TownCreateEvent`, `TownDisbandEvent`, `TownClaimEvent`,
  `TownUnclaimEvent` (reason `UNCLAIM` / `DISBAND`), `TownMemberEvent`, `NationCreateEvent`,
  `NationDisbandEvent`
- 🚫 **3 cancellable pre-events**: `TownCreatePreEvent`, `TownClaimPreEvent`,
  `TownDisbandPreEvent`. Published after internal validation but **before any state change** β€”
  cancelling costs the town nothing, notably no bank withdrawal.
- πŸ”— **`TownsAndNationsAPI`** β€” `isAvailable()`, town/nation/territory/plot queries, `canBuild()`

 

### βš™οΈ Typed Results (breaking)

 

Callers used to **re-run the checks after the fact** to guess why an action failed ("is the
balance too low? is the limit reached?"). That reports the wrong reason as soon as state moves in
between, and could not distinguish a third-party mod cancellation at all.

 

```java
ClaimResult   : SUCCESS, TOWN_NOT_FOUND, NO_PERMISSION, NOT_MAYOR, ALREADY_CLAIMED,
                MAX_CHUNKS_REACHED, CITIZEN_LIMIT_REACHED, NOT_ADJACENT,
                INSUFFICIENT_FUNDS, CANCELLED
UnclaimResult : SUCCESS, TOWN_NOT_FOUND, NO_PERMISSION, NOT_MAYOR, NOT_OWNED,
                IS_HOME_CHUNK, LAST_CHUNK, WOULD_DISCONNECT
```

 

Changed signatures:

 

| Before | After |
|--------|-------|
| `claimChunk(townUuid, chunk)` β†’ `Boolean` | `claimChunk(townUuid, chunk, actorUuid)` β†’ `ClaimResult` |
| `unclaimChunk(townUuid, chunk)` β†’ `Boolean` | `unclaimChunk(townUuid, chunk, actorUuid)` β†’ `UnclaimResult` |
| `disbandTown(townUuid)` β†’ `Void` | `disbandTown(townUuid, actorUuid)` β†’ `Boolean` |
| `togglePvp(townUuid)` β†’ `Boolean` | `togglePvp(townUuid, actorUuid)` β†’ `Boolean` (null = denied) |
| `addDeputy(townUuid, playerUuid)` | `addDeputy(townUuid, playerUuid, actorUuid)` |
| `removeDeputy(townUuid, playerUuid)` | `removeDeputy(townUuid, playerUuid, actorUuid)` |

 

All 12 call sites now `switch` on the result.

 

### πŸ›οΈ Nation Interface

 

- 🎨 **NationMenuPage reworked** into a dashboard, with `NationDashboardPage.ui` and a dedicated
  `NationNavBar.ui` navigation bar
- 🧭 Navigation added between the nation pages

 

### πŸ—ΊοΈ Map

 

- 🎨 **Improved claim rendering** β€” `ClaimImageBuilder` now accounts for fluid particle colour,
  environment water tint and block tint when generating the map image

 

### 🌐 Internationalization

 

- πŸ‡¬πŸ‡§πŸ‡«πŸ‡· **12 new keys** in both languages: protection denials, cancellations by a third-party
  mod, already-claimed chunk

 

### 🧹 Code Quality

 

- βœ… `@Nonnull` annotations enforced across commands and GUI components
- πŸ“¦ `manifest.json` reformatted; `ServerVersion` now uses the `^${hytale_build}` placeholder
  resolved at build time
- πŸ—οΈ `updatePluginManifest` build task reworked

 

### πŸ“„ Documentation

 

- πŸ“˜ **[docs/API.md](docs/API.md)** β€” full public API reference



### πŸ”œ Not Yet Implemented

 

Admin SafeZone/WarZone, broader ECS coverage (item drop/pickup, death, respawn, mounts, NPCs),
per-UUID storage locks, GFS backups, versioned migrations, taxes/upkeep/debt, per-town and
per-plot permission matrix, town chat, outposts, town levels, PAPI placeholders.