mirror of
https://github.com/ciribob/DCS-CTLD.git
synced 2026-08-26 12:57:12 +00:00
266 lines
9.6 KiB
Markdown
266 lines
9.6 KiB
Markdown
# 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 | 1–35 | Credits, links |
|
||
| i18n table setup | 36–360 | English reference keys (all `= ""`), `i18n_translate()` |
|
||
| USER CONFIGURATION | 403–600 | 50+ tunable parameters |
|
||
| Crate configuration | 601–1 200 | `ctld.spawnableCrates`, AA system templates |
|
||
| Public API functions | 1 200–1 950 | Functions usable from DO SCRIPT triggers |
|
||
| Core gameplay logic | 1 950–4 600 | Troops, vehicles, crates, FOBs, beacons |
|
||
| JTAC subsystem | 4 600–7 000 | Targeting, lasing, IR points, F10 menus |
|
||
| AI processing + menus | 7 000–8 200 | AI auto-load/unload, F10 menu building |
|
||
| `ctld.initialize()` | 8 190–8 400 | State tables init, zone parsing |
|
||
| Event handler + tools | 8 400–8 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.
|