Skip to content

Latest commit

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

BotTagsManager

A floating tag over the bots on the other team.

SwiftlyS2 1.4.5+.NET 10MIT


Built for the Nova Zombie Community zombie hunting server (Nova HunterZ CS Clan).

It is a standalone plugin though. There is nothing zombie specific in it and no dependency or anything else — it will run on any CS2 server that uses bots. Deathmatch, casual, retakes, surf, a practice server, whatever you have.

What it does

Makes bots get a visible tag over their head. Every bot on the opposite team gets a small floating label above its head. Your own side's bots get nothing extra, because the game has already handled them.

The label turns to face you, drops when the bot crouches, follows through respawns and model swaps, and cleans itself up properly when the round ends or the map changes.

Unlike the teammate markers, an enemy tag does not draw through walls. It sits in the world and gets occluded like anything else, so it tells you where a bot is once you can already see it — not where one is hiding.

  • Coloured by the bot's team, in the game's own blue and amber
  • Drawn in Stratum2, the game's UI font, unlit so it reads the same in any light
  • Optional downward arrow under the text
  • Never tags real players, HLTV, spectators, or a bot somebody has taken over
  • Survives infections, respawns, team switches, kicks and hot reloads
 BOT
▼
(o_o)

Requirements

  • A CS2 server running SwiftlyS21.4.5 or newer
  • The SwiftlyS2 managed (.NET) runtime enabled

Installing

  1. Grab BotTagsManager.zip from the Releases page.

  2. Extract it into your server's addons/swiftlys2/plugins/ folder. You should end up with:

    addons/swiftlys2/plugins/BotTagsManager/BotTagsManager.dll
    
  3. Restart the server, or load it live:

    sw plugins load BotTagsManager
    
  4. A commented config is written for you on first load at:

    addons/swiftlys2/configs/plugins/BotTagsManager/BotTagsManager.jsonc
    

That is it. Bots get tagged from the next spawn.

Building from source

You need the .NET 10 SDK.

git clone https://github.com/<you>/BotTagsManager.git
cd BotTagsManager
dotnet publish -c Release

The DLL lands in build/publish/BotTagsManager/, and a ready-to-drop build/BotTagsManager.zip is written next to it.

Commands

CommandChatPermissionWhat it does
sw_botags status!botags statusbottags/adminShows the current settings and how many tags are live
sw_botags reload!botags reloadbottags/adminRe-reads the config and rebuilds every tag

reload rebuilds rather than patches, on purpose. Font, size and scale are all baked in when the entity spawns, so patching would leave half the settings stale and make it look like the reload had not worked. Handy for tuning colour and height without bouncing the server between tests.

Grant the permission in addons/swiftlys2/configs/core/permissions.jsonc:

{
"Permissions": {
"Players": {
"76561198000000000": [ "bottags/admin" ]
}
}
}

Set AdminPermission to "" in the config if you would rather anyone could run it.

Configuration

Everything lives in BotTagsManager.jsonc. The file written on first load has all of this in it as comments.

SettingDefaultWhat it does
EnabledtrueOff loads the plugin but tags nothing
TagText"BOT"The word above the arrow. Short is better — past about six characters it looks silly
ShowArrowtrueThe little triangle under the text
DefaultColor"255 210 0""R G B", 0-255. Only used when team colours are off
TeamSpecificColorstrueColour by the bot's team instead of using DefaultColor
CounterTerroristColor"176 218 231"Only used when team colours are on
TerroristColor"251 225 105"Only used when team colours are on
Font"Stratum2"Must exist on the client. Arial, Arial Black and Verdana are safe fallbacks
Opacity255How solid the tag is, 0-255
FontSize80.0Rasterised size, scaled down by WorldUnitsPerPx
WorldUnitsPerPx0.09World height of a line is roughly FontSize × this
BaseHeight86.0Height above the bot
DuckHeightDelta18.0How far the tag drops when fully crouched
TrackDucktrueOff leaves the tag at BaseHeight and ignores the crouch
ReconcileIntervalSeconds0.25How often everything is swept and repaired
CrouchIntervalSeconds0.05How often the crouch is checked
IgnoreWarmupBotsfalseSkip tagging during warmup
AdminPermission"bottags/admin"Permission for sw_botags. Blank lets anyone run it

Notes on a few of them

DefaultColor is amber.

TeamSpecificColors colours by the bot's own team, in the same blue and amber the game uses over your own side. Turn it off and every bot gets DefaultColor instead, which reads better on a server where bots change sides mid-round.

Font defaults to Stratum2, the game's own UI face — it ships with CS2 as csgo/panorama/fonts/stratum2.uifont and the client registers it, so it is the same lettering as the stock markers. If a client cannot resolve it the arrow renders as a box; Arial Black is the closest safe fallback.

FontSize and WorldUnitsPerPx work together. The text is rasterised into a texture at FontSize and then scaled into the world by WorldUnitsPerPx. Turning FontSize down to make the tag smaller gives you a low-resolution texture that looks mushy up close — leave it high and lower WorldUnitsPerPx instead.

BaseHeight and DuckHeightDelta — the pawn origin sits at the feet, the standing hull is 72 units and the crouched hull is 54. So 86 clears the head with a bit of room, and a delta of 18 keeps that gap identical in both stances.

CrouchIntervalSeconds is how often a bot's crouch is checked. A tag rides its bot on the client, so this only sends anything when the bot actually ducks or stands back up.

IgnoreWarmupBots reads the game's own m_bWarmupPeriod. If your server's warmup is a mod's own implementation rather than the native one, this will not see it.

Notes

The tag rides the bot itself rather than being moved into place by the server. That is what makes it glide instead of stepping from one spot to the next as the bot runs.

It is deliberately not attached to a head bone, though. A bone follows the animation, so the tag would bob and sway with every run cycle and idle twitch. Driving the height off the crouch amount instead keeps it rock steady while still following the duck.

Depth offset is left at zero on purpose. That is what keeps the tag behind walls instead of in front of them.

The tag is drawn fullbright, so a bot in a dark corner reads exactly the same as one stood in the sun.

Two things about the stock markers this cannot copy, both because a tag is one world entity shared by everybody rather than a HUD element drawn per player:

Everything is destroyed at round end. That is not just tidiness, the round restart runs the engine's entity preserve pass, and a plugin-spawned entity still alive when it happens is a known way to crash clients. The sweep puts every tag back within a quarter second of the respawn anyway.

Licence

MIT. See LICENSE.

About

A floating tag over the bots on the other team. A SwiftlyS2 plugin for CS2.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages