Bots are drawn from two lists in data.yml. A bot takes a name and an IP, and that pair stays together while it is online. A name already online will not be picked twice.
Edit both under Names & IPs in the menu, or use commands:
/ultraspoof generate-names 50 pulls 50 names from our name API./ultraspoof generate-ips 50 makes up 50 IPs./ultraspoof import <url-or-names> takes a URL or a list you paste in.Bots wear the real skin of whoever owns that name on Mojang. So AlexPvP looks like AlexPvP. If nobody owns the name, the bot gets the default skin and nothing else changes. Skins are cached for 30 minutes, and a failed lookup never stops a bot from joining.
Spawn points live in data.yml and each one has a weight. Higher weight means picked more often. Add them from the menu while standing where you want them.
Two modes.
MATCH_PLAYERS copies the range your real players actually have. This is the realistic one. default is the value used when nobody real is online, and max-step caps how far a ping can move in one update.
CONFIGURED walks between a min and a max you set, with separate chances and step sizes for going up and going down.
update-seconds is how often every bot's ping moves.
Each rank has a name, a weight and a list of console commands. When a bot first gets a rank, those commands run with %player% replaced by its name. That is how you wire it to LuckPerms or whatever you use:
lp user %player% parent set vip
no-rank-weight is the chance of getting nothing. With 25 there and one VIP rank at 5, most bots stay plain.
A rank sticks to the name, so a bot keeps it across sessions. Turn the whole thing off with ranks.enabled.