The SOFLAM Integration Core mod is published under the Arma Public License (APL)Example code is free to useSuggestions: Discord to the author
For other modders
6. Testing and common errors New
Most errors in this area are silent. They look the same from outside (nothing happens, or a missile falls) and have different causes. This page is the order in which to check, and the log lines that tell the causes apart.
In plain wordsA checklist for a dedicated server test, and a table of symptoms with the log lines the Core really prints.
The test
- Run a real dedicated server and a separate client. In Workbench play client and server are one machine; ownership, relay and replication problems cannot show.
- Use two players when you can: one on the SOFLAM, one in the aircraft, far enough apart (try more than 1600 m).
- Use a code nobody else uses, and remove always-on test devices from the world. The nearest point with a matching code wins, whoever made it.
- Know the Core's net log.
GTG_LOG_NETZis a constant inGTG_SOFLAM_LaserDesignatorComponent.c, off in the published version. Switched on, every send and every effect prints a line like[GTG_SOFLAM][NETZ] SENDE Ziel anlegen | Rolle Proxy-ohne-Besitz | Code 1688 | Laser true; a SENDE without a followingWIRKTon the server is the signature of a dropped message. Build the same into your own components (and keep it off when you publish). - Look for lines that begin with
[GTG_SOFLAM]in both logs, server and client (script.log/console.log). Switch your own diagnostics off before you publish; a switch left on fills the log. - Test a late joiner: connect after the laser is on, and check that code and point arrive.
- Test the switch-off: laser off, leave the device, delete it. The point must disappear (at the latest after 5 seconds).
Symptom, cause, fix
| Symptom | Cause | Fix |
|---|---|---|
The script module does not compile; your mod references GTG_SOFLAM_* | The Core is not a dependency of your addon, or two copies of the Core are loaded. | Step 1. Use the GUID from step 2, and only one copy. |
Laser on, nothing arrives; the client log says [GTG_SOFLAM] Designator sendet ohne Besitz der Traegerentitaet UND ohne erreichbares Relais -- der Server verwirft diese Nachrichten (RplDocs: RPC invoke from the client, Not Owner -> Dropped). GTG_SOFLAM_Relay.Sender() liefert nichts: kein PlayerController oder kein gesteuerter Charakter. | The client does not own the device and has no character to relay through (“sends without owning the carrier entity and without a reachable relay”). Respawn window, spectator, or an entity not controlled by a player. | Make sure the player controls a character. For your own device build the relay of step 4. |
The same, but the Core's seeker says [GTG_SOFLAM] Suchkopf AGM sendet ohne Besitz der Traegerentitaet -- der Server verwirft diese Nachrichten. Siehe R1a in ENTWURFSVORGABEN.txt. (AGM is your m_sSeekerId) | The Core's seeker component sends its on/off state and code to the server from an entity the client does not own, and has no relay. | Switch it on and set the code on the server (or the owner), or use your own seeker (route A). |
The beam does not appear; [GTG_SOFLAM] Kein Strahl seit einer Sekunde: ... with one of five reasons | kein Designator an dieser Entitaet (the beam component has no designator next to it); Ersteller-Id ungueltig -- Traegerentitaet ohne RplComponent; Zielablage nicht gefunden (the registry system is not running: see below); kein Ziel unter dieser Ersteller-Id eingetragen (the message never arrived, ownership); Ziel eingetragen, aber ohne Position (created, never reported). | Each reason names its own place. Only reported when the same reason stands for a full second, so the normal start-up does not warn. |
[GTG_SOFLAM] Strahlkomponente ohne Licht-Prefab -- es wird kein Strahl gezeichnet. Feld 'Prefab der Lichtquelle' am Prefab setzen. | m_sBeamLightPrefab is empty on the beam component. | Set it to GTG_SOFLAM_IRLaserLight.et. |
GTG_SOFLAM_LaserTargetManager.GetInstance() is always null | The system needs one update point and an entry in the systems config. The Core has both; check that the Core is really loaded. | See the registry page. |
| A missile falls out of the sky after launch | Four causes that look the same: no code handed over, no point under the code, point outside the seeker's field of view, or the flight computer. Also the upper row of a pod (see aircraft). | Log which of the four (step 6); the AH-64 prints OHNE CODE, KEIN ZIEL ZUM CODE, AUSSERHALB SICHTFELD, GEFUEHRT. |
[GTG_AH64][TELEMETRIE] Start OHNE Codehalter ... / Start OHNE Suchkopf ... | The code holder component is missing from the turret prefab / the seeker component is missing from the ammo prefab. | Add them (step 1 and 4). |
| A missile turns towards the world origin for a moment | A point that was created and not yet reported sits at 0 0 0. | Skip the zero vector in your seeker. |
| Missiles steer to a point where nobody is lasing | A stale entry. The expiry removes it after 5 seconds without a report; if it lasts longer, something keeps reporting. | Find who reports; remove the entry when the operator leaves. |
| A laser point disappears after five seconds although the operator holds still | A publisher that only reports when the point moves. | Re-report at least every 2 seconds (step 4). |
| Targets vanish for the gunner when the operator is more than about 1600 m away | The operator's character is not streamed that far. | Stream characters to all clients (see far-away operators). |
| A code dial jumps by two | The change travels twice: through action replication and through the holder. | HasLocalEffectOnlyScript() returns true. |
| Dials do nothing in the cockpit | Wrong interaction context, or the holder is not found (it hangs on another entity). | Compare compartment name and context name (step 5); search the holder from the vehicle root. |
| Attack mode keeps the first value on the server | A listener on an input action that was renamed (WCS 8.3.0). | Input actions get renamed. |
| Thermal filter stays on the camera, the screen is white | The filter was cleared on a different camera id than it was set on. | The camera-id trap. |
| Everything in the log is quiet and still nothing works | Ownership: the message is dropped silently. | Who may send. |
NoteMeasure before you change. In nearly every one of these cases the first explanation was wrong, and the second came from the log.