Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3b644b7
test(fat-cow): in-game spike for a runtime FARP, its finite stock and…
davidp57 Oct 26, 2026
2324ed2
test(fat-cow): start the spike Apaches on the ground, engines running
davidp57 Oct 26, 2026
e3c800f
docs(fat-cow): record the spike's single-player answers
davidp57 Oct 26, 2026
33f73e7
test(fat-cow): spike commands for FARP props alone and a fuel truck a…
davidp57 Oct 26, 2026
5438c87
docs(fat-cow): FARP statics supply the ground crew, no vehicle needed
davidp57 Oct 26, 2026
957a245
test(fat-cow): spike commands to find which FARP static supplies
davidp57 Oct 26, 2026
65240a5
test(fat-cow): spike commands for the fuel depot and the ammo dump alone
davidp57 Oct 26, 2026
1548066
docs(fat-cow): the FARP Fuel Depot alone supplies fuel and weapons
davidp57 Oct 26, 2026
bb524cd
docs(fat-cow): tickets 02-06 of the lot
davidp57 Oct 26, 2026
a69637a
feat(fat-cow): a cow's stock and the FARP scene it lays out
davidp57 Oct 26, 2026
baed90c
feat(fat-cow): deploy, pack and re-sync a cow's FARP
davidp57 Oct 26, 2026
3ae0b9d
feat(fat-cow): a piloted cow's stock is the cow crates in its hold
davidp57 Oct 26, 2026
73b2f86
feat(fat-cow): F10 Fat Cow section for a piloted CH-47F
davidp57 Oct 26, 2026
0197490
feat(fat-cow): AI cow that escorts a flight and serves it in the field
davidp57 Oct 26, 2026
ba33b1a
feat(fat-cow): fatCow settings, catalogue 2.3.0 and translations
davidp57 Oct 26, 2026
c904191
docs(fat-cow): pilot and mission-maker pages, CHANGELOG; correct the …
davidp57 Oct 26, 2026
13f4eec
chore(fat-cow): declare the Fat Cow globals to luacheck
davidp57 Oct 26, 2026
0c12473
fix(fat-cow): only the flight's leader moves the cow; dressing clear …
davidp57 Oct 26, 2026
a4eb21b
fix(fat-cow): dressing outside the object registry, the scene tested …
davidp57 Oct 26, 2026
3045a30
fix(fat-cow): review findings
davidp57 Oct 26, 2026
fd16eb8
docs(fat-cow): backlog status and the final VMCT contract
davidp57 Oct 26, 2026
d8da383
docs(fat-cow): live check kit and procedure (ticket 06)
davidp57 Oct 26, 2026
aa753b7
docs(fat-cow): server variant of the live check (Syria Open Training …
davidp57 Oct 26, 2026
1e0d608
docs(fat-cow): fix a path in the server variant note
davidp57 Oct 26, 2026
b6cc2c6
feat(fat-cow): a player flight commands its cow from F10; request fro…
davidp57 Oct 26, 2026
022538a
feat(fat-cow): CH-47 loadouts straight into the hold, FARP status for…
davidp57 Oct 26, 2026
5cd3286
docs(fat-cow): loadouts, F10-commanded AI cow, Fat Cow and FARP status
davidp57 Oct 26, 2026
b119792
docs(fat-cow): first server run of the live check
davidp57 Oct 26, 2026
17271ff
feat(fat-cow): Release the Fat Cow becomes RTB (Rentre à la base)
davidp57 Oct 26, 2026
346a9c3
chore(fat-cow): drop the stale keys this branch created itself
davidp57 Oct 26, 2026
782a4a2
Merge remote-tracking branch 'origin/develop' into feature/fat-cow
davidp57 Oct 26, 2026
7433a63
docs(fat-cow): backlog index and PRD point to PR #273
davidp57 Oct 26, 2026
485c5ee
docs(fat-cow): deployFromHold's comment back above it
davidp57 Oct 26, 2026
b8f860f
docs(fat-cow): evening run findings and the fixes pending
davidp57 Oct 26, 2026
2020cd2
fix(fat-cow): one FARP per cow, stock guard, loadout profiles
davidp57 Oct 27, 2026
b329028
feat(fat-cow): Russian and mixed loadouts, one CH-47 for everyone
davidp57 Oct 27, 2026
3b11899
fix(fat-cow): stow the cow when its depot fails, close a FARP left by…
davidp57 Oct 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .backlog/FEAT-FAT-COW/PRD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# FEAT-FAT-COW — a CH-47 that lands in the field and becomes a forward refuel/rearm point

**Status:** 🔄 in-progress — ticket 01 phase 1 done (2026-10-26): a runtime Invisible FARP serves a player already in game, enforces a finite stock, and needs a supplier in range, which the `FARP Fuel Depot` static alone satisfies, for fuel and weapons, without any vehicle. Phase 2 (a remote multiplayer client) not run: Zip hosted, so his view was the server's; the design re-applies the stock on every birth instead. Tickets 02-05 implemented (Zip, 2026-10-26: "implémente"), then reworked after the first server run (loadouts, F10-commanded AI cow, statuses, RTB); PR #273. Ticket 06, the live check with the squadron, waits for Zip.

Designed with Zip on 2026-10-26 (VMCT session). Zip decided that the runtime belongs in CTLD, not in the VMCT Lua; VMCT will vendor this CTLD and add a static mission-editing tool for it afterwards.

## Problem Statement

Attack helicopters (typically AH-64D) on a long sortie have to fly back to an airfield or a mission-placed FARP to refuel and rearm.
The US Army answers this with the "Fat Cow": a CH-47 that lands near them and serves fuel from its internal tanks.
Army.mil (Feb 2020) calls it "a rapidly employed FARP" enabling "a quick refuel and rearm" of AH-64s; DVIDS (May 2022) mentions two ERFS tanks of 800 gal.

DCS has no fuel-transfer API, and the CH-47F definition has no fuel-transfer capability.
So the cow can only be a FARP spawned next to it, stocked with what the cow carries.

ED announced a native Fat Cow on 2024-04-19 and again on 2024-08-23; it is absent from DCS 2.9.30.28738.

## Decisions (Zip, 2026-10-26)

1. **Two modes, one core.**
- **AI:** a cow can be requested only on the ground, inside a friendly CTLD logistic zone. It escorts the requesting flight, lands near it when it lands, and deploys the FARP after **60 s** on the ground. When the flight takes off, it packs the FARP and follows again. It flies back to its logistic zone and despawns when its stock is empty, and also on an F10 "release the Fat Cow" command.
- **Piloted:** a player CH-47F (`CH-47Fbl1`) loads "cow" crates in a logistic zone: one crate = one 800 gal ERFS tank (about 2 400 kg of fuel, that mass in the hold), plus optional ammo crates (Hellfire, 30 mm). Once landed, an F10 command deploys the FARP, and another packs it.
2. **Materialisation:** an Invisible FARP, a few crates around and 2 or 3 infantry. **No vehicles** (Zip: where would they come from?). Reuses the scene mechanism of `src/scenes/` (`CTLD_countrysideFarpScene.lua`, `CTLD_farpScene.lua`).
3. **Stock = what the cow carries**, as a finite FARP warehouse, not unlimited. **AI default: full fuel (3 × 800 gal, about 7 200 kg) and 6 Hellfires**, configurable in the CTLD config. The 6 is Zip's call: no source gives the Hellfire load of a cow.
4. **Ticket 01 is an in-game spike, before building the rest.** If an answer kills the design, stop and report to Zip.

## What the spike must settle, and why it is not obvious

- `src/scenes/CTLD_countrysideFarpScene.lua` contradicts itself: its header says the Invisible FARP "creates a proper DCS airbase (warehouse…)", its step 11 says "Invisible FARP airbases (DCS built-in) return nil for getWarehouse()". The finite stock of decision 3 needs a warehouse.
- VMCT refills FARP warehouses on every player birth (`veafGrass.fillFarpWarehouse`) because warehouses do not sync over the network, and an ED forum guide (2024) says dynamically spawned FARPs start empty and resupply badly by script.
- RotorOps PERKS does not spawn its Fat Cow FARP: it teleports FARP statics pre-placed in the Mission Editor (`RotorOpsPerks.teleportStatic`), and skips the deployment when enemies are within 1.1 nm, because DCS refuses to rearm/refuel there. Both are hints that a runtime FARP is fragile.
- DCS historically needed a fuel truck and an ammo truck near a FARP. Decision 2 has none; if DCS still needs them, the fallback is a vehicle hidden under the cow's fuselage.

## Design (to be confirmed by the spike)

- **Core:** a `CTLDFatCow` entity (Manager + Entity pattern) holding a stock (fuel kg, items by warehouse name) and a state (`flying`, `landed`, `deployed`, `packing`, `returning`). Deploy = run the cow scene next to the cow, then set the FARP warehouse to the stock. Pack = read the warehouse back into the stock (what the players consumed is gone), then remove the scene. Empty stock → the AI cow goes home.
- **AI mode** listens to `S_EVENT_LAND` / `S_EVENT_TAKEOFF` of the escorted flight (CTLD already subscribes to these for players and AI transports), and drives the cow with DCS tasks (`Follow`/escort, `Land`).
- **Piloted mode** reuses the crate system: cow crates are crate models whose weight is the fuel mass; the deploy command sums the loaded cow crates into the stock.
- **Config** under one `fatCow` block in `src/CTLD_config.yaml` (adds keys → `configVersion` bump and a catalogue shape, per `CLAUDE.md`).

## Contract for VMCT

Documented for mission makers in `docs/mission-maker/fat-cow.md` (EN + FR).

- **A mission-placed AI cow** is a **late-activated helicopter group** declared in `fatCowAICows` with the flight it escorts: `fatCowAICows = [{ group: "<CH-47 group>", escort: "<flight group>", loadout: <index, default 1> }]`. CTLD activates it once the escorted group is in the world (at start for an AI flight, at the first player's birth for a client flight). The engine never parses a cow's name (see `CONTEXT.md`, "Config-referenced zone").
- **Settings:** `fatCowEnabled`, `fatCowTypes` (`[CH-47Fbl1]`), `fatCowCrates` (`desc`, `weight`, and `fuelKg` or `item` + `count`), `fatCowLoadouts` (`desc`, `fuelKg`, `items`: what a cow carries, piloted or AI), `fatCowDeployDelay` (60 s), `fatCowAIType` (`CH-47Fbl1`; empty disables the request), `fatCowAICows` (`fatCowAIFuelKg` and `fatCowAIItems`, in no release, were replaced by the loadouts). Catalogue version 2.3.0.
- A requested AI cow is created by script (`coalition.addGroup`, type `fatCowAIType`), so no template group is needed in the mission; the draft's `fatCow.aiTemplate` was dropped for that reason.

## Tickets

| # | Ticket | Status |
|---|---|---|
| 01 | [In-game spike: a runtime FARP, its finite stock, its vehicles](tickets/01-spike-runtime-farp.md) | 🧑 phase 1 done (a yes, b yes server side, c the FARP Fuel Depot alone suffices, no vehicle); phase 2 to run |
| 02 | [Core: a cow's stock, its scene, deploy and pack](tickets/02-core-stock-and-scene.md) | ✅ done |
| 03 | [Piloted cow: cow crates in a CH-47F and the F10 commands](tickets/03-piloted-cow.md) | ✅ done |
| 04 | [AI cow: requested by a flight, escorts it, serves it, goes home](tickets/04-ai-cow.md) | ✅ done |
| 05 | [Config, VMCT contract doc, CHANGELOG and release notes](tickets/05-config-docs-release.md) | ✅ done (release-notes jab in the CHANGELOG entry, for the release to carry) |
| 06 | [Live check in DCS](tickets/06-live-check.md) | 🧑 waiting-human (Zip) |

## Release notes

When the feature ships, the release notes poke fun at ED's native Fat Cow, announced on 2024-04-19 and 2024-08-23 and still absent from DCS 2.9.30.28738.
106 changes: 106 additions & 0 deletions .backlog/FEAT-FAT-COW/tickets/01-spike-runtime-farp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# 01 — In-game spike: a runtime FARP, its finite stock, its vehicles

**Status:** 🧑 waiting-human — phase 1 done (2026-10-26), phase 2 (multiplayer client) not run yet · **Type:** HITL (live DCS, Zip)

## Parent

[PRD — FEAT-FAT-COW](../PRD.md). Decision 4.

## Questions

- **(a)** Does a FARP spawned mid-mission serve refuel/rearm to a player who was already in game?
- **(b)** Is a finite warehouse stock respected, and seen identically by the server and by a client?
- **(c)** Does DCS require a refuel/ammo vehicle in range of an Invisible FARP?

## Kit

- `tests/dcs/pilotActive/scenario_fatcow_spike.lua` — pure DCS API, no CTLD. An F10 menu per player group, "Fat Cow spike": 1 Invisible FARP under me · 2 Finite stock (300 kg, 2 Hellfire) · 3 Read stock + my aircraft · 4 Add fuel + ammo trucks · 5 Crates only (barrels + ammo crate) · 6 Remove everything · 7 Add FARP props (fuel depot, ammo dump, barrels, ammo crate) · 8 Fuel depot only · 9 Ammo dump only. Commands 5, 7–9 were added after the first runs (the single-pad variant and a fuel-truck-only command were dropped once moot). Every measurement goes to the screen and to `dcs.log`, prefixed `[FCSPIKE]`.
- `missions/Test_FatCow_Spike.miz` — Caucasus, a flat field 19 km from Senaki and from Kutaisi (no airfield ground crew in reach). Two AH-64D slots (`Apache-1`, `Apache-2`, 80 m apart), ground start with engines running (`TakeOffGroundHot`) on the field, 30 % fuel (342 kg), empty pylons: the spike needs no flying (Zip, 2026-10-26: no stick at hand). Trees at the exact spot are not checked by any file: a slot that explodes at spawn means a tree. The script is embedded and runs at mission start.
- Built with the VMCT `veaf-mission-editor` actions on a blank Caucasus mission (`veaf_libs.blank_mission`): `add_player_slot` ×2 (air start), `set_group_properties` `move_to` ×2 and `edit_route` `set` waypoint 1 to `TakeOffGroundHot` ×2 (`add_player_slot` refuses a ground start off an airfield), `add_startup_script_trigger` (`file_static`). To rebuild after a script change, redo these actions on a fresh blank mission.

The 300 kg of fuel is below the ~800 kg a 30 % Apache takes to fill up, and the 2 Hellfires below the 4 a rail takes: a cap shows as a partial service.

## Procedure — phase 1, single player (answers a, c, and b on one machine)

Press **Print Screen** (DCS screenshot, saved in `Saved Games\DCS\Screenshots`) where marked 📸: the screenshots and `dcs.log` are read afterwards, nothing has to be copied by hand.

1. DCS main menu → **MISSION** → `Test_FatCow_Spike.miz` → **OK**. If a slot is asked, take **Apache-1**.
2. You are on the ground, engines running. A message `[FCSPIKE] loaded` shows at start. Touch nothing.
3. `\` → **F10 Other** → **Fat Cow spike** → **F1** "1. Invisible FARP under me". Green smoke under you; lines `SPAWNED` and `INITIAL STOCK`. 📸
4. `\` → **F8 Ground Crew** → **F1 Rearm & Refuel**. The rearm window opens (or not). 📸 Close it.
5. `\` → **F10 Other** → **Fat Cow spike** → **F2** "2. Finite stock". Lines `SET STOCK` and `STOCK READ BACK`. 📸
6. `\` → **F8 Ground Crew** → **F1 Rearm & Refuel**. 📸 In the window: fuel to **100 %**, and **4 × AGM-114K** on one pylon. Confirm the window.
7. Wait until the ground crew is done (or says it cannot). 📸
8. `\` → **F10 Other** → **Fat Cow spike** → **F3** "3. Read stock + my aircraft". 📸
9. **Only if step 6 or 7 refused the service:** `\` → **F10 Other** → **Fat Cow spike** → **F4** "4. Add fuel + ammo trucks", then redo steps 6 to 8.
10. **Only if step 3 printed `getWarehouse() = nil`:** `\` → **F10 Other** → **Fat Cow spike** → **F6** "6. Remove everything", then **F5** "5. Single pad FARP ahead", hover-taxi onto the green smoke 40 m ahead, land, and redo steps 4 to 8. This step needs flight controls: without them, stop at step 9 and report.
11. Quit the mission. Say "phase 1 done".

## Procedure — phase 2, multiplayer (the client side of b)

Needs the mission on a dedicated server (the VEAF test server) and Zip joining it as a client: in single player the server and the client are the same process.

1. Load `Test_FatCow_Spike.miz` on the server. Join it as a client, slot **Apache-1**.
2. Steps 2 to 8 of phase 1.
3. Back to spectators (**Esc** → **Choose slot** → spectators), then take **Apache-1** again: a new birth. The script prints `STOCK AT BIRTH`.
4. `\` → **F8 Ground Crew** → **F1 Rearm & Refuel**. 📸
5. Quit. The server's `dcs.log` holds the `[FCSPIKE]` lines.

## Reading the results

| What is seen | Conclusion |
|---|---|
| Step 3 `INITIAL STOCK` prints numbers | (b) The Invisible FARP has a warehouse: the countryside scene's step 11 comment is wrong. |
| Step 3 prints `getWarehouse() = nil` | No finite stock on an Invisible FARP → step 10; if the single pad has one, decision 2 changes its FARP type (to Zip). |
| Step 4 window opens with nothing to take | (b) The runtime FARP starts empty, as the forum guide says: the cow must stock it, which it does anyway. |
| Step 6–7 serves, without trucks | (a) yes and (c) no vehicle needed: decision 2 holds. |
| Step 6–7 refuses, step 9 serves | (c) DCS needs vehicles: fallback, a vehicle hidden under the cow's fuselage. |
| Step 9 still refuses | (a) a runtime FARP does not serve a player already in game: stop, report to Zip (the RotorOps route, teleporting pre-placed FARPs, becomes the candidate). |
| Step 8: aircraft got ~300 kg and 2 Hellfires, stock 0 | (b) finite stock respected on the server. |
| Step 8: aircraft got full fuel and 4 Hellfires | (b) the stock is not enforced: stop, report to Zip (decision 3). |
| Phase 2: rearm window shows the same quantities as `STOCK NOW` | (b) client and server agree. |
| Phase 2: the client's window shows something else (empty, or unlimited) | (b) no network sync: the stock has to be re-applied on each birth, as VMCT does, and enforcement checked server-side. |

## Answers

### Phase 1 — single player, 2026-10-26 (Zip, DCS 2.9.30.28738, no stick: Apache on the ground, engines running)

From `dcs.log` and Zip's screenshots.

| Step | Measured |
|---|---|
| 3 | `INITIAL STOCK`: jet fuel 0, every Hellfire 0, inventory empty. `getWarehouse()` is not nil. DCS logs `NO ATC COMM HELIPAD + FCSPIKE_FARP_1:127500000` (a warning, no effect seen). |
| 4 | The Mission Resources window opens, loadout list empty. |
| 5 | `STOCK READ BACK`: jet fuel 300, `AGM_114K` 2, the two other Hellfire names 0. |
| 6–7 (no trucks) | Fuel 100 % + 4 × AGM-114K, OK: nothing happens, no message. |
| 9 (trucks) | Same request: the ground crew answers, works ~30 s, then "Unable to comply". |
| 9 again | Fuel 50 %: "We don't have this in stock". |
| 7 (props, new mission) | Fuel 100 % + 4 × AGM-114K: "Copy", then served; `STOCK NOW` 0, `AIRCRAFT` 634 kg and `AGM_114K` ×2. |
| 8 | `STOCK NOW`: jet fuel 0, `AGM_114K` 0. `AIRCRAFT`: fuel 631 kg / 1 140 kg (342 at spawn), `AGM_114K` ×2, `M230_HEDP M789` ×1 200 (already full). The window shows 56 % and 2 Hellfires on pylon 2. |

- **(a) Yes.** An Invisible FARP spawned by `coalition.addStaticObject` mid-mission serves a player already in game.
- **(b) Yes, on the server side.** The runtime FARP has a warehouse and starts empty. A finite stock set by script is served until it runs out, then refused: +289 kg for 300 kg in stock (the rest burnt at idle during the test), 2 Hellfires out of 4 asked. A request bigger than the stock is partly served, then answered "Unable to comply". Liquids are in kg. The Hellfire item is `weapons.missiles.AGM_114K`.
- **(c) A supplier is required, but statics are enough: no vehicle.** With the FARP alone the window opens but nothing is served and nothing is said. With an M978 HEMTT Tanker and an M 818 30 m away, it is served. With **statics only** (command 7: `FARP Fuel Depot`, `FARP Ammo Dump Coating`, `barrels_cargo`, `ammo_cargo`, 25–30 m away, no vehicle) the ground crew answers "Copy" and serves: fuel 342 → 634 kg, `AGM_114K` ×2, stock down to 0. Decision 2 holds as is, no hidden vehicle. Then each static alone, on a new FARP with a new 300 kg / 2 Hellfire stock each time:

| Statics around the FARP | Fuel | Hellfire |
|---|---|---|
| none | no (no answer) | no |
| `barrels_cargo` + `ammo_cargo` (command 5), or each alone | no (no answer) | no |
| **`FARP Fuel Depot` alone** (command 8) | **yes** (+292 kg, stock 0) | **yes** (2, stock 0) |
| `FARP Ammo Dump Coating` alone (command 9) | no ("No can do", stock stays 300) | yes (2 → 4) |

**The `FARP Fuel Depot` alone supplies both fuel and weapons**; the ammo dump supplies weapons only; cargo statics supply nothing. The cow scene therefore needs the fuel depot and nothing else as a supplier: no ammo dump, no tent, no vehicle (Zip dislikes the bunker and the tent). Not measured: the range (25–30 m was used).
- Where the rule lives: not in DCS's Lua files (`db.Units.lua` gives the M978 and M 818 only generic attributes, and the FARP statics none), nor as text in the clear DLLs of `bin/`; it is in the compiled engine, probably `Inter.dll` or `WorldGeneral.dll`. Measuring in game was preferred over decompiling.
- The countryside scene's step 11 comment ("Invisible FARP airbases … return nil for getWarehouse()") is wrong, measured.

No answer kills the design.

### Phase 2 — multiplayer client

Not run yet: needs the mission on a dedicated server with Zip joining it as a client.

## Acceptance criteria

- [x] (a), (b) on one machine, (c) answered from `dcs.log` and the screenshots, in this ticket and the PRD.
- [ ] (b) client side answered by phase 2, or marked not measured with the reason.
- [x] If an answer kills the design, reported to Zip before ticket 02 is written.
22 changes: 22 additions & 0 deletions .backlog/FEAT-FAT-COW/tickets/02-core-stock-and-scene.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 02 — Core: a cow's stock, its scene, deploy and pack

**Status:** ✅ done · **Type:** AFK

## Parent

[PRD — FEAT-FAT-COW](../PRD.md). Decisions 2, 3; ticket 01 answers.

## What to build

- A `CTLDFatCow` entity (Manager + Entity, `src/core/class.lua`) holding a **stock**: fuel in kg and weapons by warehouse item name (`weapons.missiles.AGM_114K`, the 30 mm item), and a state: `stowed` (on board), `deploying`, `deployed`.
- A `CTLDFatCowManager` singleton keyed by cow unit name.
- A **Fat Cow scene** (`src/scenes/CTLD_fatCowScene.lua`): an Invisible FARP at the cow, a `FARP Fuel Depot` 25 m behind it (the only supplier needed, ticket 01), a few ammo crates and barrels as dressing, 3 standing infantry. No vehicle, no tent, no ammo dump, no bunker.
- **Deploy**: plays the scene; on its last step, sets the FARP warehouse to the stock (jet fuel = stock fuel, every other liquid 0, each stocked item to its count).
- **Pack**: reads the FARP warehouse back into the stock (what the players took is gone), then removes the scene.
- **Re-sync**: on every player birth, each deployed cow re-writes its warehouse with the values the server holds (read, then write): ticket 01 did not measure the client side, and VMCT re-applies on birth for that reason. Costs nothing if DCS already syncs.
- Fix the countryside scene's step 11 comment: an Invisible FARP does have a warehouse (measured).

## Acceptance criteria

- [x] Busted: deploy writes the stock into the warehouse; pack reads the remainder back; a stock emptied by players reads back as empty; re-sync writes back what the server holds; the scene spawns no vehicle and includes a `FARP Fuel Depot`.
- [x] Scene assets pass the design-time asset gate.
21 changes: 21 additions & 0 deletions .backlog/FEAT-FAT-COW/tickets/03-piloted-cow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 03 — Piloted cow: cow crates in a CH-47F and the F10 commands

**Status:** ✅ done · **Type:** AFK

## Parent

[PRD — FEAT-FAT-COW](../PRD.md). Decision 1, piloted mode.

## What to build

- Cow crates in the CTLD crate catalogue, requestable in a logistic zone by a cow-capable type (`CH-47Fbl1` by default):
- **fuel tank**: one 800 gal ERFS tank, 2 400 kg of fuel, that mass in the hold;
- **Hellfire**: a crate of Hellfires (count and mass configurable);
- **30 mm**: a crate of 30 mm rounds (count and mass configurable).
- F10, once landed with cow crates on board: **Deploy Fat Cow FARP** — the stock is the sum of the cow crates on board, which stay on board (the fuel stays in the cow, as in reality).
- F10, deployed: **Pack Fat Cow FARP** — reads the remaining stock back; the cow crates on board are reduced to what is left (fuel mass in the hold goes down; an emptied crate disappears).
- Taking off while deployed packs automatically.

## Acceptance criteria

- [x] Busted: stock = sum of the cow crates on board; pack reduces the crates and the hold mass to what is left; the deploy command needs the cow on the ground and at least one cow crate; take-off packs.
Loading
Loading