docs(spec): marksilo-flow — låner op til x ledige vogne og kører marksiloernes varer hjem til nærmeste gårdlager
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# Marksilo-flow — design
|
||||
|
||||
Dato: 2026-09-27 · Status: godkendt i chat, afventer review af denne spec
|
||||
|
||||
## Formål
|
||||
|
||||
Høsten lægges ofte i siloer ude ved markerne (mellemlager). I dag skal spilleren selv huske at køre varerne
|
||||
hjem. Marksilo-flowet kigger jævnligt alle marksiloer igennem og sender selv op til **x** ledige vogne ud for at
|
||||
hente varerne hjem til gårdens lagre.
|
||||
|
||||
**Succes:** står der varer i en marksilo, som gården kan tage, bliver de kørt hjem uden at spilleren gør noget,
|
||||
med højst x vogne ude ad gangen, og uden at tage vogne fra markarbejde, andre flows eller spilleren.
|
||||
|
||||
## Brugerens valg (fra brainstorm)
|
||||
|
||||
| Spørgsmål | Valg |
|
||||
|---|---|
|
||||
| Hvor er "hjem"? | Nærmeste af de gårdlagre, spilleren vælger i flowet, der tager varen og har plads |
|
||||
| Hvad er "x vogne"? | Lånte ledige vogne fra hele gården — ingen fast tilknytning — højst x ude samtidig |
|
||||
| Hvilke vogne må lånes? | Samme regel og flueben som markarbejdet (`fleetMode` "all"/"ticked", `ADFieldJobs.state.fleet`) |
|
||||
|
||||
## Begreber
|
||||
|
||||
- **Marksilo:** bygning af typen silo inden for `ADFields.FIELD_SILO_DISTANCE` (150 m) af en marks polygon
|
||||
(`ADFields.fieldSilos`), samlet over alle marker, uden dubletter. En bygning, der er valgt som gårdlager i
|
||||
flowet, er aldrig marksilo.
|
||||
- **Gårdlager:** bygning spilleren vælger i flowet (samme bygningsvælger som udkørslens lagre, `storeBuildings`).
|
||||
- **Lån:** en vogn, flowet har sendt på én tur. Lån ligger kun i hukommelsen.
|
||||
|
||||
## Flowet
|
||||
|
||||
Ny run-type `fieldSilos` i `ADRuns.KINDS` (ved siden af `supply`/`outbound`). Højst ét marksilo-flow pr. savegame
|
||||
(GUI'et tilbyder ikke at oprette et til, når det findes).
|
||||
|
||||
Felter (gemmes i `ADSmartPickup_runs.xml` som de øvrige):
|
||||
- `storeBuildings` — gårdlagre (bygnings-id'er → markører via den eksisterende `resolveMarkers`)
|
||||
- `maxVehicles` — x, 1–10, standard 2
|
||||
- `minLiters` — tærskel pr. silo og vare, standard 10000
|
||||
- `running` — til/fra (som de andre flows' Start/Stop)
|
||||
|
||||
## Planlægning (ren logik, nyt modul `adFieldSiloPlanner.lua`, testes med luajit)
|
||||
|
||||
Input: marksiloer `{id, markerId|nil, stock = {[fillType] = liters}}`, gårdlagre `{id, markerId, accepts =
|
||||
{[fillType] = freeLiters}, x, z}`, aktive lån `{siloId, fillType, liters}`, ledige vogne `{id, x, z, capacity,
|
||||
carries = {[fillType] = true}}`, `maxVehicles`, `minLiters`.
|
||||
|
||||
1. **Kvalificerede opgaver:** pr. (silo, vare) hvor silo har markør, `liters >= minLiters`, og mindst ét
|
||||
gårdlager har `freeLiters >= minLiters` for varen. Resten = liters minus det aktive lån på samme (silo, vare)
|
||||
allerede er på vej med; kun opgaver med rest `>= minLiters` tæller.
|
||||
Siloer uden markør → status `noMarker`; varer intet gårdlager tager → status `noFarmStore`.
|
||||
2. **Rækkefølge:** fuldeste rest først; lige → lavest silo-id (stabilt).
|
||||
3. **Vogne:** ledige pladser = `maxVehicles - #aktive lån`. For hver opgave i rækkefølge, så længe der er
|
||||
pladser: nærmeste ledige vogn (til siloen), der kan bære varen; resten reduceres med vognens kapacitet;
|
||||
samme opgave får flere vogne, så længe resten stadig er `>= minLiters`.
|
||||
4. **Gårdlager pr. lån:** nærmeste gårdlager (til siloen) der tager varen med `freeLiters >= min(vognens
|
||||
kapacitet, rest)`; ellers det med mest plads; ellers intet (opgaven springes over denne runde).
|
||||
|
||||
Output: `{dispatch = {{vehicleId, siloId, siloMarkerId, fillType, storeMarkerId, liters}}, status = {...}}`.
|
||||
|
||||
## Udførelse (`adFieldSilos.lua`)
|
||||
|
||||
- **Takt:** planlæg hvert 60. s (spiltid via `dt`), kun når flowet kører. Lagertal læses som i dag
|
||||
(`ADSmartPickup.getStationLevelAndCapacity` / silo-lagre).
|
||||
- **Ledige vogne:** `ADFieldWork.getRigs(adEnv)` filtreret til `enabled and not busy and not controlled`, og
|
||||
vogne der har aflæsbare enheder (`AutoDrive.getAllDischargeableUnits`), der understøtter varen.
|
||||
`getRigs.busy` udvides med `ADFieldSilos.isLoaned(vehicle)`, så markarbejdet ikke tager en lånt vogn
|
||||
(flows tager allerede kun deres egne tilknyttede vogne).
|
||||
- **Afsend:** AutoDrive "Hent og aflever": første markør = silomarkør, anden = gårdlagerets markør, vare =
|
||||
lånets vare, `loopCounter = 1`, parkering ved job slut slået til (`enableParkAtJobFinished`); start som
|
||||
markarbejdet (`startAd` → mode:start). Log: `marksilo: '<vogn>' henter <liter> l <vare> i <silo> → <lager>`.
|
||||
- **Frigivelse:** lånet slettes når AD ikke længere er aktivt for vognen (turen og parkeringen er færdig),
|
||||
når spilleren sætter sig i den, eller når flowet stoppes (stop = AD stoppes på lånte vogne).
|
||||
- **Vagt:** er vognen ikke kommet i gang (ingen stigning i fyldning og står stille) efter 120 s, stoppes AD,
|
||||
lånet slettes, og der logges én advarsel pr. (silo, vare), så samme opgave ikke fejler i ring hvert minut
|
||||
(opgaven får 10 min pause).
|
||||
- **Genindlæsning:** lån gemmes ikke. Ved indlæsning er alle vogne frie for flowet; en vogn AutoDrive selv
|
||||
genstarter, kører sin tur færdig som almindelig AD-tur.
|
||||
|
||||
## GUI
|
||||
|
||||
Flow-fanen: typen "Marksiloer" kan oprettes (højst én). Indstillinger: gårdlagre (eksisterende vælger),
|
||||
"Maks. vogne ude" (1–10), "Mindste mængde" (5.000 / 10.000 / 25.000 / 50.000 l), Start/Stop.
|
||||
Status: `x/y vogne ude · n siloer venter`, og én række pr. marksilo med indhold: silo, vare, liter, på vej,
|
||||
status (`ok` / `mangler markør` / `ingen gård tager <vare>`). Tekster i `l10n_da` + `l10n_en` (`spu_fs_*`).
|
||||
|
||||
## Uden for scope
|
||||
|
||||
- Salg direkte fra marksilo (kan senere bruge udkørslens prisregel).
|
||||
- Faste vogne i flowet (valg 1 i brainstorm) — fravalgt.
|
||||
- Lån der overlever genindlæsning.
|
||||
|
||||
## Test
|
||||
|
||||
- `tests/test_adFieldSiloPlanner.lua`: kvalificering (tærskel, markør, gård tager varen), fuldeste først,
|
||||
x-loft inkl. aktive lån, flere vogne til én stor silo, vogn der ikke kan bære varen springes over, nærmeste
|
||||
gårdlager med plads, fallback til mest plads, intet lager → ingen afsendelse.
|
||||
- `tests/test_adRuns.lua`: ny kind gemmes/indlæses med `maxVehicles`/`minLiters`; ukendt kind → supply som før.
|
||||
- In-game: silo ved en mark med 50.000 l hvede, gårdlager = Farma-silo, x = 2 → to vogne kører, afleverer,
|
||||
parkerer; markarbejdet tager ikke de lånte vogne imens.
|
||||
Reference in New Issue
Block a user