Lua Plugin Debugging — LAZY=FULL Root Cause & Fix

# Lua Plugin Debugging — LAZY=FULL Root Cause & Fix

> **Status**: Root cause identified, fix NOT yet applied
> **Date**: 2026-06-03
> **Plugin path**: `<AC>/apps/lua/ac-telemetry-plugin/`

---

## The Problem

The Lua plugin (port 5005) never executed a single line of code across two sessions. Zero bytes received. The script was never loaded by CSP.

---

## Root Cause: `LAZY = FULL` in manifest.ini

CSP's **App Shelf** (built-in CSP app by x4fab) documents the LAZY modes in its own `manifest.ini`:

```ini
LAZY = FULL  ; Possible values:
; • NONE (or 0, default): load script when AC is loading, run until closed
; • PARTIAL (or 1): load script only when app is first opened, keep running
; • FULL (or 2): load script when app is opened, unload when all windows closed
```

Our `manifest.ini` has `LAZY = FULL`. This means CSP parses the manifest at startup (creates window slot, adds to taskbar) but **never executes `main.lua` until the user clicks the app icon in-game**. The user never clicked it → no Lua code ever ran.

---

## Evidence Chain

1. **CSP log**: `App is loaded: '...lua/ac-telemetry-plugin', impl.: 0000000000000000, windows: 1` — `impl.: 0000000000000000` means no Lua code executed
2. **Zero `ac.log()` messages**: Three diagnostic checkpoints at module level in `src/telemetry.lua` — none appeared in any log file
3. **No app state file**: `cfg/extension/state/lua/app/` contains only `AppShelf.ini`
4. **imgui settings**: `IMGUI_LUA_actelemetryplugin_main=60,60,366,164` — window slot allocated but never rendered (366×164 is a default imgui allocation, not the manifest's `SIZE = 160, 30`)

---

## The Fix

Change `manifest.ini` line 13:
```diff
- LAZY = FULL
+ LAZY = NONE
```
Or remove the `[CORE]` section's `LAZY` line entirely (NONE is the default).

---

## After Fix: Secondary Concern

After fixing LAZY, `require("socket")` may still fail if LuaSocket is unavailable in CSP's sandboxed Lua environment. Three diagnostic `ac.log()` checkpoints are in place to confirm:

1. `"[ACTelemetry] Before require('socket')"` — if this appears but next doesn't → LuaSocket unavailable
2. `"[ACTelemetry] require('socket') succeeded"` — if this appears but next doesn't → `socket.udp()` missing
3. `"[ACTelemetry] socket.udp() succeeded"` — if this appears → plugin works end-to-end

If LuaSocket is unavailable, alternatives:
- CSP's native networking: `ac.connect()`, `ac.connectUDP()`, `web.request()`
- CSP's `ac.store()` / `ac.storage()` for file-based data exchange
- Named pipe via `io.open()` on a FIFO

---

## Window Visibility

With `LAZY = NONE`, the floating title bar will appear at session start (`VISIBLE = 1`). For a background telemetry sender, consider setting `VISIBLE = 0` to hide it (script still runs), or keep `VISIBLE = 1` as a visual indicator that the plugin is active.

---

## Cross-Reference

- **AC protocol spec**: [Assetto Corsa — UDP Telemetry Protocol Specification](joplin://aed9f3be040943048273a16e05a8100f) (Feed C section)

---

*Originally part of: Telemetry Feed Analysis Session 2026-06-03*
*Remaining KSUDP/Telemetry Tool findings moved to the AC protocol spec note*

id: 395bc805650d44b6bfec423ca095ed64
parent_id: 94aa3283ead4477d8449e324a27eb3d0
created_time: 2026-06-03T15:37:49.270Z
updated_time: 2026-06-06T08:27:31.508Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1780501069270
user_created_time: 2026-06-03T15:37:49.270Z
user_updated_time: 2026-06-06T08:27:31.508Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
type_: 1