§ How to · with Forge AI

How to make a Roblox FPS (with AI)

A Roblox FPS needs five wired-up systems: server-authoritative hit detection, ammo + reload, weapon switching, recoil pattern, and respawn. Forge AI generates all five in 2m 35s — including the FOV punch on fire and ADS animation.

14 files · 480 lines · 2m 35s · 1 credit. Three weapons by default (rifle, shotgun, pistol) — extensible.

Server-authoritative hits

Client casts the ray, sends hit position. Server re-casts from the player's CFrame to validate. No client-trusted hit damage.

Ammo + reload

Per-weapon mag size, reserve ammo, reload duration. Server tracks ammo state — exploiters cannot fire empty clips.

Weapon switching

1/2/3 keys swap between weapons. Each weapon is a Tool with attached attributes (damage, mag, recoil).

Recoil pattern

Per-weapon recoil curve (vertical kick + horizontal randomness). FOV punch on fire for game feel.

ADS (aim down sights)

Right-mouse aims, narrows crosshair, lowers recoil, shifts FOV. Tween-based, smooth.

Respawn flow

Death → 5s timer → respawn at SpawnLocation, re-equip last weapon. Configurable respawn delay.

Files Forge AI ships for this prompt

14 files · 480 lines · 2m 35s · 1 credit

ServerScriptService/WeaponServer.lua

Hit re-cast + damage application

92 lines

ServerScriptService/AmmoService.lua

Per-player ammo state, reload state machine

48 lines

ReplicatedStorage/Modules/WeaponConfig.lua

Per-weapon damage, mag, recoil tables

64 lines

ReplicatedStorage/Remotes/FireRemote

Fire request RemoteEvent

instance

ReplicatedStorage/Remotes/ReloadRemote

Reload request RemoteEvent

instance

StarterPlayer/StarterPlayerScripts/WeaponClient.lua

Input → ray cast → fire remote

84 lines

StarterPlayer/StarterPlayerScripts/RecoilController.lua

Recoil curve + FOV punch

38 lines

StarterPlayer/StarterPlayerScripts/ADSController.lua

FOV tween on right-mouse

26 lines

StarterPack/Rifle (Tool)

Rifle Tool with attached attributes

instance

StarterPack/Shotgun (Tool)

Shotgun Tool

instance

StarterPack/Pistol (Tool)

Pistol Tool

instance

StarterGui/WeaponHUD.lua

Ammo + reserve display, weapon icon

32 lines

StarterGui/Crosshair.lua

Dynamic crosshair, narrows on ADS

20 lines

StarterGui/HitMarker.lua

Server-fired hit marker pop-up

16 lines

Sample output: ServerScriptService/WeaponServer.lua

--!strict
-- ServerScriptService/WeaponServer.lua  (Forge AI · excerpt)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local FireRemote = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("FireRemote")
local Config = require(ReplicatedStorage.Modules.WeaponConfig)

local lastFire: { [number]: number } = {}

FireRemote.OnServerEvent:Connect(function(player: Player, weaponName: string, hitPos: Vector3)
    local weapon = Config[weaponName]
    if not weapon then return end
    local now = tick()
    if lastFire[player.UserId] and now - lastFire[player.UserId] < weapon.fireRate then return end
    lastFire[player.UserId] = now

    -- server re-cast from authoritative origin
    local origin = player.Character and player.Character:FindFirstChild("Head")
    if not origin then return end
    local dir = (hitPos - origin.Position).Unit * weapon.range
    local ray = Ray.new(origin.Position, dir)
    local hit, _ = workspace:FindPartOnRayWithIgnoreList(ray, { player.Character })
    local humanoid = hit and hit.Parent:FindFirstChildOfClass("Humanoid")
    if humanoid then humanoid:TakeDamage(weapon.damage) end
end)

Building a Roblox FPS

FPS is the genre with the most server-load and the most exploit pressure on Roblox. The two patterns that determine whether it survives launch: server-authoritative hit detection, and rate-limited fire events. Forge AI ships both.

The hit detection pattern is hybrid: client casts the ray for instant visual feedback, server re-casts from the player's Head CFrame to validate damage. The client never gets to write a damage number — only a hint position the server can sanity-check. Standard hit-modifier exploits (set damage to 1000, fire through walls) do not work because the server re-casts from authoritative state.

The ammo system is server-side state. Per-player ammo + mag count lives in AmmoService — exploiters cannot empty-fire (server rejects the fire if mag is 0) or skip reload (server tracks reload duration). Reload is a state machine: idle → reloading (1.5s default) → idle. During reload, fire requests are rejected.

Weapon switching is a Tool-based system. Each weapon is a Tool in StarterPack with attached attributes (damage, mag, fireRate, recoil). Switching is a Roblox-native equip/unequip — no custom switch logic needed. To add a weapon: drop a Tool in StarterPack, add an entry to WeaponConfig.lua with the same name. Forge can also regenerate WeaponConfig with more entries via a follow-up prompt.

Recoil is a per-weapon curve. RecoilController applies vertical kick + horizontal randomness to the camera CFrame on every fire. FOV punch (default 5°, recovers in 0.2s) gives the fire feel without affecting hit detection. ADS multiplies recoil by 0.6 by default — tunable per weapon.

See more on the Luau generator, the game builder, or browse the full blog.

Frequently asked

Is hit detection client-side or server-side?+

Server-authoritative. Client casts the ray for visual feedback (sparks, hit marker), server re-casts from the player's Head CFrame to validate damage. No client-trusted hits.

Can I add more weapons?+

Yes. Add an entry to WeaponConfig.lua with damage, mag, fireRate, recoil — and drop a new Tool in StarterPack. Forge can also regenerate the WeaponConfig with more entries.

How is recoil handled?+

Per-weapon recoil curve in WeaponConfig (vertical kick + horizontal random). RecoilController applies it on the camera CFrame. FOV punch is a tween on FieldOfView.

Does ADS reduce recoil?+

Yes. ADS tweens FOV down (zoom in), narrows the crosshair, and applies a recoil multiplier (default 0.6). Configurable per weapon.

What about netcode for high-ping players?+

Server uses the client's reported hit position as a hint, then re-casts from the player's authoritative CFrame. This compensates for a few hundred ms of lag without trusting the client's damage number.

Related Forge AI prompts