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.mdsource 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/
— @XelaNull (FS25_UsedPlus)references/pitfalls/
— @umbraprior (FS25-Community-LUADOC) — use WebFetch for deep lookupsreferences/luadoc-index/
— @Dukefarming (FS25-lua-scripting) — use WebFetch for deep lookupsreferences/lua-source-index/
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()
→ useos.date()
org_currentMission.timeg_currentMission.environment.currentDay
/goto
→ use::label::
orif/else
patternsrepeat/break
→ use manual loopstable.move()
with captures > 1 may have issuesstring.gmatch
Non-Obvious "Wrong Way" Traps (memorize these)
| ❌ Wrong | ✅ Correct | Why |
|---|---|---|
as base class | as base | Rendering crashes |
| | Function doesn't exist |
widget | | Unreliable events |
| | Sandboxed Lua |
| / | Lua 5.1 only |
| | 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:
| File | When to Read |
|---|---|
| Starting a new mod, modDesc structure |
| Core Lua patterns, class system |
| i18n / translations |
| Key bindings |
| Custom dialog creation ⭐ |
| Multiplayer network events ⭐ |
| Savegame persistence ⭐ |
| Singleton managers |
| Hooking existing classes + HookManager cleanup pattern |
| Field & player position detection ⭐ |
| Data classes with business logic |
| Loans, depreciation |
| Deferred/queued operations |
| Event subscription |
| Modifying physics properties |
| Shop screen customization |
| Custom purchase dialogs |
| Vehicle HUD info |
| Vehicle specializations |
| Placeable objects |
| Trigger zones |
| HUD displays |
| Animations |
| Animal husbandry |
| Production chains |
| Vehicle configurations |
| ALWAYS check this ⭐ |
| API function lookup |
| Giants source lookup |