AFK
Automatic AFK, idle kick, tab list indicator.
Commands 2#
Examples#
Go AFK manually with a reason#
You want to mark yourself as away and show a reason in the broadcast, without waiting for the timeout.
/afk back in 10 minutes
You personally get now_afk. If afk.broadcastOnAfk (or enableafkBroadcasts) is on, everyone gets afkMessage with {player} and the given reason. A second /afk clears the status (no_longer_afk + returnMessage). /afk is in excludedCommands, so the command handler does not reset the timer or clear AFK before the toggle.
Return by moving, not by command#
Check that the movement detector clears AFK on its own.
/afk
/afk
The first call sets AFK. After that, just walk: every 5 s AfkMovementDetector compares position/yaw/pitch against the movementThreshold (0.1) and rotationThreshold (5.0) thresholds. If enableActivityTracking and trackMovement are on, updateActivity clears AFK and sends the return broadcast. The second /afk in the example is the manual return if you do not want to move. Turning your head in place counts; small drift below the threshold does not.
Edge cases#
The tab list indicator comes from tablist.json, not from afk#
AfkTablistHandler computes prefix/suffix from AfkManager fields (enableTablistIndicator, tablistAfkPrefix, tablistAfkSuffix), but setTabListDisplayName is commented out — it does not change the name in the list. The actual suffix is drawn by TablistManager: tablist.json → showAfkIndicator (true by default) and afkSuffix (&7[AFK] by default). There are no enableTablistIndicator / tablistAfkPrefix keys in the afk config section.
What to do: Configure the indicator in tablist.json. The afk section handles the timeout, kick, broadcasts and detectors, not the text in the player list.
Kick: kickTimeout, exempt and the warning#
Checked every 30 s. Kick is on if kickTimeout > 0 (seconds; a compatible kickTimeoutMinutes exists), or explicitly with kickAfkPlayers: true. An explicit kickAfkPlayers: false suppresses the kick even with timeout > 0. If kick is enabled with timeout 0, the code forces 30 minutes and logs an error. neoessentials.afk.exempt skips only the kick, not auto-AFK. A kick_warning is sent a minute before the kick; because of the 30 s step the message may repeat. The kick text is afkkickMessage, otherwise the localized template.
What to do: For a kick, kickTimeout: 900 (15 minutes after going AFK) is enough. Grant staff neoessentials.afk.exempt.
Movement detector and anti click-farm#
AfkMovementDetector is a separate thread that reads coordinates via server.execute every 5 s. It counts only if enableActivityTracking and trackMovement are on. Chat (trackChat), commands (trackCommands) and interactions (trackInteractions) are separate switches; the master enableActivityTracking: false turns off all four. AfkActivityHandler on clicks/drops: more than 30 identical actions in 60 s build up a score; after 300 that action stops resetting the timer. Default excludedCommands: afk, list, who, tps, ping, help, ?.
What to do: Block-click macros will not keep a player out of AFK once the score is exceeded. If /list should not clear AFK, it is already in the list; /away is not (see knownIssues).
/afk requires the chat module to be enabled#
Despite the separate AFK system, the command exits with commands.neoessentials.afk.disabled if isChatEnabled() is false or ChatManager.isAfkEnabled() is false. Auto-marking by timeout lives in AfkManager and does not depend on the chat command, but the manual toggle is unavailable.
What to do: Keep the chat module on if you need /afk. To turn off only the manual command, use commands.afk: false (this also disables /away).
Sleep, invulnerability and storage#
ignoreAfkInSleep: true (the default) excludes AFK players from the sleep percentage. invulnerableWhenAfk is false by default. State is written to the afk_data collection (the legacy afk_data.json file is migrated); autoSave / saveInterval control periodic flushing. The auto-AFK check runs every 30 s, so an actual timeout of 300 s may fire between 300 and 330 s.
What to do: Do not expect to-the-second accuracy. Better not to enable invulnerableWhenAfk on PvP arenas.
Known issues#
/away does not clear AFK while trackCommands is on#
CommandEvent fires before executes. For /away (not in the default excludedCommands) AfkCommandHandler calls updateActivity: if the player is already AFK, the status is cleared. Then toggleAfk sets AFK again — chat may get both the return message and "is now AFK", and the player stays AFK. /afk is in the exclusion list, so toggling back and forth works.
What to do: Return with /afk or by moving. Or add away to afk.excludedCommands.
Permissions 2#
Detailed guide#
The section below is the project's original documentation (docs/Wiki/AFKSystem.md). Links to other wiki pages are rewritten to this site; the guides themselves are not edited, so upstream syncs stay conflict-free.
Version: 1.0.2.6 · Config: config.json → afk section
Overview#
The AFK system automatically marks players as AFK after a configurable period of inactivity, broadcasts status changes, shows an indicator in the tablist, and optionally kicks long-term AFK players.
Config (config.json → afk)#
| Key |
Default |
Description |
enabled |
true |
Enable/disable the AFK system |
timeout |
300 |
Seconds of inactivity before a player is marked AFK |
kickTimeout |
0 |
Seconds after going AFK before being kicked (0 = disabled). Setting this to any value > 0 automatically enables AFK kicking. |
kickAfkPlayers |
(auto) |
Optional explicit override. Omit this key (recommended) and let kickTimeout > 0 enable kicking. Set to false to force-disable kicking even if kickTimeout > 0. |
afkkickMessage |
"Kicked for being AFK too long" |
Message shown on AFK kick |
enableafkBroadcasts |
true |
Broadcast AFK status changes to all players |
broadcastOnAfk |
true |
Broadcast when a player goes AFK |
broadcastOnReturn |
true |
Broadcast when a player returns from AFK |
afkMessage |
"{player} is now AFK" |
Broadcast when going AFK ({player} placeholder) |
returnMessage |
"{player} is no longer AFK" |
Broadcast on return |
ignoreAfkInSleep |
true |
AFK players do not count for sleep percentage |
enableActivityTracking |
true |
Track player activity to detect inactivity |
trackMovement |
true |
Player movement resets AFK timer |
trackChat |
true |
Chat messages reset AFK timer |
trackCommands |
true |
Commands reset AFK timer |
trackInteractions |
true |
Block/entity interactions reset AFK timer |
movementThreshold |
0.1 |
Minimum movement distance to count as activity |
rotationThreshold |
5.0 |
Minimum look-rotation change to count as activity |
excludedCommands |
["afk","list","who","tps","ping","help","?"] |
Commands that do NOT reset the AFK timer |
invulnerableWhenAfk |
false |
Make AFK players immune to damage while AFK |
autoSave |
true |
Periodically save AFK state to disk |
saveInterval |
60 |
Auto-save interval in seconds |
enableActivityTracking is a master switch — set it to false and none of trackMovement/
trackChat/trackCommands/trackInteractions reset the AFK timer regardless of their own value.
Each of the four sub-toggles independently gates its own activity source (movement ticks, chat
messages, command execution, block/item interactions). A genuine, non-muted, non-frozen chat
message now resets the AFK timer when trackChat is enabled (previously chat never reset the
timer at all, regardless of this setting — fixed alongside the rest of this audit).
Tablist AFK indicator is NOT configured here. The enableTablistIndicator/
tablistAfkPrefix/tablistAfkSuffix keys previously documented in this section don't exist in
the shipped afk config, and the code path that would consume them (AfkTablistHandler) is
dead — it computes a display name but never applies it. The AFK indicator that actually renders
is controlled by tablist.json → showAfkIndicator (default true) and afkSuffix (default
" &7[AFK]", suffix only — there's no separate prefix option). See
Tablist System for the rest of that config.
Commands#
| Command |
Syntax |
Permission |
Description |
/afk |
/afk [message] |
neoessentials.afk |
Toggle your AFK status manually, optionally with a custom reason shown in the broadcast |
/away |
alias |
same |
Alias |
Permissions#
| Node |
Default |
Description |
neoessentials.afk |
✅ |
Use /afk to manually toggle AFK |
neoessentials.afk.exempt |
🔒 |
Exempt from AFK kick timer |
How It Works#
- Activity detection —
AfkActivityHandler listens for movement, chat, commands, and interactions. Each event that passes the threshold resets the player's inactivity timer.
- AFK trigger — After
timeout seconds of no qualifying activity, AfkManager marks the player as AFK, broadcasts the message, and updates the tablist.
- Return — Any qualifying activity while AFK removes the AFK flag and broadcasts the return message.
- Kick — If
kickTimeout > 0, a player who remains AFK longer than that value is kicked with afkkickMessage.
- Sleep — With
ignoreAfkInSleep: true, AFK players are excluded from the sleep count so the night can be skipped without them.
- Invulnerability — With
invulnerableWhenAfk: true, players take no damage while AFK.
Anti-Spam Filter#
The activity tracker (AfkActivityHandler, covering block/item right-click, left-click-attack, and item-toss events) has a built-in repetitive-action filter. If the same action type occurs more than 30 times within a rolling 60-second window, the suspicion score increases by 10 per occurrence over that threshold; once the score exceeds 300 that action stops resetting the AFK timer, preventing AFK farms via automated clicking. The score decays by 5 the next time that action type recurs after a 5-minute gap (it does not decay purely from the 60-second window elapsing).
Back to Wiki Home