docs: design for behovsstyret forsyning (feed the factory)

This commit is contained in:
2026-09-21 12:47:12 +02:00
parent 63afbba1f8
commit 7e42b93b4f
@@ -0,0 +1,73 @@
# Behovsstyret forsyning ("Feed the factory") — design
Dato: 2026-09-21 · Status: godkendt af bruger
## Problem
En produktion med flere input (fx TMR-blander: hø, græs, ensilage, sukkerroer) kræver i dag
én AutoDrive-traktor pr. vare, fordi AD's Pickup&Deliver kun kører én vare fra ét sted.
Varerne ligger spredt over mange lokationer på kortet.
## Løsning
Én traktor holder alle input fyldt. For hver tur vælger moden den ingrediens aflæsningsmålet
har mest brug for, finder en silo der har den, skifter AD's vare og sender traktoren derhen.
### Betjening (ingen ny GUI, ingen config-fil)
1. Aflæsningsmål = produktionens markør.
2. Multi-vælg ingredienserne i AD's vare-dropdown (>1 vare = funktionen er aktiv).
3. "Brug mapper" + "Rotér mål: pålæsning" slået til (krævet for at AD kalder `getNextPickup`).
4. Start Pickup&Deliver. AD's loop-tæller virker uændret (N læs → parkér, 0 = uendeligt).
Med præcis én valgt vare er opførslen uændret (eksisterende mappe-rotation, mindst fyldte først).
### Logik pr. tur (i `getNextPickup`-wrapperen)
1. **Ingrediensliste pr. køretøj.** Ved >1 valgt vare gemmes listen i modens egen tilstand
(`vehicle → {ingredients, narrowedTo}`). Derefter indsnævres AD's `selectedFillTypes` til den
valgte vare, fordi AD ellers selv roterer vare ved triggeren
(`ADStateModule:selectPreferredFillTypeFromFillLevels`).
Ved næste kald: er AD's valg stadig `{narrowedTo}` → brug den gemte liste. Er det noget andet →
brugeren har ændret valget: ny multi-liste erstatter, enkelt-valg sletter tilstanden.
2. **Behov.** Find `UnloadingStation` nærmest anden markør (≤ 40 m). For hver ingrediens summeres
`level`, `capacity` over `station.targetStorages`; `free = capacity - level`.
Ingredienser stationen ikke understøtter, eller med `free < MIN_FREE_LITERS`, springes over.
3. **Rangering.** `ADSupplyPlanner.scoreNeed(level, capacity, freeSpace)` → højeste score først.
4. **Kilde.** For ingredienserne i behovs-rækkefølge: blandt *alle* AD-markører (ikke kun én mappe)
findes markører med farm-tilgængelig `LoadingStation` ≤ 40 m der har varen. Aflæsningsmålets
egen placeable udelukkes som kilde. Rangering som eksisterende: eget lager før nabo-lån,
mindst fyldte først. Første ingrediens med en kilde vinder.
5. **Effekt.** `setFillType(vare)`, `selectedFillTypes = {vare}`, dirty-flag, returnér markørens
`markerIndex`. Logges som `ADSmartPickup: '<traktor>' -> <markør> (<vare>, behov …)`.
6. **Fallback.** Intet behov / ingen kilde / ingen station / fejl (`pcall`) → AutoDrives
originale `getNextPickup` (ved fejl: `Logging.warning`). Aldrig crash.
## Filer
| Fil | Ansvar |
|---|---|
| `FS25_ADSmartPickup/adSupplyPlanner.lua` (ny) | Rene funktioner: `scoreNeed`, `rankNeeds`, `resolveIngredients` (tilstandslogik). Ingen spil-API. |
| `FS25_ADSmartPickup/adSmartPickup.lua` | Spil-/AD-adaptere (station ved markør, lagerniveauer, kilde-søgning) + hook. Kilde-søgning generaliseres til at tage en markørliste. |
| `FS25_ADSmartPickup/modDesc.xml` | Ny sourceFile før `adSmartPickup.lua`, version 1.1.0.0, beskrivelse. |
| `tests/test_adSupplyPlanner.lua` (ny) | Enhedstests af de rene funktioner. |
| `tests/test_adSmartPickup.lua` | Integration gennem hook'en med mocks; eksisterende 11 tests skal forblive grønne. |
## Tests (luajit, mocks)
- mest trængende ingrediens vælges; vare og AD-valg skiftes; rigtig markør returneres
- ingrediens uden plads i målet springes over
- ingrediens uden kilde springes over → næste i rækken
- kilde i anden mappe end første markør findes
- aflæsningsmålets egen station bruges ikke som kilde
- gemt liste genbruges når AD's valg er indsnævret; brugerændring nulstiller/erstatter
- én vare valgt → eksisterende opførsel uændret
- intet behov / ingen aflæsningsstation / API-fejl → `ORIGINAL` (+ WARN ved fejl)
## Kendte begrænsninger
- AD læsser fuld vogn; er der mindre plads end ét læs, venter traktoren ved aflæsning (AD-standard).
- Ingredienslisten lever kun i hukommelsen — efter savegame-reload multi-vælges varerne igen.
- Forudsætter at målet er en placeable med aflæsningstrigger (produktionspunkt/silo/stald),
ikke en blandevogn. Bekræftes ved første in-game test via log.txt.
- Server-side logik; MP-klienter ser vareskiftet via AD's eget dirty-flag.