Skip to main content
The friend system allows you to designate specific players as friends, protecting them from combat modules and providing visual indicators.

Overview

The FriendManager (features/misc/FriendManager.kt:32) maintains a list of friends and automatically handles friend-related events throughout the client.

Configuration

CancelAttack Option

Prevents attacking friends when enabled:
val cancelAttack by boolean("CancelAttack", false)
When enabled, the AttackEntityEvent is cancelled if the target is a friend (FriendManager.kt:46-50).

Managing Friends

Friend Data Structure

Each friend consists of:
class Friend(val name: String, var alias: String?)
  • name: Player’s Minecraft username (unique identifier)
  • alias: Custom display name (optional)
Friends are stored in a TreeSet for automatic sorting and duplicate prevention (FriendManager.kt:34).

Using the Friend Command

The .friend command provides full friend management:
1

Add a Friend

.friend add <name> [alias]
Adds a player to your friend list with an optional custom alias
2

Remove a Friend

.friend remove <name>
Removes a player from your friend list
3

Set Alias

.friend alias <name> <new_alias>
Changes the display name for a friend
4

List Friends

.friend list
Displays all friends with interactive remove buttons
5

Clear All

.friend clear
Removes all friends from the list

Checking Friend Status

The manager provides utility methods to check if a player is a friend:
// Check by username
if (FriendManager.isFriend("playerName")) {
    // Player is a friend
}

// Check by entity
if (FriendManager.isFriend(entity)) {
    // Entity is a friend
}
The entity check validates that the entity is a Player before checking the name (FriendManager.kt:78).

Event Integration

TagEntityEvent

Automatically tags friend entities for visual identification:
private val tagEntityEvent = handler<TagEntityEvent> {
    if (isFriend(it.entity)) {
        it.assumeFriend()
    }
}
This allows modules and rendering systems to display friends differently (FriendManager.kt:39-43).

AttackEntityEvent

Prevents attacking friends when CancelAttack is enabled:
private val onAttack = handler<AttackEntityEvent> {
    if (cancelAttack && isFriend(it.entity)) {
        it.cancelEvent()
    }
}

Storage and Persistence

Friends are stored in the config system with ValueType.FRIEND:
val friends by list(name, TreeSet<Friend>(), valueType = ValueType.FRIEND)
The friend list is automatically:
  • Loaded on client startup
  • Saved when modified
  • Sorted alphabetically by username

Use Cases

Combat Protection

Enable CancelAttack to prevent your combat modules from targeting friends during PvP scenarios.

Visual Identification

ESP and nametag modules can use the friend status to:
  • Display friends in different colors
  • Show friend indicators
  • Hide or prioritize friend information

Team Gameplay

Mark teammates as friends to:
  • Avoid friendly fire in team modes
  • Coordinate with the same players across servers
  • Maintain persistent friend relationships

Command Examples

Interactive friend list display (CommandFriend.kt:84-127):
- Steve (Best Friend) [X]
- Alex (Teammate) [X]
- Notch (Legend) [X]
Each entry includes:
  • Username (clickable to copy)
  • Alias in parentheses
  • Red [X] button to remove (click to suggest remove command)

Implementation Notes

The Friend class implements Comparable<Friend> for automatic sorting (FriendManager.kt:71) and overrides equals() and hashCode() to compare by name only (FriendManager.kt:58-69). Default aliases use the format “Friend ” when no custom alias is set (FriendManager.kt:73).

Build docs developers (and LLMs) love