Companion mod
FSConnect
Farming Simulator tells you a little about a running server and nothing about the farm inside it. FSConnect runs on your game server and exports the rest — fields, herds, finances, productions, contracts and live vehicle positions — for Farmalytics to read and report into Discord.
Current release
v1.0.0.7
SHA-256
4b1ab4d245efe6e70a6f40cdcf3ed601e361089c98fb86fb144da0151469fb8e
Install this on your game server, not on your own PC.
FSConnect only does anything on the machine that owns the savegame:
a dedicated server, or whoever is hosting a multiplayer game.
Installing it on a player's computer does no harm, but it does
nothing either.
Installing
- Stop your game server Farming Simulator only reads its mods at startup, so a running server will not pick this up.
- Copy the zip into the mods folder
Upload
FS25_FConnect.zipto the game server'smods/folder over FTP. Leave it zipped — Farming Simulator loads mods as .zip files. - Enable it for your savegame In the web manager, tick FSConnect in the mod list for the savegame you are running.
- Start the server
On first load the mod creates its own folder under
modSettings/and starts writing data files there every few seconds. - Point Farmalytics at it
Run
/setup-serverin Discord. It searches your FTP for the mod's folder, so you normally do not have to type any paths yourself.
Updating. Replace the zip with the new one and restart
the game server. Your settings and recorded history live in
modSettings/ and are left alone. Farmalytics checks the
version on every server it watches and tells you in Discord when an
update is out, so you do not need to keep checking this page.
Release notes
What changed
Version 1.0.0.7
Fixed
- Players trapped in the cab after borrowing contract equipment. Taking a contract with borrowed equipment and climbing into one of the vehicles left the player unable to get out, for the rest of the session. The mod polled every contract the game had, once every 10 seconds, and read each one through the game's own getters — among them
AbstractFieldMission:getCompletion(). That method is not a passive accessor: it drives the incremental field scan that walks a mission field a partition at a time across frames. The mission list includes contracts that are not running — offers still on the board, and ones midway through spawning their borrowed equipment — and none of those have scan state built yet. Driving the scan from outside the mission's own lifecycle left its partitions in a shape itsupdatedid not expect, and the update then indexed a nil table and threw. It threw every cycle from then on, and a mission throwing inupdatetakes the rest of the frame's update chain with it — including whatever would have let the player leave the vehicle. Every contract value now comes from a plain field read. No getter on a mission object is called at all, so nothing the mod does can perturb a mission's state. Where a field is absent the value is reported as unknown, which costs a label in the bot and nothing else. This was invisible in the server log, which is worth recording. Each getter sat inside apcall, so the throw was caught on the mod's side and never logged; the crash surfaced later indataS/scripts/missions/field/with nothing to connect it back here. A clean log was taken as evidence the mod was uninvolved. It was evidence of nothing but the pcall. - **Borrowed equipment images missing from contracts, and a collector that could take the whole contract list down with it.** The vehicle block guarded on
contract.vehiclesbut iteratedcontract.vehiclesToLoad— a different field, and one the game may already have cleared by the time the first is set, so images were as likely to be absent as present. Worse, alone among the getters in that function the store lookup was unguarded, and it throws on a nil filename. A single malformed entry — routine while a contract-altering mod is midway through spawning — therefore aborted the entire collect, so the bot lost every contract on the server rather than one contract's images, every 10 seconds, for as long as the equipment was out.
Changed
locationon a contract now reports the field ID, andtitlefalls back to the mission type name where the contract carries no title of its own. Both previously came from getters that are no longer called. Farmalytics reads whichever it finds.
Version 1.0.0.6
Fixed
- Constant "No access to folder" errors in the server log. Farming Simulator only lets a mod write inside a folder named after the mod itself. FSConnect was writing to a folder whose name differed by a single letter, so the game refused part of every write and logged an error each time. The visible symptom was log noise, but it also meant the mod could never delete its own temporary file: a stray
data.xml.tmpwas left besidedata.xmlafter every save, doubling what the folder held. Both are fixed.
Upgrading from 1.0.0.5 or earlier
- Your data now lands in
modSettings/FS25_FConnect/instead of the oldmodSettings/FS25_FSConnect/. Farmalytics follows the move on its own, so there is nothing to reconfigure and no need to re-run/setup-server. - Recorded history stays behind in the old folder. If you want to keep it, copy
yields.xml,contractStats.xmlandchat.xmlinto the new folder over FTP before starting the server on this version. Skipping this loses your harvest and contract history and nothing else.
Version 1.0.0.3
Added
- Yield tracking. Records harvested volume per game year, field and crop by watching combine and baler fill units, attributing each increase to the field the cutter is standing on. Also records hectares worked and the farm/player responsible, so the bot can show yield per hectare and a harvest leaderboard rather than bare totals. Writes
yields.xml; toggle withfsConnect.modules#yields. Records from installation onwards — earlier harvests cannot be backfilled because the data never existed. - Live Courseplay worker status. Reports which vehicles are running a CP job, their waypoint progress and estimated time remaining. This is the one thing that cannot come from the savegame:
Courseplay.xmlholds only global settings andCpAssignedCourses.xmlthe course list, neither of which says whether a driver is running right now. Entirely optional — every Courseplay call sits behind a type check, so a server without the mod collects nothing rather than erroring. Toggle withfsConnect.modules#courseplay. - Crop state indices on every field:
isWithered,isCut,witheredState,cutState,minHarvestState,maxHarvestState.
Changed
- Withered crops are no longer reported as ready to harvest. The check for "ready" also matched withered and freshly-cut fields, so a dead crop showed as harvestable and the bot advised harvesting it. Each state is now identified correctly.
- Growth percentages no longer read over 100%. Crops past full growth reported figures like 111–125%, which drew progress bars fuller than full. They are now capped at 100%.
- Field crop detection samples a much larger area. The scan box was a fixed 10 m x 10 m patch at the field centre — 0.05% of a 20 ha field — so one unrepresentative point decided the crop and growth stage for the whole field. The box now scales with field size (capped at 40 m half-width to avoid spilling into neighbours), raising coverage on that same field to 3.2%.
data.xmlis ~70% smaller. The fill type reference (base price plus the 12-period seasonal curve for every fill type) was 585 KB of an 830 KB file, rewritten every 10 seconds despite being static for the session. It now lives infilltypes.xml, refreshed every 30 minutes (fsConnect.settings#fillTypeInterval). Measured on a live server: 830,631 → 246,004 bytes. For a bot polling once a minute that is 1,196 MB/day → 354 MB/day per server. Farmalytics reads whichever layout it finds, so old and new servers both work during a staged rollout.
Fixed
- Stray
data.xml.tmpleft on disk. The mod writes to a temporary file and then promotes it, but only cleaned that file up under some conditions — so servers accumulated a permanent duplicate ofdata.xml, the same size as the real one. Cleanup now always runs. (Completed in 1.0.0.6, which fixed the folder permissions that were blocking the delete.) - Contract stats no longer count expiries as completions. A contract that finishes and one that runs out of time both simply vanish from the mission list, and the old "gone means done" rule credited every expiry with its full reward, so lifetime totals drifted upwards indefinitely. Completion is now judged on the contract's own
finishStatewhere the game exposes it, else on whether it had passed 90% completion. Where neither is readable the previous behaviour is kept, so the stat page can never silently stop updating.
Version 1.0.0.2
- Previous release.