From 7e42b93b4fc2a130ce0acf1ee95f75da76eca64a Mon Sep 17 00:00:00 2001 From: masterdraco Date: Mon, 21 Sep 2026 12:47:12 +0200 Subject: [PATCH] docs: design for behovsstyret forsyning (feed the factory) --- ...026-09-21-behovsstyret-forsyning-design.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-21-behovsstyret-forsyning-design.md diff --git a/docs/superpowers/specs/2026-09-21-behovsstyret-forsyning-design.md b/docs/superpowers/specs/2026-09-21-behovsstyret-forsyning-design.md new file mode 100644 index 0000000..d1e24e9 --- /dev/null +++ b/docs/superpowers/specs/2026-09-21-behovsstyret-forsyning-design.md @@ -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: '' -> (, 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.