Android emulators

as we all know alot of exploiters use android emulators and they install delta or vega x or any exploiting apks. what about kicking those who use emulators. this would take away alot of the exploiters. and there is a way of doing this and i will show you how. first create a localscript in starterplayerscripts and paste this code into it. the ban api just bans if the localscript is deleted.

local UIS = game:GetService("UserInputService")
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local REMOTE_TAG = "SecurityKey"
local currentRemote = nil

-- Wait for the server to provide our unique session token
local sessionToken = player:GetAttribute("S_Key")
while not sessionToken do
	task.wait(0.5)
	sessionToken = player:GetAttribute("S_Key")
end

local function updateRemote()
	local tagged = CollectionService:GetTagged(REMOTE_TAG)
	if #tagged > 0 then currentRemote = tagged[1] end
end

CollectionService:GetInstanceAddedSignal(REMOTE_TAG):Connect(function(instance)
	currentRemote = instance
end)

updateRemote()

-- Heartbeat with TOKEN verification
task.spawn(function()
	while true do
		if currentRemote then
			-- Sending the token so the server knows it's the LEGIT script
			currentRemote:FireServer("HEARTBEAT", sessionToken)
		end
		task.wait(20)
	end
end)

-- Emulator Check
task.spawn(function()
	task.wait(5)
	if UIS.TouchEnabled and UIS.KeyboardEnabled and UIS.MouseEnabled and (UIS.GyroscopeEnabled or UIS.AccelerometerEnabled) then
		if currentRemote then
			currentRemote:FireServer("EMULATOR_SIGNAL")
		end
	end
end)

ice in the script there is local hastouch local haskeyboard and local hasmouse all emulators dont have these this way you can detect them and kick them. now onto the serverscript
Server Script: Emulator Detection & Kick System

This script receives emulator detection signals from clients and kicks any detected emulator instances.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")

local ROTATION_SPEED = 10 
local REMOTE_TAG = "SecurityKey"
local WHITELIST = {1, 2, game.CreatorId} 

-- Store session tokens here (not accessible to clients)
local activeSessions = {}

local function issueBan(player, reason, privateReason)
	if table.find(WHITELIST, player.UserId) then return end
	Players:BanAsync({
		UserIds = {player.UserId},
		Duration = -1,
		DisplayReason = "\n[SECURITY]\n" .. reason,
		PrivateReason = privateReason,
		ExcludeAltAccounts = true 
	})
end

local function rotateRemote()
	local newRemote = Instance.new("RemoteEvent")
	newRemote.Name = "Net_" .. math.random(1000, 9999)
	CollectionService:AddTag(newRemote, REMOTE_TAG)
	newRemote.Parent = ReplicatedStorage

	newRemote.OnServerEvent:Connect(function(player, action, token)
		if action == "HEARTBEAT" then
			-- Verify the token belongs to this specific player session
			if token == activeSessions[player.UserId] then
				player:SetAttribute("LastCheck", os.time())
			else
				issueBan(player, "Security Protocol: Token Mismatch.", "Invalid Session Token")
			end
		elseif action == "EMULATOR_SIGNAL" then
			player:Kick("Please Play On A Real Device Not A Emulator.")
		end
	end)

	for _, old in pairs(CollectionService:GetTagged(REMOTE_TAG)) do
		if old ~= newRemote then
			CollectionService:RemoveTag(old, REMOTE_TAG)
			task.delay(1, function() if old then old:Destroy() end end)
		end
	end
end

Players.PlayerAdded:Connect(function(player)
	-- Generate a random token for this session
	local sessionToken = "ST_" .. math.random(100000, 999999)
	activeSessions[player.UserId] = sessionToken
	player:SetAttribute("LastCheck", os.time())

	-- Give the token to the client via an Attribute (Harder to intercept than a Remote)
	player:SetAttribute("S_Key", sessionToken)
end)

-- The Watchdog remains the same, checking LastCheck every few seconds
task.spawn(function()
	while true do rotateRemote(); task.wait(ROTATION_SPEED) end
end)

Your formatting sucks

local UIS = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remote = ReplicatedStorage:WaitForChild("EmulatorKick")

task.wait(1)

local hasTouch = UIS.TouchEnabled
local hasKeyboard = UIS.KeyboardEnabled
local hasMouse = UIS.MouseEnabled

if hasTouch and hasKeyboard and hasMouse then
	Remote:FireServer("EMULATOR")
end
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local Remote = ReplicatedStorage:FindFirstChild("EmulatorKick")
if not Remote then
	Remote = Instance.new("RemoteEvent")
	Remote.Name = "EmulatorKick"
	Remote.Parent = ReplicatedStorage
end

local EmuTracker = {}

local COOLDOWN = 30

local KICK_MESSAGE = [[
:stop_sign: ACCESS BLOCKED :stop_sign:

This experience only allows official Roblox clients running on real devices.

Detected Android emulators are not permitted. Examples include, but are not limited to:

    BlueStacks
    NoxPlayer
    LDPlayer
    MEmu
    MuMuPlayer

Running multiple emulator instances is not allowed — each instance will be kicked automatically.

Please close all emulators and play directly on a standard mobile device or PC.

:stop_sign: This action is enforced automatically. :stop_sign:
]]

Remote.OnServerEvent:Connect(function(player, flag)
	if flag ~= "EMULATOR" then return end

	local userId = player.UserId
	if not EmuTracker[userId] then
		EmuTracker[userId] = { count = 0, lastKick = 0 }
	end

	local now = tick()
	-- reset count if last detection was more than COOLDOWN seconds ago
	if now - EmuTracker[userId].lastKick > COOLDOWN then
		EmuTracker[userId].count = 0
	end

	EmuTracker[userId].count = EmuTracker[userId].count + 1
	EmuTracker[userId].lastKick = now

	warn(string.format("[ANTI-EMU] Detected emulator instance #%d for player %s (UserId: %d)",
		EmuTracker[userId].count, player.Name, userId))

	-- Kick the instance
	player:Kick(KICK_MESSAGE)

end)

Players.PlayerRemoving:Connect(function(player)
	EmuTracker[player.UserId] = nil
end)

You know you can plug in a keyboard and mouse on any android device, what if someone just plays with a keyboard and mouse on mobile?

1 Like

they can play normally on mobile not emulators

:white_check_mark: Real Mobile Device (Phone/Tablet)

  • TouchEnabledtrue :white_check_mark:
  • KeyboardEnabledfalse :cross_mark: (most mobiles don’t have physical keyboard)
  • MouseEnabledfalse :cross_mark: (most mobiles don’t have a mouse)

:white_check_mark: Android Emulator on PC

  • TouchEnabledtrue (emulated)
  • KeyboardEnabledtrue :white_check_mark: (PC always has keyboard)
  • MouseEnabledtrue :white_check_mark: (PC always has mouse)

@Tavikron I modified both scripts so you can use the Device Emulator in Studio without being kicked.

Replace the previous local script for this one
if game:GetService("RunService"):IsStudio() then return end

local UIS = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remote = ReplicatedStorage:WaitForChild("EmulatorKick")

local hasTouch = UIS.TouchEnabled
local hasKeyboard = UIS.KeyboardEnabled
local hasMouse = UIS.MouseEnabled

if hasTouch and hasKeyboard and hasMouse then
	Remote:FireServer("EMULATOR")
end
Replace the previous server script for this one
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

if RunService:IsStudio() then return end

-- Create RemoteEvent if it doesn’t exist
local Remote = ReplicatedStorage:FindFirstChild("EmulatorKick")
if not Remote then
	Remote = Instance.new("RemoteEvent")
	Remote.Name = "EmulatorKick"
	Remote.Parent = ReplicatedStorage
end

-- Track emulator instances per UserId
local EmuTracker = {} -- [UserId] = { count = number, lastKick = tick() }

-- Temporary cooldown (in seconds) to prevent rapid reconnect abuse
local COOLDOWN = 30

-- Professional kick message
local KICK_MESSAGE = [[
:stop_sign: ACCESS BLOCKED :stop_sign:

This experience only allows official Roblox clients running on real devices.

Detected Android emulators are not permitted. Examples include, but are not limited to:

BlueStacks
NoxPlayer
LDPlayer
MEmu
MuMuPlayer
Running multiple emulator instances is not allowed — each instance will be kicked automatically.

Please close all emulators and play directly on a standard mobile device or PC.

:stop_sign: This action is enforced automatically. :stop_sign:
]]

-- Server receives emulator detection
Remote.OnServerEvent:Connect(function(player, flag)
	if flag ~= "EMULATOR" then return end

	local userId = player.UserId
	if not EmuTracker[userId] then
		EmuTracker[userId] = { count = 0, lastKick = 0 }
	end

	local now = tick()
	-- reset count if last detection was more than COOLDOWN seconds ago
	if now - EmuTracker[userId].lastKick > COOLDOWN then
		EmuTracker[userId].count = 0
	end

	EmuTracker[userId].count = EmuTracker[userId].count + 1
	EmuTracker[userId].lastKick = now

	warn(string.format(
		"[ANTI-EMU] Detected emulator instance #%d for player %s (UserId: %d)",
		EmuTracker[userId].count, player.Name, userId
		))

	-- Kick the instance
	player:Kick(KICK_MESSAGE)
end)

-- Clean up tracker when player leaves
Players.PlayerRemoving:Connect(function(player)
	EmuTracker[player.UserId] = nil
end)
1 Like

if you play on pc why would you want to have a emulator?

Mobile users can connect a keyboard and mouse with OTG USB Hubs. I used to do that before I bought a laptop to play Roblox. Besides this, laptops with touch screens exist. Players who play on Linux and may get their sessions misidentified as mobile devices as well.

keyboards and mice can be used on mobile devices, so this is going cause some false positives

I already know that and really don’t care about this thread, it’s poorly made.

  1. This would prevent a ton of Chromebook and other laptop users from playing the game.
  2. Hooking Remote Events is an extremely simple task. It takes less than 20 minutes to write a hook to bypass the detection.

This isn’t an effective way to detect emulators or prevent exploiting.

Hey dude, are you ok? I think there’s a better/more respectful way to give critical feedback on this thread