Jump to content

Finding new functionality in Lua aircraft mods


Recommended Posts

Here are some tips&tricks I've developed over the past year to help figure out functionality that is available to Lua aircraft mods in DCS (but not commonly available in internet/forum searches or Beginners Guide to DCS Aircraft Modules), maybe this will help others on this path. Please share your tips&tricks too!


  • search all DCS DLLs for strings (using e.g. strings utility), especially cockpitbase.dll. This can give many false leads, but also some good ones.
  • DLL Export Viewer on DCS DLLs, especially cockpitbase.dll. Learn to see what the Lua functions typically look like, so you can find others you didn't know about.
  • inputenum.txt (but numerically sorted by value instead)
  • Look at all Lua files of all other modules. Can install modules with these instructions. Can often find useful info w.r.t. gauges, switches, HUD drawing in these files, and also their default.lua files (inputs for keyb/joystick) sometimes give interesting clues (related to inputenum above). Their device_init.lua files can also give some useful info.
  • print_message_to_user() and log.info()/log.alert() etc. functions (latter makes entries in Users/username/Saved Games/DCS/Logs/DCS.log)
  • Dumping Lua global (_G) and metatables (see code further down)
  • DCS modelviewer.exe in bin directory
  • EDM arg extractor, handy together with modelviewer for figuring out how other modules do certain animation effects
  • The Mods How To section (where this post lives) has lots of useful things, can often be found on google too though



Some basic common recursive table dumping code that you can include in other Lua files:

Function to recursively dump a table to a string:
Usage (e.g. to gain introspection into _G table):
local lines=strsplit("\n",str)
for k,v in ipairs(lines) do
function basic_dump (o)
 if type(o) == "number" then
   return tostring(o)
 elseif type(o) == "string" then
   return string.format("%q", o)
 else -- nil, boolean, function, userdata, thread; assume it can be converted to a string
   return tostring(o)

function dump (name, value, saved, result)
 seen = seen or {}       -- initial value
 result = result or ""
 result=result..name.." = "
 if type(value) ~= "table" then
 elseif type(value) == "table" then
   if seen[value] then    -- value already saved?
     result=result.."->"..seen[value].."\n"  -- use its previous name
     seen[value] = name   -- save name for next time
     result=result.."{}\n"     -- create a new table
     for k,v in pairs(value) do      -- save its fields
       local fieldname = string.format("%s[%s]", name,
       if fieldname~="_G[\"seen\"]" then
         result=dump(fieldname, v, seen, result)
 return result

function strsplit(delimiter, text)
 local list = {}
 local pos = 1
 if string.find("", delimiter, 1) then
   return {}
 while 1 do
   local first, last = string.find(text, delimiter, pos)
   if first then -- found?
     table.insert(list, string.sub(text, pos, first-1))
     pos = last+1
     table.insert(list, string.sub(text, pos))
 return list


Dumping _G with above, was able to find get_clickable_element_reference() and a bunch of other very useful

directly or indirectly.


Can also dump metatable of any Lua device from inside to find functions that device exposes, e.g.

local dev = GetSelf()
str=dump("GetSelf meta",m)
local lines=strsplit("\n",str)
for k,v in ipairs(lines) do


Finding new interesting sounding function names is only half the battle, you need to often guess the parameters, that can often be quite time consuming and frustrating.

  • Like 1


Heatblur Simulations


Link to comment
Share on other sites

just to make it a little easyer, in DLLs, look for functions like


int cockpit::avSimpleElectricSystem::l_AC_Generator_1_on(struct lua_State *) 

(its L_AC_Gen...)


which is callable as "GetDevice(x):AC_Generator_1_on(x)" in the Lua enviroment


sidenote, the complete Cockpitbase.dll dump is nearly 6000 lines ;)

'controlling' the Ka50 feels like a discussion with the Autopilot and trim system about the flight direction.

Link to comment
Share on other sites

If you're interested in calling dll functions from C++, I often use dependency walker as well to see exported functions and their prototypes. As far as I know, only static functions, usually utility functions, without obscure/unique data struct parameters will be directly callable by address in this manner.


Another way to see exported data if you're familiar with unix systems or have cygwin installed is to use the "strings" and "grep" or "less" commands like this:


strings "CockpitBase.dll" | less




strings "CockpitBase.dll" | grep "<search_term>"

Edited by SilentEagle
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...