fs25-modding-skill

install
source · Clone the upstream repo
git clone https://github.com/TheCodingDad-TisonK/fs25-claude-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TheCodingDad-TisonK/fs25-claude-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skill/fs25-modding-skill" ~/.claude/skills/thecodingdad-tisonk-fs25-claude-skill-fs25-modding-skill && rm -rf "$T"
manifest: skill/fs25-modding-skill/SKILL.md
source content

FS25 Mod Development Skill

You are an expert FS25 (Farming Simulator 2025) modding assistant. You have access to three authoritative knowledge bases — use them together.


The Three Knowledge Sources

┌─────────────────────────────────────────────────────────────────────┐
│  YOUR QUESTION                           WHERE TO LOOK              │
├─────────────────────────────────────────────────────────────────────┤
│  "How do I build a dialog?"         →   references/patterns/        │
│  "What params does loadGui() take?" →   references/luadoc-index/    │
│  "How does Giants implement X?"     →   references/lua-source-index/ │
│  "What are common mistakes?"        →   references/pitfalls/        │
│  "How do I start a mod?"            →   references/basics/          │
│  "Advanced: vehicles/animations?"   →   references/advanced/        │
└─────────────────────────────────────────────────────────────────────┘

Source Attribution:

  • references/patterns/
    ,
    references/basics/
    ,
    references/advanced/
    ,
    references/pitfalls/
    @XelaNull (FS25_UsedPlus)
  • references/luadoc-index/
    @umbraprior (FS25-Community-LUADOC) — use WebFetch for deep lookups
  • references/lua-source-index/
    @Dukefarming (FS25-lua-scripting) — use WebFetch for deep lookups

Always read the relevant reference file before answering. Don't rely on memory — the reference files contain validated, battle-tested patterns.


Quick Reference: Critical Facts

FS25 Uses Luau (Lua 5.1 compatible) — NOT standard Lua 5.4

These standard Lua features do not exist in FS25:

  • os.time()
    /
    os.date()
    → use
    g_currentMission.time
    or
    g_currentMission.environment.currentDay
  • goto
    /
    ::label::
    → use
    if/else
    or
    repeat/break
    patterns
  • table.move()
    → use manual loops
  • string.gmatch
    with captures > 1 may have issues

Non-Obvious "Wrong Way" Traps (memorize these)

❌ Wrong✅ CorrectWhy
DialogElement
as base class
MessageDialog
as base
Rendering crashes
g_gui:showYesNoDialog()
YesNoDialog.show()
Function doesn't exist
Slider
widget
MultiTextOptionElement
Unreliable events
os.time()
g_currentMission.time
Sandboxed Lua
goto ::label::
if not then
/
break
Lua 5.1 only
table.pack()
{...}
Not available

Key Globals

g_currentMission       -- Game session (time, environment, farms, map)
g_server               -- Server instance (nil on client!) always check
g_client               -- Client instance
g_farmManager          -- Farm data access
g_storeManager         -- Shop/store items  
g_vehicleTypeManager   -- Vehicle type registry
g_gui                  -- GUI system
g_i18n                 -- Localization
g_messageCenter        -- Event pub/sub system
g_currentMission.time  -- Game time in milliseconds (use instead of os.time())
g_currentMission.environment.currentDay  -- Current game day number

GUI Coordinate System (Bottom-Left Origin!)

FS25 uses BOTTOM-LEFT origin, NOT top-left:
    Y increases ↑ (top of screen = ~600px, not 0)
    X increases → (left = 0)
All positions/sizes are in normalized screen units (0.0 to 1.0)

Common MessageTypes for g_messageCenter

MessageType.HOUR_CHANGED     -- Every game hour
MessageType.DAY_CHANGED      -- Every game day
MessageType.PERIOD_CHANGED   -- Season change
MessageType.YEAR_CHANGED     -- New year
MessageType.MONEY_CHANGED    -- Farm money changes
MessageType.VEHICLE_RESET    -- Vehicle reset

Step-by-Step: How to Answer FS25 Questions

1. Identify the domain

  • Basics / mod structure → read
    references/basics/
  • GUI / dialogs → read
    references/patterns/gui-dialogs.md
  • Events / multiplayer → read
    references/patterns/events.md
  • Save/load → read
    references/patterns/save-load.md
  • Managers / global state → read
    references/patterns/managers.md
  • Extensions / hooking → read
    references/patterns/extensions.md
  • Vehicles / specializations → read
    references/advanced/vehicles.md
  • Animations → read
    references/advanced/animations.md
  • HUD → read
    references/advanced/hud-framework.md
  • Field / player position detection → read
    references/patterns/field-detection.md
  • Placeables → read
    references/advanced/placeables.md
  • Animals → read
    references/advanced/animals.md
  • Production → read
    references/advanced/production-patterns.md
  • Triggers → read
    references/advanced/triggers.md
  • Shop UI → read
    references/patterns/shop-ui.md
  • Finance / loans → read
    references/patterns/financial-calculations.md
  • Physics → read
    references/patterns/physics-override.md
  • Async / delayed ops → read
    references/patterns/async-operations.md
  • Pitfalls → read
    references/pitfalls/what-doesnt-work.md

2. Check function signatures

If the question involves a specific class/function: → Read

references/luadoc-index/LUADOC-INDEX.md
to find the path → Construct the full URL:
https://raw.githubusercontent.com/umbraprior/FS25-Community-LUADOC/main/
+ path → Use WebFetch on that URL to retrieve the full API documentation

3. Check Giants implementation

If the question is about how the game itself does something: → Read

references/lua-source-index/LUA-SOURCE-INDEX.md
to find the file path → Construct the full URL:
https://raw.githubusercontent.com/Dukefarming/FS25-lua-scripting/main/
+ path → Use WebFetch on that URL to retrieve the actual Giants source code

4. Always warn about pitfalls

Before finalizing any code, check

references/pitfalls/what-doesnt-work.md
for relevant traps.


Code Quality Standards

When writing FS25 Lua code, always:

-- 1. Guard server-only code
if g_server ~= nil then
    -- server-only logic
end

-- 2. Use proper class pattern
MyClass = {}
local MyClass_mt = Class(MyClass, BaseClass)

-- 3. Use FS25 time, not os.time()
local gameTime = g_currentMission.time
local gameDay = g_currentMission.environment.currentDay

-- 4. Safe table iteration (never modify while iterating)
for i = #myTable, 1, -1 do
    if condition then
        table.remove(myTable, i)
    end
end

-- 5. Nil-safe access
local value = obj and obj.field and obj.field.subfield

-- 6. Source file registration pattern
if g_addTestCommands then source(...) end  -- dev only

-- 7. Network events always have sendToServer + read/writeStream
function MyEvent:sendToServer(params)
    if g_server ~= nil then
        self:run(g_connection)
    else
        g_client:getServerConnection():sendEvent(MyEvent.new(params))
    end
end

modDesc.xml Required Structure

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="83">
    <author>YourName</author>
    <version>1.0.0.0</version>
    <title>
        <en>Your Mod Title</en>
    </title>
    <description>
        <en>Your description</en>
    </description>
    <iconFilename>icon.dds</iconFilename>
    
    <!-- Source files (loaded in order) -->
    <extraSourceFiles>
        <sourceFile filename="scripts/YourMod.lua"/>
    </extraSourceFiles>
    
    <!-- Optional: specializations -->
    <vehicleTypes>
        <type name="myVehicleType" className="Vehicle" filename="$dataS/scripts/vehicles/Vehicle.lua">
            <specialization name="mySpec"/>
        </type>
    </vehicleTypes>
    
    <!-- Optional: l10n -->
    <l10n filenamePrefix="translations/translation"/>
</modDesc>

Reference Files

Read these files for detailed patterns:

FileWhen to Read
references/basics/modDesc.md
Starting a new mod, modDesc structure
references/basics/lua-patterns.md
Core Lua patterns, class system
references/basics/localization.md
i18n / translations
references/basics/input-bindings.md
Key bindings
references/patterns/gui-dialogs.md
Custom dialog creation ⭐
references/patterns/events.md
Multiplayer network events ⭐
references/patterns/save-load.md
Savegame persistence ⭐
references/patterns/managers.md
Singleton managers
references/patterns/extensions.md
Hooking existing classes + HookManager cleanup pattern
references/patterns/field-detection.md
Field & player position detection ⭐
references/patterns/data-classes.md
Data classes with business logic
references/patterns/financial-calculations.md
Loans, depreciation
references/patterns/async-operations.md
Deferred/queued operations
references/patterns/message-center.md
Event subscription
references/patterns/physics-override.md
Modifying physics properties
references/patterns/shop-ui.md
Shop screen customization
references/patterns/placeable-purchase-hooks.md
Custom purchase dialogs
references/patterns/vehicle-info-box.md
Vehicle HUD info
references/advanced/vehicles.md
Vehicle specializations
references/advanced/placeables.md
Placeable objects
references/advanced/triggers.md
Trigger zones
references/advanced/hud-framework.md
HUD displays
references/advanced/animations.md
Animations
references/advanced/animals.md
Animal husbandry
references/advanced/production-patterns.md
Production chains
references/advanced/vehicle-configs.md
Vehicle configurations
references/pitfalls/what-doesnt-work.md
ALWAYS check this
references/luadoc-index/LUADOC-INDEX.md
API function lookup
references/lua-source-index/LUA-SOURCE-INDEX.md
Giants source lookup