This repository provides an AFK system that prevents players from being kicked for inactivity and allows players to manually toggle their AFK status. It also adds an AFK tag above the player’s head to visually indicate whether they are AFK. [ I was feeling bored so I made this. Enjoy! ]
Features
Prevents AFK kick by simulating player activity every 30 seconds.
Allows players to manually toggle their AFK status with a UI button.
Displays an AFK tag above the player’s head when they are AFK.
Updates the UI button with a green “AFK” or red “Not AFK” based on the player’s status.
Setup Instructions
Follow these steps to set up the AFK system in your Roblox game.
Create a ReplicatedStorage folder if it does not already exist.
Inside ReplicatedStorage, create the following objects:
SimulateActivity (RemoteEvent): Used to simulate player activity every 30 seconds.
AFKTag (BillboardGui): A template for the AFK tag that will be placed above the player’s head when they are AFK.
The AFKTag should look like this:
AFKTag (BillboardGui)
Frame (Frame)
AFKTagText (TextLabel)
3. Add the LocalScript
Insert the LocalScript into a ScreenGui or a suitable UI component within the player’s GUI.
This script controls the UI and AFK logic for the player.
4. Add the Script to Handle AFK Simulation
Insert the Script into ServerScriptService.
This script will handle the remote event (SimulateActivity) to keep the player from being kicked due to inactivity.
5. Customize the UI
You can customize the AFK button’s appearance, text, and layout by modifying the LocalScript and the button inside your UI.
The AFKTag (BillboardGui) can also be customized to fit your game’s theme.
6. Test the AFK System
In Roblox Studio, run the game in Play mode.
The AFK button will appear in the player’s GUI. Clicking the button will toggle the AFK state.
If the player remains inactive for more than 5 minutes, the AFK state will automatically be enabled.
The AFK tag will appear above the player’s head when they are AFK.
The system will prevent the player from being kicked for inactivity.
Troubleshooting
AFK tag is not appearing: Ensure the AFKTag template in ReplicatedStorage has the correct setup (BillboardGui and child objects like Frame and TextLabel).
Button click does not toggle AFK: Ensure the LocalScript is correctly inserted into a ScreenGui and that the button’s MouseButton1Click event is connected properly.
Player gets kicked despite AFK system: Verify that the SimulateActivity RemoteEvent is being fired every 30 seconds.
I don’t think that firing remote events will reset the afk time… Considering I’ve played many games where remotes are fired constantly, it uses user input to detect, not remote events
I’m not sure how you’d properly make an anti afk, but remote events sadly won’t work
Any touching to the server will as if you don’t have a handshake then an exploiter can just write a script to prevent the player kick via hooks. Only way to prevent this is by shooting remotes to the server every time there’s an input and then going from there.
As I promised, here is an improved AFK system with a nice anti-cheat. I have already tested it, and it works perfectly.
Features
AFK System
Players can toggle their AFK status with a button.
AFK status is visually indicated with a UIGradient button and a BillboardGui tag above the player’s head.
The system automatically detects inactivity and toggles AFK status after a configurable timeout.
Anti-Exploit System
Event Rate Limiting: Prevents players from spamming the AFK RemoteEvent.
Checksum Verification: Ensures that RemoteEvent calls are legitimate.
Suspicious Activity Tracking: Flags players who repeatedly misuse the system.
Ban Mechanism
Automatically bans players who exceed the suspicious activity threshold.
Persistent bans are managed using Roblox’s DataStore (Ban:Async).
Installation
The installation is very easy. Just add it to your project, drag everything to where it needs to be, and ungroup the items. They have labels to help you identify where to drag them.
Run the game and toggle the AFK button.(Make sure to actually join the game instead of running it in studio, as the studio doesn’t have the timer like the actual game does.)
Verify the AFK tag appears and disappears as expected.
Check the server logs for valid RemoteEvent calls.
Anti-Exploit Testing
Spamming RemoteEvent
Use the Developer Console (F9) to spam the RemoteEvent:
for i = 1, 100 do
game.ReplicatedStorage.SimulateActivity:FireServer(os.time(), "invalid_checksum")
wait(0.1)
end
Not gonna lie, this system is pretty cool. Keep working on it. If a player is ‘AFK’, and they’re actively interacting with something, or moving, you should automatically set their status to not afk incase they have forgot to change their status or they have kept the AFK status. I feel that’d be more efficient.
Automatically marks a player as AFK when they tab out of the game.
Resets AFK status upon returning to the game.
When you’re interacting with the game and you are AFK, it will automatically turn off.
Installation
The installation is very easy. Just add it to your project, drag everything to where it needs to be, and ungroup the items. They have labels to help you identify where to drag them.
Known Issues:
None reported.
Future Improvements:
Logging:
Add server-side logging to track AFK trends and suspicious activities.
If you have any suggestions, please feel free to share them.
For the anti-cheat system, exploiters can easily access the local script and grab the secret key so I think that it is useless as well, the rate-limiting function makes sense but I don’t think the checksum provides any security
Finally anti afk does not work, firing remotes is not the way to do I’ve tested in an actual roblox game
This part of the code is responsible for detecting player inactivity and automatically toggling AFK status. If a player remains inactive for too long, they are marked as AFK. Conversely, if they resume activity, their AFK status is removed.
game:GetService("RunService").Heartbeat:Connect(function()
for player, data in pairs(playerStates) do
if player.Character and player.Character:FindFirstChild("Humanoid") then
local currentTime = os.time()
local isInactive = (currentTime - data.lastInputTime) > Config.AFKTimeout
if isInactive and not data.isAFK then
-- Mark as AFK
data.isAFK = true
local afkTag = afkTagTemplate:Clone()
afkTag.Parent = player.Character
afkTag.Adornee = player.Character:FindFirstChild("Head")
print(player.Name .. " is now AFK.")
elseif not isInactive and data.isAFK then
-- Remove AFK status
data.isAFK = false
local afkTag = player.Character:FindFirstChild("AFKTag")
if afkTag then afkTag:Destroy() end
print(player.Name .. " is no longer AFK.")
end
end
end
end)
You made some great points, and I appreciate your feedback. I will review and refine the code further to improve its efficiency. Thanks again!
Also, note that you should probably use task.wait(1/30) instead of wait(). Does it really matter in this case? No, not really. Just note that wait is deprecated.
My point is the last input time always updates every 30 seconds so that bit of code is pointless unless u fire remotes only when there is an input rather than in a loop
Roblox detects inactivity based on last input. That’s why exploiters circumvent this detection by using the VirtualUser service, but that’s not accessible by games.
A remote called “SimulateActivity” won’t do anything, since it’s normal for remotes to fire even if the player is AFK. It has nothing to do with input, so the timer doesn’t reset.
The only feasible way to implement anti-AFK is to use TeleportService, but even then you should realize that that’s just a hack and could be patched in the future.