Debugging & Best Practices

Learn techniques for debugging Lua code and writing clean code

Debugging in Lua

Learn effective techniques for finding and fixing bugs in your Lua code, as well as best practices for writing maintainable code.

Print Debugging

The simplest form of debugging is using print() statements to display variable values and track code execution:

print_debug.lua
-- print_debug.lua
local function calculateArea(width, height)
  print("Debug: width = " .. width)
  print("Debug: height = " .. height)
  
  local area = width * height
  print("Debug: calculated area = " .. area)
  
  return area
end

local result = calculateArea(5, 10)
print("The area is: " .. result)

Error Handling with pcall

Use pcall() (protected call) to catch errors without crashing your program:

error_handling.lua
-- error_handling.lua
local function riskyFunction(x)
  if x <= 0 then
    error("Input must be positive")
  end
  return 10 / x
end

local function safeCall(func, ...)
  local success, result = pcall(func, ...)
  
  if success then
    print("Function executed successfully.")
    print("Result: " .. result)
  else
    print("An error occurred:")
    print(result)
  end
end

-- Test with valid input
print("Calling with valid input:")
safeCall(riskyFunction, 2)

-- Test with invalid input
print("\nCalling with invalid input:")
safeCall(riskyFunction, 0)

Code Style Best Practices

Following consistent code style practices makes your code more readable and easier to maintain:

  • Use meaningful variable and function names
  • Add comments to explain complex logic
  • Use consistent indentation (2 or 4 spaces)
  • Break complex functions into smaller, reusable ones
  • Avoid global variables when possible
  • Use local variables for better performance
good_style.lua
-- good_style.lua
-- Module for player statistics management
local PlayerStats = {}

-- Initialize a new player's stats
-- @param playerName The name of the player
-- @return A table containing the player's initial stats
function PlayerStats.createNew(playerName)
  if not playerName then
    error("Player name is required")
  end
  
  -- Create a new stats table with default values
  local stats = {
    name = playerName,
    level = 1,
    experience = 0,
    health = 100,
    maxHealth = 100,
    coins = 0,
    lastUpdated = os.time()
  }
  
  return stats
end

-- Add experience to a player and handle level ups
-- @param stats The player's stats table
-- @param expAmount The amount of experience to add
-- @return The updated stats table
function PlayerStats.addExperience(stats, expAmount)
  -- Validate parameters
  if not stats then
    error("Stats table is required")
  end
  
  if type(expAmount) ~= "number" or expAmount <= 0 then
    error("Experience amount must be a positive number")
  end
  
  -- Update experience
  local oldLevel = stats.level
  stats.experience = stats.experience + expAmount
  
  -- Check for level up
  stats.level = math.floor(1 + stats.experience / 100)
  
  -- If player leveled up, increase max health
  if stats.level > oldLevel then
    local levelsGained = stats.level - oldLevel
    stats.maxHealth = stats.maxHealth + (levelsGained * 10)
    stats.health = stats.maxHealth  -- Fully heal on level up
  end
  
  stats.lastUpdated = os.time()
  return stats
end

return PlayerStats