Files
DCS-CTLD/.github/AS-IS-ANALYSIS.md

266 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DCS-CTLD — As-Is Analysis
> This document captures the current state of the CTLD codebase prior to
> the v2 modernization effort. It serves as a reference and justification
> for the changes outlined in `MODERNIZATION-PLAN.md`.
---
## 1. Overview
| Metric | Value |
| ------ | ----- |
| Primary script | `CTLD.lua` |
| Lines of code | ~8 700 |
| i18n script | `CTLD-i18n.lua` |
| Bundled dependency | `mist.lua` (MIST 4.5 build 128-DYNSLOTS-02) |
| Lua version | 5.1 (DCS sandbox) |
| Public functions (`ctld.*`) | 100+ |
| Local / private functions | 0 (everything is public on the `ctld` table) |
| OOP / metatables usage | None — fully procedural |
| Unit tests | None |
---
## 2. File structure
```text
.
├── CTLD.lua -- Main script (monolith)
├── CTLD-i18n.lua -- Translation tables (FR, ES, KO)
├── mist.lua -- MIST library (stock, not customized)
├── beacon.ogg -- Radio beacon sound
├── beaconsilent.ogg -- Silent beacon sound (FC3)
├── README.md -- User / mission-maker guide
├── demo-mission.miz
├── test-mission.miz
├── test-dev-dynamic.miz
├── test-dev-static.miz
├── test_witchcraft_#131.miz
└── test_witchcraft_#137 et #149.miz
```
No `src/`, no `test/`, no `docs/`, no CI configuration.
---
## 3. CTLD.lua section breakdown
| Section | Lines | Content |
| ------- | ----- | ------- |
| Header + contributors | 135 | Credits, links |
| i18n table setup | 36360 | English reference keys (all `= ""`), `i18n_translate()` |
| USER CONFIGURATION | 403600 | 50+ tunable parameters |
| Crate configuration | 6011 200 | `ctld.spawnableCrates`, AA system templates |
| Public API functions | 1 2001 950 | Functions usable from DO SCRIPT triggers |
| Core gameplay logic | 1 9504 600 | Troops, vehicles, crates, FOBs, beacons |
| JTAC subsystem | 4 6007 000 | Targeting, lasing, IR points, F10 menus |
| AI processing + menus | 7 0008 200 | AI auto-load/unload, F10 menu building |
| `ctld.initialize()` | 8 1908 400 | State tables init, zone parsing |
| Event handler + tools | 8 4008 705 | DCS event handler, `ctld.tools` utilities |
---
## 4. State management
34 global tables inside the `ctld` namespace track runtime state.
Most are duplicated per coalition.
### 4.1 — Coalition-duplicated tables (RED / BLUE pairs)
| Table pair | Content |
| ---------- | ------- |
| `ctld.spawnedCratesRED` / `BLUE` | Spawned crate statics |
| `ctld.droppedTroopsRED` / `BLUE` | Deployed infantry groups |
| `ctld.droppedVehiclesRED` / `BLUE` | Deployed vehicles |
| `ctld.droppedFOBCratesRED` / `BLUE` | FOB crates on ground |
This duplication creates **50+ `if coalition == 1 then … RED … else … BLUE`** branches.
### 4.2 — Shared tables
| Table | Content |
| ----- | ------- |
| `ctld.inTransitTroops` | Cargo currently onboard (keyed by unit name) |
| `ctld.inTransitSlingLoadCrates` | Simulated sling-load crates |
| `ctld.builtFOBS` | Completed FOB positions |
| `ctld.completeAASystems` | Assembled AA system groups |
| `ctld.deployedRadioBeacons` | Active beacons |
| `ctld.fobBeacons` | FOB beacon cache (refreshed every 60 s) |
| `ctld.extractZones` | Extract zone definitions |
| `ctld.hoverStatus` | Hover-over-crate tracking |
| `ctld.crateLookupTable` | Crate weight → type lookup |
| `ctld.callbacks` | Registered callback functions |
| `ctld.jtacUnits` | JTAC unit references |
| `ctld.jtacCurrentTargets` | JTAC active targets |
| `ctld.jtacSelectedTarget` | Player-selected JTAC targets |
| `ctld.jtacGeneratedLaserCodes` | Allocated laser codes |
| `ctld.usedUHFFrequencies` / `VHF` / `FM` | Radio frequency pools |
---
## 5. Code duplication patterns
### 5.1 — RED/BLUE branching (most pervasive)
```lua
-- This pattern appears 50+ times
if _heli:getCoalition() == 1 then
_list = ctld.droppedTroopsRED
else
_list = ctld.droppedTroopsBLUE
end
```
### 5.2 — Troop / Vehicle symmetry
Many functions have near-identical troop and vehicle variants differentiated
only by a boolean parameter (`true` = troops, `false` = vehicles).
### 5.3 — Sling load vs simulated load
Two code paths for crate pickup depending on `ctld.slingLoad`:
- Real sling load (DCS native, crashy)
- Simulated hover load (custom implementation)
### 5.4 — Zone handling
Pickup zones, dropoff zones, and waypoint zones share similar parsing
(smoke color, coalition check, active flag) but are implemented separately.
---
## 6. MIST dependency
91 calls to `mist.*` functions across the codebase.
| Category | Functions | Call count |
| -------- | --------- | ---------- |
| Utility | `deepCopy`, `round`, `makeVec2/3` | ~28 |
| Distance / vectors | `get2DDist`, `vec.mag`, `vec.dp`, `vec.sub` | ~15 |
| Heading / bearing | `getHeading` | ~8 |
| Coordinate format | `tostringLL`, `tostringMGRS` | ~4 |
| Spawning | `dynAdd`, `dynAddStatic` | ~8 |
| Route / waypoints | `buildWP`, `getGroupRoute` | ~4 |
| LOS / search | `getUnitsLOS`, `getAvgPos`, `makeUnitTable` | ~4 |
| Database | `mist.DBs.unitsByName` | iterated |
| Scheduling | `mist.scheduleFunction` | ~1 |
| Other | misc | ~19 |
No functions provide a fallback if MIST is absent — CTLD hard-crashes on
`assert(mist ~= nil)` during initialization.
---
## 7. Scheduling and timers
20+ `timer.scheduleFunction` calls drive recurring behavior.
All timers reschedule themselves recursively; there are no continuous
polling loops.
| Timer | Interval | Purpose |
| ----- | -------- | ------- |
| `checkTransportStatus` | 3 s | Monitor transport helicopters |
| `checkHoverStatus` | 1 s | Track hover-over-crate countdown |
| `refreshRadioBeacons` | 60 s | Update beacon battery status |
| `refreshSmoke` | 300 s | Refresh smoke markers |
| `checkAIStatus` | 2 s | AI troop behavior check |
| `timerJTACAutoLase` | variable | JTAC targeting loop |
| `timerLaseUnit` | variable | Single-unit lasing |
| `autoUpdateRepackMenu` | 1 s | Refresh vehicle repacking F10 menu |
| `reconRefreshTargetsInLosOnF10Map` | variable | RECON map markers |
---
## 8. Error handling
- **pcall usage**: 12 instances, mainly around crate spawning and hover math.
- **Nil checks**: Extensive `if X == nil then return end` before DCS API calls.
- **No structured error propagation**: errors are logged via `env.error()` /
`ctld.logError()` and silently swallowed.
- **No stack traces** or exception chaining.
---
## 9. Internationalization (i18n)
| Language | Code | `translation_version` | Completeness |
| -------- | ---- | --------------------- | ------------ |
| English | `en` | 1.6 | Reference (keys only, values = `""`) |
| French | `fr` | 1.6 | Partial — many crate/equipment names empty |
| Spanish | `es` | 1.6 | Similar to French |
| Korean | `ko` | **1.1** | Severely outdated, many missing keys |
Issues:
- No tooling to detect missing keys or version drift.
- Empty string (`""`) is a valid Lua value, so missing translations silently
fall back to the English key (which is also `""` for reference entries).
- All translations live in a single `CTLD-i18n.lua` file — no per-language
separation.
---
## 10. Documentation
| Audience | Coverage | Location |
| -------- | -------- | -------- |
| Mission maker | Partial | `README.md` (setup, config, API examples) |
| Player | Minimal | `README.md` (gameplay mechanics mentioned briefly) |
| Developer | None | No architecture doc, no contributing guide |
README strengths:
- Good coverage of pickup/dropoff zone configuration.
- Code examples for DO SCRIPT functions.
- Dynamic loading workflow documented.
README gaps:
- JTAC advanced features poorly explained.
- No API reference table (signatures, parameters, return values).
- No architecture or data flow diagrams.
- Some examples use different defaults than the current code.
---
## 11. Testing
- **No automated tests** of any kind.
- **Manual smoke testing** via `.miz` missions in the repository:
- `test-mission.miz` — full feature demonstration
- `test-dev-dynamic.miz` — dynamic script loading for fast iteration
- `test-dev-static.miz` — static loading variant
- `test_witchcraft_#131.miz`, `test_witchcraft_#137 et #149.miz` — bug repro missions
- No test framework, no mocks, no CI.
---
## 12. Dead code and technical debt
| Item | Location | Detail |
| ---- | -------- | ------ |
| Commented-out blocks | 18+ blocks across file | Old implementations, debug markers, disabled alternatives |
| Unused function | `ctld.tools.getRelativeBearing` | Defined but never called |
| Unused function | `ctld.tools.isValueInIpairTable` | Called once, could be inlined |
| Commented event handler | `ctld.initialize()` | Old `ctld.eventHandler` pattern, replaced but not removed |
| Disabled vehicle types | Crate config tables | Many entries commented out (`-- BUK`, `-- Strela`, etc.) |
| Debug markers | Various | `--ctld.logTrace("FG_ XXXX...")` left in code |
| Alternate coordinate | `ctld.listFOBS()` | MGRS conversion commented out |
---
## 13. Summary of pain points
1. **Monolithic file**: 8 700 lines, impossible to navigate or review efficiently.
2. **No encapsulation**: 100+ public functions, 0 local functions, all state is global.
3. **RED/BLUE duplication**: 50+ coalition branches + paired tables.
4. **MIST hard dependency**: 91 calls, no fallback, no abstraction layer.
5. **No tests**: zero automated tests, zero mocks, zero CI.
6. **No OOP**: purely procedural, no classes, no metatables.
7. **Dead code**: 18+ commented blocks, unused functions.
8. **i18n drift**: Korean 3 versions behind, many empty translations.
9. **No developer documentation**: new contributors must read 8 700 lines to understand the architecture.
10. **No build system**: the source file IS the deliverable.