This article describes more technically how LotAtc server works with DCS.


LotAtc Server is a LUA library written in C++ (using Qt5) loaded by DCS as a mod (as any other DCS Mods).

Once loaded by DCS at start, LotAtc will load mission and DCS database to extract all data needed to build the tactical view (item, name, position, detection rangeā€¦). Every characteristic comes from DCS so it is coherent with DCS pilots.

When LotAtc Server is ready, LotAtc can receive LotAtc client authentification requests.

When a client tries to connect to server, if it is accepted (see authentification), LotAtc Server will create a Simulation Unit (SimUnit) (or get one if already running).

  • In global mode, there is a SimUnit per coalition. The first client of each coalition will create it, next client will just join it
  • In MonoRadar mode, a SimUnit is created per radar with a controller (it is free if no more controller)

Each SimUnit will compute all units to build the tactical view in its own thread and send data to each client connected to him.

graph LR LoServA-->LoClientB1[Client Blue 1] LoServA-->LoClientB2[Client Blue 2] LoServB-->LoClientR1[Client Red 1] subgraph dcs[ ] Export[DCS Export]-->LoLua[LotAtc LUA] db[DCS Database]-->LoLua gui[DCS GUI]-->LoLua rt[DCS Simu]-->LoLua cfg[DCS Config]-->LoLua lcfg[LotAtc Config]-->LoLua subgraph lo[LotAtc Server] LoLua-->SimUA[SimuUnit Blue] SimUA-->LoServA[Client Server Blue] LoLua-->SimUB[SimuUnit Red] SimUB-->LoServB[Client Server Red] end end style dcs fill:#6FDBFF,stroke:#C0C0C0,stroke-width:2px style lo fill:#C4FFC4,stroke:#C0C0C0,stroke-width:2px

Integration in DCS runtime

Here is a classic interaction of DCS/LotAtc.

On each inter-frame of DCS, LotAtc Lua is called.

LotAtc gets unit update (status/position) and returns chats from LotAtc that will be send by DCS afterwards to pilots. This is the only blocking DCS part and takes less than 1ms. Unit updates are sent internally to each SimUnit which compute to build the view. Once done, results are sent to all clients asynchronously.

Radar computation and client networking take more time (between 1ms to 100ms on very heavy mission) but are done in another thread and does not block DCS. If a DCS update is coming and previous update is not already sent, LotAtc will skip computation of this new one, this is an automatic throttling.

All dash lines are asynchronous, all plain lines are synchronous

sequenceDiagram loop Every frame DCS->>+Lo: get all units Lo-->>SimUnit: update units activate SimUnit Lo->>-DCS: send chats end SimUnit-->>Clients: send update deactivate SimUnit

If a client changes a symbol for example, the request is sent to server (client has changes anything yet). The server validates (or not) this request and send update to all clients.

sequenceDiagram participant SimUnit participant Clients Clients-->>SimUnit: ask symbol update SimUnit-->>Clients: symbol update

More details on update units processing

Previously we said that LotAtc updates all units on each inter-frames, that is not exactly true. With 70 frames per second for example, it is too much call for LotAtc needs.

In reality, LotAtc will split units in groups, each group will be updated in an inter-frame, reducing impact on framerate.

In the config.lua, are defined :

  • update_time (2 seconds by default). It gives as instructions to update each units every 2 seconds.
  • max_loop_unit (50 by default) represents the number of each units in each group.
  • minimum_frame_update (0.3 second by default) minimum time between 2 groups

For example:

A mission with 176 units will be split in 4 groups A, B, C and D that will be updated every 500 ms (2s/4).

graph LR subgraph f1[2s] ga[Group A] -- 500ms --> gb[Group B] gb -- 500ms --> gc[Group C] gc -- 500ms --> gd[Group D] end

In the case that there is lot of units/groups (for example 500 units so 10 groups), time between each 2 groups should be 2s/10=200ms. 200ms is less than minimum_frame_update, LotAtc will decide to increase automatically update_time to 3s in order to preserve minimum_frame_update time between 2 groups. It also avoid too much DCS CPU use.

graph LR subgraph f1[3s] ga[Group A] -- 300ms --> gb[Group B] gb -.-> gi[Group I] gi -- 300ms --> gj[Group J] end

Server admin settings?

Depending on mission needs, values can be changed to adapt, you can decrease minimum_frame_update and/or update_time to have a better framerate on LotAtc client, but more CPU needed on server side.

They are accessible in config.lua and can be customized through config.custom.lua.

Internal testing

During development, LotAtc can dump lot of information on its use : DCS blocking time, filtering/radar/relief computation time. This allows to follow the performances of all algorithms during dev phase.

Optimisation is a continuous work, each release gain some performances, it is very important with DCS that allows more units now. Moreover, by adding new features and more simulation into LotAtc, performances have to stay the same and even better..