You are viewing a potentially older version of this package. View all versions.
Ryanlt-AdminHelper-1.0.0 icon

AdminHelper

A tool to assist in event admining. Lists and highlights players who are ramboing.

Date uploaded 3 weeks ago
Version 1.0.0
Download link Ryanlt-AdminHelper-1.0.0.zip
Downloads 22
Dependency string Ryanlt-AdminHelper-1.0.0

This mod requires the following mods to function

HoldfastModding-BepInExPack_Holdfast-5.4.2305 icon
HoldfastModding-BepInExPack_Holdfast

BepInEx pack for Holdfast: Nations At War. Preconfigured and ready to use.

Preferred version: 5.4.2305
Ryanlt-RyLib-1.0.0 icon
Ryanlt-RyLib

Shared UI library for Holdfast client mods. Lets several mods add P menu tabs, a shared Mods tab, a battle map, player and kill log actions, key hints and world or minimap markers without colliding.

Preferred version: 1.0.0

README

AdminHelper

Latest release License

A BepInEx mod for Holdfast: Nations At War that finds "rambos": players who have left their formation and are off fighting on their own. It scores every player continuously and marks the ones who stay out, so an admin does not have to eyeball a 150 player field.

It only works for admins. Nothing about another player is drawn until the server itself has authenticated your rc login. See Admin only.

Install

With a mod manager. Install through r2modman or Thunderstore Mod Manager and launch the game from the manager. BepInEx is pulled in as a dependency, so there is nothing else to set up.

By hand. Install BepInExPack into the game folder and run the game once so it creates its folders. Then download AdminHelper.dll from the latest release and put it here:

Steam\steamapps\common\Holdfast Nations At War\BepInEx\plugins\AdminHelper\AdminHelper.dll

Did it work?

Open BepInEx\LogOutput.log and look for:

[Info   :   BepInEx] Loading [AdminHelper 1.0.0]

If it is not there, the mod was not loaded. See Troubleshooting.

Using it

Log into the server console as normal:

rc login <password>

From then on, anyone drifting gets a ring at their feet and a floating label with their scores. The marker appears as soon as ISO passes RingThreshold and clears the moment they come back, because it follows the live score rather than a timer.

Two states:

  • ISOLATED, yellow. Out of position right now. Worth a look.
  • RAMBO, red. Has held above RamboThreshold for RamboHoldSeconds, and the label counts the seconds.

A corner list gives you the same players sorted worst first, with scores and distance, so you know who to fly to.

The overlay starts hidden, so press F6 to show it. It then stays as you left it, across rounds and map changes, until you quit the game. The scorer keeps running while it is hidden, so nothing is lost and a player already flagged is still flagged when you bring it back. Change the key with ToggleKey, or set StartHudVisible to have it up from the start.

The two numbers

Meaning
ISO Isolation. How far you are from your own side, built up over time.
DGR Danger. How much of that isolation is actually a threat, based on how deep into the enemy you are.

Both run 0 to 100, and DGR never exceeds ISO. A player alone in an empty field scores high ISO and zero DGR, because being lost is not the same as ramboing. The same player at 60 ISO standing in the middle of three enemies scores close to 60 DGR. Sort your attention by DGR, use ISO to see why.

How a player is scored

Four signals, recomputed five times a second:

  • Distance from your side. The midpoint of your two nearest living teammates, and how far you are from it. Nothing counts under ClusterNearMetres, and it saturates at ClusterFarMetres. See Tuning it for what those two numbers actually mean in metres.
  • Time. The score builds while you stay out and falls RecoverMultiplier times faster when you rejoin, so brief separations do not flag.
  • Enemies. How close the nearest enemy is and how many are inside EnemyRadius. This scales ISO into DGR: no enemies nearby means no danger at all, and EnemyCrowd enemies at contact means the full score. A lone enemy at contact counts half of what a full crowd does.
  • Formation. Being in formation removes FormationSuppression of the raw signal. Three ways to qualify: standing inside an officer's or sergeant's placed form line, sitting on a line your neighbours also sit on, or being in a tight cluster such as a square or a skirmisher knot. The last two cover regiments who line up manually without ever using the order.

Cavalry is not scored by default, since operating apart is its job. Artillery is never scored. Add anything else you do not want flagged to ExemptClasses.

Admin only

Every part of this mod that reveals another player is behind rc login. Without it, the mod draws nothing but your own scores.

That gate is deliberate. A HUD that marks isolated enemies is a wallhack in everything but intent, so it is tied to the server's own admin authentication rather than to a setting. RequireAdminLogin exists so you can test against bots on your own server, and turning it off gives you exactly what it sounds like.

Settings

BepInEx\config\com.ryannlt.adminhelper.cfg, written on first run. Read live, so edits apply within a second with no restart. Entries are grouped into [General], [Isolation], [Scoring], [Danger], [Formation], [Flagging] and [Display] sections.

For an in-game editor instead of a text file, ConfigurationManager works, but only after setting HideManagerGameObject = true under [Chainloader] in BepInEx\config\BepInEx.cfg. Holdfast's BepInEx pack ships that as false, which stops ConfigurationManager drawing at all.

Setting Default Effect
Enabled true Master switch. Off stops the scorer as well as the HUD.
TickHz 5 Scoring ticks per second.
RequireAdminLogin true Only reveal other players after an rc login.
ClusterNearMetres 10 Distance from your two nearest mates at which isolation starts counting.
ClusterFarMetres 30 Distance at which isolation is saturated.
RiseSeconds 6 Time constant for the score climbing.
RecoverMultiplier 3 How much faster it falls than it climbs.
EnemyRadius 30 How close an enemy must be before any isolation counts as danger.
EnemyCrowd 3 Enemies inside the radius that count as being fully inside their formation.
FormationSuppression 0.9 Fraction of the raw signal removed while in formation.
LineRadius 10 Radius searched for formation mates.
LineMinMates 2 Mates needed before the line fit is attempted.
LineMaxMates 6 Most mates fed into the line fit.
LineResidual 2 Metres of spread either side of the line still counted as a line.
ClusterMinMates 3 Mates close by that count as a square or skirmisher knot.
ClusterFormationRadius 8 Radius for the tight cluster test.
RingThreshold 40 ISO at which a marker appears. Follows the live score, so it clears on return.
RamboThreshold 75 ISO at which the dwell timer starts.
RamboHoldSeconds 5 Seconds of dwell above the threshold before flagging.
ScoreCavalry false Score cavalry too.
ExemptClasses empty Comma-separated class names never flagged, e.g. Surgeon,Sapper.
ShowRings true Ground ring under each watched player.
ShowLabels true Floating name and score label.
ShowCornerList true Corner list of watched players, worst first.
ShowOwnScore true Your own scores plus the raw distances behind them. Works without an rc login.
MaxLabels 12 Most floating labels at once, worst first.
ToggleKey F6 Key that hides and shows the HUD. Any KeyCode name.
StartHudVisible false Whether the HUD starts visible when the game launches.

Tuning it

ShowOwnScore is on by default and shows the raw inputs under your scores: how far you are from your two nearest mates, how far the nearest enemy is, whether you count as in formation, and your dwell time. Walk away from your own line and watch those move. Every threshold below is picked from that one readout.

The scale is set by two numbers. The score climbs towards the raw distance signal and stops there, so a player is only ever flagged if their distance alone clears the threshold. With the defaults:

Metres from your two nearest mates Score settles at
under 10 0
15 25
18 40, a marker appears
20 50
25 75, flagged as a rambo
30 and beyond 100

So a marker appears at about 18 m out and the rambo flag needs more than 25 m held for long enough: roughly 8 seconds to cross, plus RamboHoldSeconds on top.

  • Too many false positives? Raise ClusterFarMetres, which stretches the whole scale, or raise RiseSeconds so players have longer to get back.
  • Missing obvious rambos? Lower ClusterFarMetres. If your typical rambo sits 18 m out, set it to 22 and they cross.
  • Flagging too slowly? Lower RiseSeconds, or RamboHoldSeconds.

Dwell decays instead of resetting, so tapping back onto the line for a second does not wipe a rambo's timer. It falls at RecoverMultiplier times the rate it builds, which clears a long-standing flag in a few seconds once the player is genuinely back.

Troubleshooting

Nothing in the log at all, or no log. BepInEx is not running. Check that winhttp.dll and a BepInEx folder sit next to Holdfast NaW.exe. If you use a mod manager, launch the game from it rather than from Steam.

Mod loads but nothing is drawn. You are almost certainly not logged into the server console. Run rc login <password> and try again. If that is not it, check Enabled and press the toggle key.

Nothing is drawn and the log has no scene loaded line. The mod lost its frame loop. Open an issue with BepInEx\LogOutput.log; the driver awake, driver destroyed and scene loaded lines say what happened.

Rings are missing but labels work. The ring shader could not be found. Set ShowRings to false and open an issue with your log.

The game crashes on launch after adding the mod. Remove the .dll, launch to confirm the game is fine, then open an issue with BepInEx\LogOutput.log attached.

Building

Only needed if you want to change something. Otherwise use the release above.

Requires: the game installed, BepInEx installed in an r2modman profile, and a .NET SDK for the compiler.

powershell -ExecutionPolicy Bypass -File .\build.ps1

That compiles every .cs in the folder and copies the .dll into the r2modman profile's BepInEx\plugins\AdminHelper\. Restart the game to load it. Add -NoDeploy to build without copying, which is useful while the game is running and holding the file. -ProfileName picks a profile other than Dev.

package.ps1 builds the same way and stages an uploadable Thunderstore zip in Package\.

The script expects the default install path:

C:\Program Files (x86)\Steam\steamapps\common\Holdfast Nations At War

Edit $GameDir at the top of the script if yours differs.

The .csproj is for IDE support only. build.ps1 is the real build. It drives csc directly, which avoids needing a targeting pack installed.

Why there is no CI build

Building needs Assembly-CSharp.dll from a real install. Those are AGS files, not mine to redistribute, so they cannot be committed here and a GitHub Actions runner has no way to get them. Releases are built locally and uploaded by hand.

Compatibility

Built against Holdfast on Unity 2022.3.62f2 with BepInEx 5.4.23.5 (Mono). It reads named fields rather than offsets, so it usually survives game updates. If AGS renames or restructures the client player managers it will stop working rather than misbehave. Open an issue if that happens.

Licence

MIT. Do what you like with it, no warranty.

CHANGELOG

Changelog

1.2.0

Now built on RyLib, a shared UI library, so AdminHelper and other mods can add to the P menu without breaking each other. Mod managers install it automatically; by hand, it goes in BepInEx\plugins\RyLib\.

The overlay is drawn in the world, not on a HUD. Watched players glow through walls and terrain, with a ring at their feet and a label that sits under the P menu rather than over it. The corner list and your own score readout are gone, and with them ShowCornerList, ShowOwnScore and StartHudVisible. New ShowGlow.

Rambo UI modes. A Rambo UI button under the players list steps between Always On, Freeflight (only in free roam) and Off, like the game's Admin Raygun, and the mode is remembered between launches. F6 still hides and restores it. New RamboUi.

Colours say how bad it is. Isolation alone runs green to yellow; any danger turns the mark orange, deepening to red. FIGHT stays blue and AFK grey.

Spectate rambos with [ and ]. Steps through watched players worst first, and the game's own key bar shows a Spectate Rambos entry in free roam and while spectating. New SpectatePrevKey and SpectateNextKey.

All settings in the P menu, under a shared Mods tab: Mods > AdminHelper, grouped into Rambo Detection, Flags, Players Tab, Kill Log and Map.

Kill log. A melee kill is marked with crossed swords, explained by a line under the heading; the old IN MELEE / NO MELEE text is gone. While Rambo UI is on, names are coloured by their rambo mark at the moment of the kill. Clicking a row opens actions for the killer and the victim.

Reg TP prefers the same class. It sends a player to the middle of their regiment's players of the same class, and to the closest friendly player when there are none.

Flags glow in their faction's colour instead of a ring and beam, and follow the game's minimap reveal rules, with FlagMinimapAlways letting admins see all of them. New ShowFlagLabels. Every flag setting is now off by default, including FlagMinimapMarkers.

A battle map. A Map tab with an overhead picture of the battle, every player drawn by class in their faction's colour, a class legend, search, zoom, rambo outlines and flags, and admin actions that only fire after a button is pressed. Turn it off with MapEnabled or Mods > AdminHelper > Map.

1.1.2

The player search reads factions and sides. french, allied, austrian and the country names behind them all filter the players tab, and attackers or defenders resolve to whichever faction is attacking or defending this round. They combine with a class, so french cav is French hussars and dragoons and def surgeon is the defending side's surgeons, and plurals are understood throughout. Class groups grew too: skirmishers, rank & file, infantry, support and horse. Anything the mod cannot read is handed straight back to the stock name and tag search, so nothing that worked before stopped working. New FactionSearchEnabled.

Two new buttons on a player's admin row. Reg TP teleports that player to their own regiment - to the mate standing nearest the middle of the group, so they land in the line rather than on a straggler - and Rez + Reg TP revives a dead player first, waits for them to come back, then sends them. Both go through the game's own admin plumbing, and both live in the admin block, so they only exist once you are logged in. New RowActionsEnabled.

Source files are now grouped into Core, Game, Tracking, Overlay and PMenu folders. No behaviour change, but build.ps1 now recurses.

1.1.1

Three additions for CTF events.

Flags are highlighted. With the overlay up, every flag in the round gets a cyan ring and a beam, either at the carrier's feet or where the flag is lying, a label saying who has it, and a line at the top of the corner list with the distance. On the minimap the carrier's own pointer is tinted rather than doubled up, and a flag on the ground gets a marker of its own, named by its faction. Every flag carryable the game has counts, so this is not tied to one CTF mod. It ships off, since it only matters on a flag game mode - turn on FlagHighlightEnabled under the new [CTF] section.

Players standing still are greyed out. Anyone who has not moved for AfkSeconds is drawn grey with an AFK tag, so a parked player is not read as someone worth flying to. They keep their ring and their place in the list. New [AFK] settings.

Melee grace. A player who enters a melee without already being flagged is not flagged while it lasts, plus the usual window afterwards, and the label reads FIGHT. The last one or two left alive in a fight their mates started no longer read as rambos, while a player who runs in alone still flags. Their dwell keeps building underneath, so nothing is lost if they really are out on their own. Turn it off with MeleeGrace.

1.1.0

Two additions, both inside the game's own P menu rather than a separate window.

Find players by class or regiment. The players tab search box now also matches class names and shorthands, so rifleman, rifle, line, sgt and cavalry all narrow the list, with the count above it. Regiment tags are matched with punctuation and accents stripped from both sides, so [45e] is found by 45e or 45, and 7.Fuß by 7fus. Searching by name or ID is unchanged.

Kill log. Every kill is marked with whether the victim was in a melee when they died, so a teamkill in a scrum can be told apart from a clean one. A player counts as being in a melee once they hit, block, or are blocked by the other side, and that spreads to everyone standing within MeleeChainMetres of them. A blank mark means the mod was not tracking and does not know, which is never to be read as a clean kill. A square toggle beside the heading switches the log to teamkills only, and typing tk in its search box does the same.

New settings live under [PMenu] and [KillLog].

1.0.1

Fixed the BepInEx dependency. 1.0.0 depended on BepInEx-BepInExPack, which is not published in the Holdfast community, so mod managers could not resolve it and installed no loader. Now depends on HoldfastModding-BepInExPack_Holdfast. No code changes.

1.0.0

First release. Built for BepInEx 5.