Files
fs25-adsmartpickup/docs/superpowers/plans/2026-09-23-flow-tavle.md
T
2026-09-23 18:13:14 +02:00

5.9 KiB
Raw Blame History

Flow-tavle — implementeringsplan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Én tavle med ét flow pr. række (Vare · Fra · Til · Regel · Traktorer · Status); Fra/Til vælges som bygninger, markører findes automatisk. Faner: Flows · Lagre.

Architecture: Ny spil-adapter adBuildings.lua (bygninger + markør-opslag + cache). Modellen får bygnings-id-lister; controlleren udleder waypoint-lister fra dem (resolveMarkers) så planlægger/hooks er uændrede. GUI omskrives: SmartPickupFrame.lua (faner, tavle, fælles), SmartPickupFlowTab.lua (detail-blok), SmartPickupStorageTab.lua (uændret).

Tech Stack: FS25 Lua, AutoDrive-globaler via FS25_AutoDrive, luajit-tests.

Spec: docs/superpowers/specs/2026-09-23-flow-tavle-design.md

Global Constraints

  • Motoren (adOutbound, adOutboundPlanner, adSupplyPlanner, adUnloadWait, adSmartPickup-hooks) røres ikke.
  • Byg kun når alle tests er grønne (for t in tests/test_*.lua; do luajit $t|tail -1; done), derefter zip → ~/FS25-data/mods/ → commit → push gitea main.
  • Version 1.13.0.0. XML-version 3; v1/v2 læses.
  • Wait-markører er aldrig bygningsmarkører. Siloers læssemarkør = strengt opslag; alt andet = nærmeste ≤ 40 m.

Review Focus

  1. Run med bygning der er solgt siden sidst: rækken viser "(mangler)", Start afviser med noMarker, intet crash. (Task 3 test)
  2. v2-fil med markør der ikke kan oversættes til en bygning: markøren beholdes rå og virker som før. (Task 2 test)
  3. To bygninger med markører inden for 40 m af hinanden (silo-rækker): hver silo får sin egen markør (strengt opslag). (Task 1 test)
  4. Forsynings-run: Fra vises som "alle siloer" og sources-listen røres ikke. (Task 3 test)
  5. Fanen rebuild'es mens et run kører: Start/Stop-knappen og status følger isRunning. (in-game)

Task 1: adBuildings

Files: Create FS25_ADSmartPickup/adBuildings.lua; Test tests/test_adBuildings.lua.

Produces:

ADBuildings.MAX_MARKER_DISTANCE = 40; ADBuildings.CACHE_MS = 1000
ADBuildings.list(adEnv, farmId)          -- {building...} sorteret kind, navn (cachet)
ADBuildings.find(adEnv, farmId, id)      -- building | nil
ADBuildings.byMarker(adEnv, farmId, wayPointId, role)  -- role "load"|"unload": building hvis markøren er dens markør, ellers nil
ADBuildings.getId(placeable)             -- uniqueId eller "pos:x:z"
ADBuildings.invalidate()
building = {id, name, kind, placeable, loadMarker={id,name,distance}|nil, unloadMarker=…|nil, canBeSource, canBeTarget, canSell}

Kilder til bygninger: g_currentMission.placeableSystem.placeables (ejet af farm eller sell) — kind: factory (spec_productionPoint), silo (spec_silo), husbandry (getHusbandryFillLevel), objectStorage (spec_objectStorage), sell (ADPrices.isSellingStation på placeable.spec_sellingPoint / unloadingStation via storageSystem). Læssetriggere: productionPoint.loadingStation.loadTriggers, spec_silo.loadingStation.loadTriggers, husbandry: alle loadingStations i storageSystem med owningPlaceable == placeable. Aflæsningstriggere: unloadingStations med owningPlaceable == placeable. Objektlager/pallespawner: rootNode/spawnPlaces[1].startNode. Markørvalg: nærmeste markør (ikke Wait) til en trigger-node ≤ 40 m; for silo-load: kun markører hvor ADSmartPickup.getLoadStationAtWayPointId(marker.id) == siloens station.

  • Tests B1–B7 (kind, markører, silo strengt, Wait udelukket, byMarker, id-fallback, cache-invalidering) → RED → implementér → GREEN → commit feat: adBuildings.

Task 2: Model v3

Files: Modify adRuns.lua, adRunsStorage.lua; Test tests/test_adRuns.lua.

Produces: run-felter sourceBuildingIds, targetBuildingIds (lister af strenge); ADRuns.toggleSourceBuilding/toggleTargetBuilding(store, runId, id); XML v3 #sourceBuildings/#targetBuildings (mellemrumsadskilte). ADRuns.XML_VERSION = 3. Migration sker i controlleren (Task 3), ikke i modellen.

  • Tests R-v3 → RED → implementér → GREEN → commit.

Task 3: Controller — resolve + migration + validering

Files: Modify adRunsController.lua; Test tests/test_adRunsController.lua.

Produces:

ADRunsController.resolveMarkers(adEnv, run)   -- udfylder run.sourceWayPointIds (outbound) / targetWayPointIds (supply) fra bygninger; rå markører (uden bygning) bevares; returnerer {missing = {buildingName...}}
ADRunsController.migrateBuildings(adEnv)      -- ved load: markører → bygnings-id via byMarker; logger
ADRunsController.getFlowRow(adEnv, run)       -- {product, from, to, rule, vehicles, status, warning} tekster til tavlen
validateVehicle: ny grund "noMarker" når en valgt bygning mangler markør

Start/plan: startRun og ADOutbound.buildPlanInput kalder resolveMarkers først (buildPlanInput via ADRunsController.getRunForVehicle → resolve i getRunForVehicle? nej: i ADSmartPickup.choosePickup/ADOutbound.choosePickup kaldes ADRunsController.resolveMarkers(adEnv, run) én gang pr. plan).

  • Tests C-flow → RED → implementér → GREEN → commit.

Task 4: GUI — Flows-fane

Files: Rewrite gui/SmartPickupFrame.lua (faner Flows/Lagre, tavle, fælles rækker, knapper), Create gui/SmartPickupFlowTab.lua (detail-blok, callbacks), delete SmartPickupSupplyTab.lua/SmartPickupOutboundTab.lua (indhold flyttes), Modify gui/SmartPickupFrame.xml (statiske rækker: runOption "Flow", waitPool, loops, returnBelow, sellAt, storeAbove; prefabs som i dag), l10n da/en (spu_tab_flows, spu_flow_*, spu_direction_in/out, spu_from_allSilos, spu_noMarker, spu_reason_noMarker, spu_section_*), adSmartPickup.lua (source()).

  • Implementér; syntaks- og definitions-tjek; in-game.

Task 5: README, version, byg, deploy, push, memory.