diff --git a/HelperPayroll_icon.dds b/HelperPayroll_icon.dds new file mode 100644 index 0000000..37074e8 Binary files /dev/null and b/HelperPayroll_icon.dds differ diff --git a/README.md b/README.md index 9ddb8b8..da117e1 100644 --- a/README.md +++ b/README.md @@ -1,167 +1,492 @@ -# FS25_HelperPayroll +# FS25 HelperPayroll -**Helper Payroll** is an early alpha Farming Simulator 25 mod that replaces the vanilla AI helper wage drain with a configurable payroll model. +**FS25 HelperPayroll** replaces Farming Simulator 25's continuous AI-worker wage deductions with a configurable payroll system. -Instead of letting the game charge its built-in AI helper rate continuously, Helper Payroll suppresses the vanilla helper price and applies its own helper wage calculation using hourly rates, minimum charges, optional call-out fees, helper-slot mappings, and optional daily payroll. +Instead of paying every helper at one fixed game-controlled rate, farms can define payroll roles, set their own hourly rates, choose when charges are settled, assign roles to individual A–J helper slots, and review a persistent payroll ledger. -## Alpha status +The mod works independently in its default `roleType` mode. Optional integration with [FS25 HelperProfiles](https://github.com/SimGamerJen/FS25_HelperProfiles) adds live worker identities and save-specific role mappings. -This is an **alpha/test build**. It has been tested against native AI fieldwork jobs, including mowing with the standard AI worker system. It is not yet a polished ModHub-ready release. +> **Current release:** `0.3.3.1` beta release candidate +> **Game:** Farming Simulator 25 +> **Multiplayer:** Not currently supported -Current build: **0.1.3.3-alpha** -FS25 modDesc: **110** +--- -## What it does now +## Main Features -- Suppresses the vanilla AI helper wage calculation for supported AI jobs. -- Detects active AI fieldwork jobs. -- Tracks helper job duration. -- Applies configurable hourly helper wages. -- Supports a minimum charge per job or per daily payroll row, depending on billing mode. -- Supports optional call-out fees. -- Supports two billing modes: - - `onJobFinish` - - `dailyPayroll` -- Maintains session and daily ledger summaries in the log. -- Provides helper-slot mapping structure for future HelperProfiles integration. -- Includes UK Tenant Farm and US Ranch example rate profiles. +- Suppresses the game's normal AI-worker wage deductions. +- Calculates custom labour charges from configurable payroll roles. +- Includes Owner, Trainee, Standard, Skilled and Contractor defaults. +- Supports immediate job-finish billing or scheduled daily payroll. +- Supports a global minimum charge and call-out fee. +- Provides a game-styled payroll-management screen. +- Supports role-based and A–J helper-slot payroll modes. +- Stores settings and worker mappings separately for each savegame. +- Records persistent payroll history by month, role, helper and job. +- Provides an in-game role list, report overlay and console tools. +- Optionally consumes live worker identities from an API-enabled HelperProfiles build. +- Captures the worker assignment when a job starts, preventing later role changes from altering a job already in progress. +- Uses the authoritative game clock for accelerated-time-safe daily payroll. -## What it does not do yet +--- -- It does not yet automatically detect named helpers from FS25_HelperProfiles. -- It does not yet provide an in-game payroll UI. -- It does not yet persist/export the payroll ledger to a savegame XML file. -- It does not change contract rewards. -- It does not include a contract rate-card system. -- It has primarily been tested with `AIJobFieldWork`; other AI job categories may need further testing. +## How Payroll Works + +### Payroll modes + +HelperPayroll provides two worker-assignment modes. + +#### `roleType` + +This is the default, standalone-friendly mode. + +Every new AI job uses the currently selected payroll role. For example, selecting **Skilled Operator** causes subsequently started jobs to use that role and its configured hourly rate. + +The assignment is captured when the job starts. Changing the selected role afterwards does not retroactively change an active job. + +#### `helperSlot` + +This mode assigns payroll roles to the detected vanilla helper slots A–J. + +It can operate with slot fallbacks from the payroll policy, but is intended for advanced use with HelperProfiles. When a compatible HelperProfiles API is available, HelperPayroll can use live worker names and stable identities while retaining save-specific payroll mappings. + +### Billing modes + +#### `onJobFinish` + +The calculated charge is deducted when an AI job finishes. + +For each completed job: + +```text +labour = elapsed hours × hourly rate +subtotal = labour + call-out fee +charge = maximum(subtotal, minimum charge) +``` + +The minimum is only applied when the calculated subtotal is greater than zero. + +#### `dailyPayroll` + +Completed jobs are aggregated by worker and game day. At the configured payroll hour, HelperPayroll makes one payment for each worker with recorded work that day. + +For each worker/day: + +```text +subtotal = combined labour + one call-out fee +charge = maximum(subtotal, minimum charge) +``` + +Unpaid rows from an earlier game day are treated as overdue and settle automatically. + +> `dailyPayroll` is a scheduled settlement mode, not a fixed daily salary. The current minimum charge is global and only applies to workers with recorded chargeable work. + +### Current limitation + +Version 0.3.3.1 uses hourly role rates. The minimum charge and call-out fee are global for the save, rather than configurable per role or per worker. + +Per-role and per-worker hourly/daily pay policies are planned for a later development phase. + +--- + +## Management Screen + +Open the payroll-management screen with: + +```text +RCTRL + H +``` + +The screen contains six tabs: + +| Tab | Purpose | +|---|---| +| **Overview** | Displays the active profile, modes, selected role, policy values, integration status and save path. | +| **Billing** | Configures payroll mode, billing mode, payroll hour, minimum charge, call-out fee and rounding. | +| **Roles** | Displays the active role list and allows existing hourly rates to be adjusted. | +| **Workers** | Assigns payroll roles to A–J helper slots or HelperProfiles identities. | +| **Ledger** | Displays persistent payroll totals. | +| **Help** | Explains the management workflow and current modes. | + +Changes are staged until **Apply** is selected. **Discard** restores the currently loaded values. + +### Reload and reset + +- **Reload Save** reloads the global policy and then reapplies the current save-specific settings. Its default button-bar shortcut is `X`. +- **Reset Save** has no competing `X` shortcut. It requires a second **Confirm Reset** action before replacing the current save's payroll policy, role list and mappings with the global defaults. + +Resetting a save is destructive for that save's custom payroll configuration. It does not overwrite the global `defaultPayrollConfig.xml` file. + +--- + +## Default Keybinds + +Keybinds can be changed in the Farming Simulator controls menu. + +| Action | Default binding | Description | +|---|---:|---| +| Cycle payroll role | `;` | Selects the next role in `roleType` mode. | +| Toggle payroll role list | `RCTRL + ;` | Shows or hides the standalone role list. | +| Toggle payroll report | `RCTRL + P` | Opens or closes the payroll report overlay. | +| Open management screen | `RCTRL + H` | Opens the full payroll-management UI. | + +When HelperProfiles is enabled, it owns the semicolon key family. HelperPayroll therefore suppresses its standalone role-cycle and role-list inputs for that session to prevent conflicts. The management and report shortcuts remain available. + +--- ## Installation -1. Download `FS25_HelperPayroll_v0_1_3_3_alpha.zip`. -2. Place the ZIP in your Farming Simulator 25 mods folder. -3. Enable **Helper Payroll Alpha** in the save's mod selection screen. -4. Start a save and hire an AI worker. -5. Check `log.txt` for `[HelperPayroll]` entries. +1. Download `FS25_HelperPayroll.zip` from the GitHub release. +2. Place the ZIP directly in your Farming Simulator 25 mods folder: + +```text +Documents/My Games/FarmingSimulator2025/mods +``` + +3. Do not unpack the ZIP. +4. Launch Farming Simulator 25. +5. Enable **Helper Payroll Beta** for the intended savegame. + +HelperProfiles is optional. HelperPayroll remains usable in standalone `roleType` mode when HelperProfiles is absent or does not expose the required shared API. + +Because this is a beta release candidate, test it on a copied save before relying on it in an important playthrough. + +--- -## Configuration +## Configuration and Save Data -Configuration is stored in: +### Global policy template + +On first use, HelperPayroll creates an editable global policy file at: ```text -config/defaultPayrollConfig.xml +Documents/My Games/FarmingSimulator2025/modSettings/FS25_HelperPayroll/defaultPayrollConfig.xml ``` -Key settings: +This file supplies the defaults for new saves and for the **Reset Save** action. -```xml -uk_tenant -skilled - -true -onJobFinish -18 -5.00 -0.00 -true -debug +The bundled configuration inside the mod ZIP remains a fallback and template. Do not edit the copy inside the ZIP for normal configuration. + +### Save-specific settings + +Each save stores its active payroll policy, role list, worker mappings, pending daily payroll and overlay settings at: + +```text +Documents/My Games/FarmingSimulator2025/modSettings/FS25_HelperPayroll/savegameX/helperPayrollSettings.xml ``` -### Billing modes +Replace `savegameX` with the relevant save slot, such as `savegame17`. -#### `onJobFinish` +Save-specific values take priority over the global defaults. Editing `defaultPayrollConfig.xml` does not automatically replace an existing save's active settings. + +Use one of the following after editing XML while the game is running: + +- Select **Reload Save** in the management screen. +- Run `hpaySave reload` in the console. -The helper is charged when the AI job ends. +Use **Reset Save** only when you deliberately want the current save to inherit the global policy again. -Example: +### Persistent ledger + +Payroll history is stored under: ```text -Helper works 0.205 hours at £18/hour = £3.68 -Minimum charge = £5.00 -Applied charge = £5.00 +Documents/My Games/FarmingSimulator2025/modSettings/FS25_HelperPayroll/savegameX/ledger ``` -#### `dailyPayroll` +The folder contains an index and period files such as: + +```text +index.xml +Y001_M06.xml +``` + +Exported text reports are written to the save-specific HelperPayroll folder. + +--- + +## Default Roles + +The default public payroll profile includes: + +| Role ID | Display name | Hourly rate | +|---|---|---:| +| `owner` | Owner Labour | 0.00 | +| `trainee` | Trainee Helper | 10.00 | +| `standard` | Standard Helper | 18.00 | +| `skilled` | Skilled Operator | 22.00 | +| `contractor` | Contractor | 30.00 | + +The policy template also contains example UK tenant-farm and US ranch profiles. + +All numeric rates use the active save's currency context. -The helper's work is added to the daily ledger. Payroll is applied once at or after the configured `payrollHour`. +--- -Example: +## Adding a Custom Role + +The current management UI can edit existing role rates but does not yet provide Add, Rename or Delete Role controls. + +Custom roles can be added to the save-specific `helperPayrollSettings.xml` file. Add another worker entry within ``: ```xml -dailyPayroll -18 + + + +``` + +The actual file will usually contain the existing roles as well. Keep those entries unless you deliberately want to remove them from that save. + +After saving the XML, select **Reload Save** or run: + +```text +hpaySave reload ``` -The helper works during the day, the job is deferred to payroll, and the farm is charged at 18:00 game time. +Version 0.3.3.1 treats the save-specific role section as authoritative for each profile it contains. Custom IDs, names and rates are loaded into the UI and preserved when **Apply** writes the save again. Familiar policy roles retain their policy order; save-only roles are appended in their XML order. + +If the selected or fallback role no longer exists, HelperPayroll selects a valid role from the loaded list. -## Helper slots +--- -The alpha contains helper-slot mapping data, but it does not yet automatically connect to FS25_HelperProfiles. +## Default Policy Example -Example UK profile: +The following is a shortened example of the global policy structure: ```xml - - - - - - + + + true + true + default + roleType + standard + standard + true + onJobFinish + 18 + 5.00 + 0.00 + true + + + + + + + + + + + + + + +``` + +--- + +## HelperProfiles Integration + +HelperProfiles is optional and is not a hard dependency. + +With a compatible API-enabled HelperProfiles build, HelperPayroll can: + +- Read live A–J helper identities and display names. +- Retain mappings by stable identity where available. +- Show selected and in-use worker information in the management UI. +- Assign different payroll roles to individual workers. +- Include worker identity data in payroll reports and ledger entries. + +In `helperSlot` mode, the detected `job.helperIndex` identifies the A–J slot. HelperProfiles supplies the live identity, and HelperPayroll applies the save-specific identity or slot mapping. + +If HelperProfiles is loaded without the required shared API, HelperPayroll logs the condition and remains available in standalone `roleType` mode. + +Check the current integration state with: + +```text +hpayProfiles status +hpayProfiles slots +``` + +--- + +## Console Commands + +Run each main command with `help` to display its available subcommands. + +### Role selection + +| Command | Description | +|---|---| +| `hpayRole status` | Displays the active profile, selected role and rate. | +| `hpayRole list` | Lists the available roles. | +| `hpayRole next` | Selects the next role. | +| `hpayRole prev` | Selects the previous role. | +| `hpayRole set ` | Selects a role immediately. | + +### Overlay + +| Command | Description | +|---|---| +| `hpayOverlay on\|off\|toggle` | Controls the role-list overlay. | +| `hpayOverlay status` | Displays overlay and selected-role status. | +| `hpayOverlay pos ` | Sets normalized screen position. | +| `hpayOverlay anchor TL\|TR\|BL\|BR` | Sets the anchor corner. | +| `hpayOverlay scale <0.5..2.0>` | Sets overlay scale. | +| `hpayOverlay width <0.15..0.90>` | Sets overlay width. | +| `hpayOverlay opacity <0..1>` | Sets background opacity. | +| `hpayOverlay font <0.010..0.030>` | Sets font size. | +| `hpayOverlay rowgap <0.001..0.03>` | Sets row spacing. | +| `hpayOverlay maxrows <3..30>` | Sets the maximum visible rows. | +| `hpayOverlay pad <0..0.05>` | Sets padding. | +| `hpayOverlay bg\|outline\|shadow on\|off` | Controls visual elements. | +| `hpayOverlay debounce ` | Sets role-selector debounce time. | +| `hpayOverlay reset` | Restores the overlay defaults. | + +### Reports and ledger + +| Command | Description | +|---|---| +| `hpayReport summary` | Prints the persistent ledger summary. | +| `hpayReport session` | Prints the current in-memory session report. | +| `hpayReport jobs [limit] [period]` | Prints recent persisted entries. | +| `hpayReport month ` | Prints a specific monthly ledger. | +| `hpayReport roles` | Prints persistent totals by role/helper rate. | +| `hpayReport daily` | Prints pending in-memory daily payroll rows. | +| `hpayReport export [name]` | Exports the persistent ledger summary. | +| `hpayReport exportSession [name]` | Exports the current session report. | + +### Configuration and diagnostics + +| Command | Description | +|---|---| +| `hpayConfig status` | Shows the global policy source and template values. | +| `hpayConfig path` | Prints the global policy path. | +| `hpayConfig reload` | Reloads the global policy and current save overrides. | +| `hpayConfig reset` | Regenerates the global policy from bundled defaults. | +| `hpaySave status` | Shows the current save's effective settings. | +| `hpaySave path` | Prints the current save settings path. | +| `hpaySave reload` | Reloads the global policy and current save settings. | +| `hpaySave reset` | Immediately resets the current save from the global policy. | +| `hpayProfiles status` | Shows HelperProfiles/API integration status. | +| `hpayProfiles slots` | Lists A–J identities and payroll mappings. | +| `hpayDump status` | Prints the full runtime status. | +| `hpayDump clock` | Shows the payroll clock and pending-row due state. | +| `hpayDump roles\|ledger\|report\|config` | Prints the selected diagnostic view. | + +> Unlike the management-screen reset, the console command `hpaySave reset` does not present a confirmation screen. + +--- + +## Troubleshooting + +### Vanilla AI wages are still appearing + +Check that HelperPayroll is enabled for the save and inspect: + +```text +hpayDump status +hpayConfig status +hpaySave status ``` -For manual testing, set: +Confirm that the policy contains: ```xml -B +true +true +true +``` + +### A custom role does not appear + +- Confirm that it was added to the active save's `helperPayrollSettings.xml`, not only another save slot. +- Confirm that its `profile` matches the active payroll profile. +- Give the role a unique, non-empty ID. +- Use **Reload Save** or `hpaySave reload` after editing. +- Check `log.txt` for duplicate-role or XML warnings. + +### Daily payroll did not settle at the expected time + +Run: + +```text +hpayDump clock +hpayReport daily ``` -This will make jobs resolve to slot B, Rhys, using the configured skilled operator rate. +Pending rows from an earlier game day should settle automatically, even when the configured hour was skipped through accelerated time. + +### HelperProfiles names are unavailable + +Run: + +```text +hpayProfiles status +``` + +If HelperProfiles is detected but the API is unavailable, update to an API-enabled HelperProfiles build. HelperPayroll will continue to work in standalone `roleType` mode. + +### The semicolon controls do not work + +When HelperProfiles is enabled, it intentionally owns the semicolon controls. Use the management screen or `hpayRole` console commands for payroll changes. + +Also check the Farming Simulator controls menu for local keybind overrides or conflicts. + +### Requesting support + +Include: + +- HelperPayroll version. +- Relevant `log.txt` excerpt. +- Savegame number. +- Active payroll and billing modes. +- Whether HelperProfiles is enabled. +- Clear steps to reproduce the issue. + +--- + +## Version 0.3.3.1 + +This maintenance build fixes two management-screen and persistence issues found in 0.3.3.0: -## Financial impact +- **Reload Save** and **Reset Save** no longer share the same `X` action. +- Reset now requires a second confirmation action in the management screen. +- Save-specific roles no longer need to exist in the global policy before they can be loaded. +- Custom role IDs, display names and rates are preserved when the UI writes the save. +- Save-only roles retain their relative XML order after the known policy roles. +- Invalid selected or fallback roles are safely reassigned after a role-list change. -Helper Payroll does affect the save's money balance. +The finished ZIP was also checked for valid Lua syntax, valid XML and correct top-level FS25 packaging. -It suppresses the vanilla AI helper cost and then applies its own charge using the game's money system with `MoneyType.AI`. Any money charged by the mod remains part of the save's financial history. Removing the mod later will not refund previous payroll charges. +--- -The mod does not add required vehicles, placeables, fillTypes, animals, or map objects. +## Planned Development -## Tested behaviour +The current roadmap includes: -Confirmed in testing: +- Per-role and per-worker minimum call-out settings. +- A per-role or per-worker choice between hourly and daily pay. +- Worker-specific overrides that can inherit from role defaults. +- Separate worked-day and rostered-day daily-pay policies. +- Add, rename and delete role controls in the management UI. +- Continued improvement of payroll reporting and HelperProfiles integration. -- Native AI fieldwork/mowing detected as `AIJobFieldWork`. -- Vanilla helper price detected as `0.0005` per millisecond. -- The mod returns `0` to suppress the vanilla helper charge. -- `onJobFinish` billing applies correctly. -- `dailyPayroll` defers correctly and applies payroll at the configured hour. -- Minimum charge applies correctly. -- Session and daily ledger logs update correctly. +These items are planned directions and are not yet included in version 0.3.3.1. -## Recommended alpha testing checklist +--- -- Start a single-player test save. -- Enable Helper Payroll Alpha. -- Hire an AI worker for fieldwork. -- Confirm vanilla helper wages do not drain continuously. -- Confirm `[HelperPayroll] AI helper pricing suppressed` appears in the log. -- Test `onJobFinish` mode. -- Test `dailyPayroll` mode by advancing game time to the payroll hour. -- Test a manual `defaultHelperSlot` value, such as `B`. +## Permissions -## Compatibility notes +Copyright © SimGamerJen. All rights reserved. -- Designed to coexist with FS25_HelperProfiles, but automatic integration is not implemented yet. -- Multiplayer is declared as supported, but the alpha should be treated as unverified for serious multiplayer saves until dedicated testing is completed. -- Other mods that override AI job pricing may conflict. +**Editing, redistributing, or publishing modified versions of this mod is prohibited without prior written permission from the mod author.** -## Roadmap +The presence of source files in this repository does not grant permission to republish, repackage, redistribute or release modified versions of the mod. -Planned next steps: +--- -1. HelperProfiles bridge diagnostics. -2. Automatic helper-slot detection. -3. Named helper payroll. -4. Persistent savegame payroll ledger. -5. Optional in-game payroll summary UI. -6. Wider AI job type testing. +## Disclaimer -Contract reward realism is now intended to become a separate future mod, likely `FS25_ContractRateCard`. +FS25 HelperPayroll is an unofficial Farming Simulator 25 mod and is not affiliated with or endorsed by GIANTS Software. diff --git a/config/defaultPayrollConfig.xml b/config/defaultPayrollConfig.xml new file mode 100644 index 0000000..7c6e976 --- /dev/null +++ b/config/defaultPayrollConfig.xml @@ -0,0 +1,95 @@ + + + + true + true + true + + + default + + + roleType + standard + standard + + + + + true + onJobFinish + 18 + 5.00 + 0.00 + true + 450 + normal + false + false + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/HelperPayrollMenu.xml b/gui/HelperPayrollMenu.xml new file mode 100644 index 0000000..bcadea2 --- /dev/null +++ b/gui/HelperPayrollMenu.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +