Pelican is a modular library for DCS World, focused on enabling external integrations via an embedded HTTP and WebSocket server. It allows developers to build rich interfaces and tools that interact with DCS in real-time, making it ideal for dashboards, companion apps, telemetry capture, automation systems, and more.
Pelican is designed for use in both the Mission Scripting Environment (MSE) and the GUI Scripting Environment within DCS world.
Pelican is distributed as a DLL
file. To install:
Place the DLL into the following directory:
%USERPROFILE%\Saved Games\DCS\Mods\tech\Pelican\bin
Replace Pelican
with the actual name of your mod if you want to isolate it from other usages, i.e. for Version
Pinning
or to avoid conflicts with other mods.
⚠️ Ensure that the directory structure matches your mod usage.
Pelican's setup process differs depending on the environment you're using.
Refer to the GUI Environment setup guide for detailed instructions on configuring Pelican for GUI scripting.
Refer to the Mission Scripting Environment setup guide for details on configuring Pelican in the MSE context.
If you're comfortable with DCS scripting, here's a simple setup example for both environments.
Place the following script in your DCS World Saved Games Scripts/Hooks folder:
-- %USERPROFILE%\Saved Games\DCS\Scripts\Hooks\PelicanTestGameGUI.lua
package.cpath = package.cpath .. ";" .. lfs.writedir() .. "\\Mods\\tech\\Pelican\\bin\\?.dll"
PELICAN = { logger_level = "debug" }
local status, ____pelican = pcall(require, "pelican")
if not status then
log.write("PELICAN", log.ERROR, "Failed to load Pelican: " .. tostring(____pelican))
return
else
log.write("PELICAN", log.INFO, "Pelican loaded successfully")
end
local logger = ____pelican.logger
local my_logger = logger.Logger.new("PELICAN.GUI")
my_logger:info("Pelican Running...")
local jsonrpc = ____pelican.jsonrpc
local server = jsonrpc.JsonRpcServer.new({ host = "127.0.0.1", port = 1234 })
local router = jsonrpc.JsonRpcRouter.new()
router:add_method(
"ping",
function(params)
local param = params[1]
return { message = "pong " .. param }
end
)
local user_callbacks = {}
function user_callbacks.onSimulationFrame()
local result, err = server:process_rpc(router)
if not result then
log.error("PELICAN", log.INFO, "RPC error: " .. tostring(err))
end
end
log.write("PELICAN", log.INFO, "Scheduling user callbacks for simulation frame processing...")
DCS.setUserCallbacks(user_callbacks)
-- %USERPROFILE%\Saved Games\DCS\Scripts\PelicanTestMission.lua
package.cpath = package.cpath .. ";" .. lfs.writedir() .. "\\Mods\\tech\\Pelican\\bin\\?.dll"
PELICAN = { logger_level = "debug" }
local status, ____pelican = pcall(require, "pelican")
if not status then
env.error("Failed to load Pelican: " .. tostring(____pelican))
return
else
env.info("Pelican loaded successfully")
end
local logger = ____pelican.logger
local my_logger = logger.Logger.new("PELICAN.MISSION")
my_logger:info("Pelican Running...")
local jsonrpc = ____pelican.jsonrpc
local server = jsonrpc.JsonRpcServer.new({ host = "127.0.0.1", port = 1235 })
local router = jsonrpc.JsonRpcRouter.new()
router:add_method(
"ping",
function(params)
local param = params[1]
return { message = "pong " .. param }
end
)
timer.scheduleFunction(
function(arg, time)
local result, err = server:process_rpc(router)
if not result then
env.error("RPC error: " .. tostring(err))
end
return timer.getTime() + .01
end,
nil,
timer.getTime() + .01
)
MissionScripting.lua
to load the script before sandbox restrictions are applied:-- C:\Program Files\Eagle Dynamics\DCS World\Scripts\MissionScripting.lua
--Initialization script for the Mission lua Environment (SSE)
dofile("Scripts/ScriptingSystem.lua")
dofile(lfs.writedir() .. "/Scripts/PelicanTestMission.lua")
--Sanitize Mission Scripting environment
--This makes unavailable some unsecure functions.
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
--You can remove the code below and make availble these functions at your own risk.
local function sanitizeModule(name)
_G[name] = nil
package.loaded[name] = nil
end
do
sanitizeModule("os")
sanitizeModule("io")
sanitizeModule("lfs")
_G["require"] = nil
_G["loadlib"] = nil
_G["package"] = nil
end
Alternatively, re-add the
require
,package
andlfs
functions bearing in mind the security implications of doing so.