RLS Studios
ProjectsPatreonCommunityDocsAbout
Join Patreon
BeamNG Modding Docs

Guides

Lua Classes & MetatablesLua Coding StandardsProven GE PatternsAnti-Patterns to AvoidOverriding Lua ModulesCleaning Up AI-Generated CodeError Handling & Defensive CodingPerformance OptimizationLua Modding FAQ

Reference

UI

Resources

BeamNG Game Engine Lua Cheat SheetGE Developer RecipesMCP Server Setup

// RLS.STUDIOS=true

Premium Mods for BeamNG.drive. Career systems, custom vehicles, and immersive gameplay experiences.

Index

HomeProjectsPatreon

Socials

DiscordPatreon (RLS)Patreon (Vehicles)

© 2026 RLS Studios. All rights reserved.

Modding since 2024

GuidesLua

Cleaning Up AI-Generated Code

How to identify and fix common AI coding patterns — excessive guards, restating comments, unnecessary boilerplate, and other slop that hurts readability.

AI coding tools like Cursor, Copilot, ChatGPT, and Claude are powerful for BeamNG modding — but their output needs editing. AI-generated code tends to be verbose, over-defensive, and formulaic. Learning to spot and fix these patterns will make you a better coder regardless of your tools.


What Is AI Slop?

"AI slop" is code that's superficially competent but bloated — it works, but it's harder to read, maintain, and debug than it needs to be.

The data backs this up:

  • GitClear (2025): Across 211M lines of code, copy-pasted blocks rose 8x since AI tools became mainstream. Code churn (revisions within 2 weeks) increased significantly. Refactoring dropped from 25% to under 10% of changes.
  • CodeRabbit (2025): AI-generated code had 1.7x more issues than human-written code across 470 PRs — especially in logic, readability, and security.
  • Google DORA (2024): Teams saw a 7.2% decrease in delivery stability for every 25% increase in AI tool adoption.

The pattern: AI makes you faster at producing code, but that code needs more cleanup. Knowing what to fix is the skill.


The Slop Catalog

Each pattern below shows the AI-generated version and the clean alternative, using BeamNG Lua examples.

1. Comments That Restate the Code

The #1 tell. AI treats code like a tutorial and explains every obvious line.

  • AI slop:
-- Initialize the career data table
local careerData = {}

-- Set the player's money to the starting amount
careerData.money = startingMoney

-- Set the player's experience to zero
careerData.experience = 0

-- Return the career data
return careerData
  • Clean:
local careerData = {
  money = startingMoney,
  experience = 0,
}
return careerData

Rule: If deleting the comment loses zero information, delete it. Comments should explain why, never what.


2. Excessive Nil Checks

AI doesn't understand your call graph. It adds guards for values that can't be nil in context.

  • AI slop:
local function onVehicleSpawned(vehicleId)
  if vehicleId == nil then return end  -- spawn hook ALWAYS provides an ID
  local vehicle = be:getObjectByID(vehicleId)
  if vehicle == nil then return end
  if vehicle.getJBeamFilename == nil then return end  -- method always exists
  local name = vehicle:getJBeamFilename()
  if name == nil then return end  -- always returns a string
  log('I', 'myMod', 'Spawned: ' .. name)
end
  • Clean:
local function onVehicleSpawned(vehicleId)
  local vehicle = be:getObjectByID(vehicleId)
  log('I', 'myMod', 'Spawned: ' .. vehicle:getJBeamFilename())
end

The test: Can you name a real scenario where this value would be nil? If not, don't check.


3. Unnecessary pcall/Error Handling

AI wraps simple internal logic in error handling that adds nothing.

  • AI slop:
local function getRepairCost(vehicle, damage)
  local success, result = pcall(function()
    return damage.severity * vehicle.repairRate
  end)
  if not success then
    log('E', 'repair', 'Error calculating repair cost: ' .. tostring(result))
    return 0
  end
  return result
end
  • Clean:
local function getRepairCost(vehicle, damage)
  return damage.severity * vehicle.repairRate
end

Rule: pcall is for trust boundaries — file I/O, external APIs, deserialization. Not for multiplying two numbers.


4. Verbose Variable Names That Add No Clarity

AI over-describes variables, making lines unnecessarily long without adding meaning.

  • AI slop:
local vehicleRepairCostCalculationResult = calculateRepairCost(vehicle)
local isVehicleRepairAffordableByPlayer = vehicleRepairCostCalculationResult <= playerMoney
if isVehicleRepairAffordableByPlayer then
  processVehicleRepairTransaction(vehicleRepairCostCalculationResult)
end
  • Clean:
local cost = calculateRepairCost(vehicle)
if cost <= playerMoney then
  processRepair(cost)
end

Rule: Variable names should be as long as needed and no longer. Context does most of the work.


5. "Just To Be Safe" Defensive Patterns

AI adds redundant validation, type coercion, and double-checks that serve no purpose.

  • AI slop:
local count = tonumber(tostring(value)) or 0  -- value is already a number
if count ~= nil and type(count) == "number" and count > 0 then
  processBatch(count)
end
  • Clean:
if value > 0 then
  processBatch(value)
end
  • AI slop:
-- Check if career module exists and is loaded before calling
if career_career ~= nil and type(career_career) == "table" and career_career.isActive ~= nil then
  if career_career.isActive() == true then
    doCareerThing()
  end
end
  • Clean:
if career_career.isActive() then
  doCareerThing()
end

6. Boilerplate That Serves No Purpose

AI generates wrapper functions, unnecessary locals for single-use values, and structural overhead that adds nothing.

  • AI slop:
local vehicleName = vehicle.name
local vehicleId = vehicle.id
local vehicleColor = vehicle.color
log('I', 'myMod', vehicleName .. ' (' .. vehicleId .. ') is ' .. vehicleColor)
  • Clean:
log('I', 'myMod', vehicle.name .. ' (' .. vehicle.id .. ') is ' .. vehicle.color)
  • AI slop:
local function getVehicleName(vehicle)
  return vehicle.name
end
  • Clean: Delete the function. Use vehicle.name directly.

7. Type Coercion Lua Doesn't Need

AI brings habits from typed languages — explicit conversions that Lua handles automatically or that are simply unnecessary.

  • AI slop:
local name = tostring(playerName)     -- already a string
local count = tonumber(itemCount)     -- already a number
local enabled = (flag == true)        -- just use flag directly
  • Clean:
local name = playerName
local count = itemCount
local enabled = flag

8. Not Using Lua Idioms

AI often generates verbose patterns instead of idiomatic Lua.

  • AI slop:
local result
if someCondition then
  result = valueA
else
  result = valueB
end
  • Clean:
local result = someCondition and valueA or valueB
  • AI slop:
local config = {}
config.enabled = true
config.name = "delivery"
config.reward = 500
  • Clean:
local config = {
  enabled = true,
  name = "delivery",
  reward = 500,
}

Working With AI Tools Effectively

AI slop isn't inevitable. These practices minimize cleanup:

Spec first, code second

Write a clear specification before prompting. AI performs dramatically better with constraints:

  • What the function does (inputs, outputs, side effects)
  • What patterns to follow (link to your existing code)
  • What NOT to do ("no nil checks on core modules", "no comments that restate code")

Use rules files

Tools like Cursor support .cursorrules or .mdc files. Encode your style:

- Use early returns, not nested ifs
- No comments that restate the code
- Only nil-check values that can actually be nil
- Use Lua idioms: `or` for defaults, `and/or` for ternary
- Follow the M = {} module pattern

Prompt in small chunks

One focused task per prompt. "Add a save/load system to this module" beats "build me a career mod with saving, loading, UI, vehicle tracking, and settings."

Review every diff

No exceptions. Read every line before committing. This is the single most important practice — the moment you stop reading AI output is the moment slop enters your codebase.

Know when to rewrite

Sometimes the AI's approach is fundamentally wrong — not just verbose, but architecturally off. Don't polish bad code. Rewrite it. AI output is a draft, not scripture.


AI Code Review Checklist

Run through this after receiving AI-generated Lua code:

  • Comments: Delete any comment that restates the code
  • Nil checks: Can you name the nil scenario? If not, remove the check
  • pcall: Is this a trust boundary? If not, remove the pcall
  • Variable names: Could they be shorter without losing clarity?
  • Defensive patterns: Are type checks/coercions actually needed?
  • Single-use locals: Is the variable used once? Inline it
  • Wrapper functions: Does this function just call another function? Delete it
  • Table construction: Should be constructor syntax, not line-by-line assignment
  • Lua idioms: Could and/or, or-defaults, or other idioms simplify this?
  • Duplication: Did AI copy-paste similar blocks? Extract shared logic
  • Style match: Does this look like YOUR code or generic AI output?

The Bottom Line

AI tools are accelerators, not replacements. They're excellent at scaffolding, boilerplate, and exploring unfamiliar APIs. They're poor at knowing your codebase's invariants, your project's style, and what's actually worth defending against.

Your job after AI generates code: subtract. Remove unnecessary guards, delete restating comments, inline pointless variables, and make it match your project. The best AI-assisted code is indistinguishable from hand-written code.


See Also

  • Lua Coding Standards — The style to aim for
  • Common Patterns — Battle-tested patterns for BeamNG mods
  • Anti-Patterns — Mistakes to avoid (AI-generated or not)
  • MCP Server Setup — Give your AI tools access to these docs

Overriding Lua Modules

How to safely override and extend existing Lua module functions without breaking other mods.

Error Handling & Defensive Coding

How errors propagate in BeamNG Lua, pcall/xpcall patterns, nil safety, and preventing silent state corruption.

On this page

What Is AI Slop?The Slop Catalog1. Comments That Restate the Code2. Excessive Nil Checks3. Unnecessary pcall/Error Handling4. Verbose Variable Names That Add No Clarity5. "Just To Be Safe" Defensive Patterns6. Boilerplate That Serves No Purpose7. Type Coercion Lua Doesn't Need8. Not Using Lua IdiomsWorking With AI Tools EffectivelySpec first, code secondUse rules filesPrompt in small chunksReview every diffKnow when to rewriteAI Code Review ChecklistThe Bottom LineSee Also