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

Overview

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

Once loaded by DCS at start, LotAtc will load the 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 authentication requests.

When a client tries to connect to the server, if it is accepted (see authentication), 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, the next client will just join it
  • In MonoRadar mode, a SimUnit is created per radar with a controller (it is freed if there is 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 it.

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 the server (the client has not changed anything yet). The server validates (or not) this request and sends an 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-frame, but that is not exactly true. With 70 frames per second for example, it is too many calls for LotAtc needs.

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

In the config.lua, the following are defined:

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

For example:

A mission with 176 units will be split into 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 are a lot of units/groups (for example 500 units so 10 groups), the time between each 2 groups should be 2s/10=200ms. 200ms is less than minimum_frame_update, so LotAtc will automatically decide to increase update_time to 3s in order to preserve minimum_frame_update time between 2 groups. It also avoids 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 will be needed on the server side.

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

Internal testing

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

Optimization is continuous work, each release gains some performance improvements, which is very important with DCS that allows more units now. Moreover, by adding new features and more simulation into LotAtc, performance has to stay the same and even get better.

Updated: