A real integration
This is a working integration rather than a toy one. A faction event plugin hooks SomaHider into two events, a KoTH and a giant totem. The shape is the same both times: the zone opens around the arena when the event starts, reveals a few groups, and closes when it ends.
One helper for both events
Section titled “One helper for both events”Both events go through a small helper, so the API is touched in exactly one place. It gets the API, maps each player to their faction, applies the disguise read from the config, and opens the zone.
public static HiderZone open(ConfigurationSection hider, Region region, VisibilityRule... reveal) { SomaHider somaHider = SomaHiderProvider.getOrNull(); if (somaHider == null || region == null) { return null; } if (hider != null && !hider.getBoolean("enabled", true)) { return null; } return somaHider.hide(region) .groupResolver(Hiders::factionId) // each player -> their faction id .disguise(hider) .reveal(reveal) .open();}
public static String factionId(Player player) { Faction faction = FactionUtils.getFactionByPlayer(player); return faction != null && faction.isNormal() ? faction.getId() : null;}getOrNull() and the check after it keep the plugin running when SomaHider is not installed, which is
what softdepend implies. The resolver returns null for a player without a faction, and a null
group is never revealed.
Passing the config section straight to disguise(...) means server owners tune the look of the
disguise in the event’s own config file, with the same keys as
config.yml, and the plugin needs no code for it.
KoTH: reveal whoever holds the point
Section titled “KoTH: reveal whoever holds the point”At the start of the event a zone covers the arena. Everyone is hidden except your own faction and the one currently holding the KoTH. The owner is read live, so the reveal follows the capture.
// when the event startsConfigurationSection hider = getConfig().getConfigurationSection("koths." + koth.getName() + ".hider");
zone = Hiders.open(hider, Hiders.around(koth.getArea().getMiddle(), hider), Reveal.sameGroup() .or(Reveal.group(() -> Hiders.factionId(currentKoth.getOwner()))));
// when it stopszone.close();sameGroup() keeps teammates recognisable to each other. Reveal.group(Supplier) reveals the owning
faction to everybody, and because it takes a supplier rather than a fixed id, the reveal moves to the
new owner as soon as the point changes hands. No extra code runs on capture. While nobody holds the
point the supplier returns null and only teammates see each other.
Giant totem: reveal the top of the standings
Section titled “Giant totem: reveal the top of the standings”Same shape, different rule. Around the totem, reveal your own faction and the top three of the standings. When the standings move, the revealed set moves with them.
ConfigurationSection hider = getConfig().getConfigurationSection("giant-totems." + totem.getName() + ".hider");
zone = Hiders.open(hider, Hiders.around(totem.getLocation(), hider), Reveal.sameGroup() .or(Reveal.groupsTogether(() -> Hiders.top(standings, 3))));public static List<String> top(List<EventData> standings, int count) { List<String> ids = new ArrayList<>(); for (int i = 0; i < standings.size() && i < count; i++) { ids.add(standings.get(i).getId()); } return ids;}groupsTogether(Supplier) reveals the members of a set of groups to one another: viewer and target
must both be in the set. Here the set is the leading factions, recomputed as the event goes, so the
standings open up as they change.
Why the suppliers cost nothing
Section titled “Why the suppliers cost nothing”A rule is evaluated for every viewer and target pair, several times a second. Reading the standings there once per pair would be expensive.
The supplier factories avoid it: SomaHider calls the supplier at most once per pass and hands the result to every pair evaluated in that pass. Build the lambda once, when you open the zone, as the examples above do. Creating a new lambda on each call would defeat the caching, which is keyed on the supplier instance.
What to take away
Section titled “What to take away”- One helper holds the API access, the group resolver and the disguise.
- The zone opens when the event starts and closes with
zone.close()when it ends. - Supplier-based rules follow game state on their own, with no extra logic to write.
The full catalogue of factories is in reveal rules.