Jupyter kernel for live connection to DCS (Digital Combat Simulator) scripting environment
Project description
DCS Jupyter
A Jupyter kernel for live connection to DCS (Digital Combat Simulator) scripting environment. Execute Lua code in Jupyter notebooks that communicates directly with a running DCS mission via UDP socket connection.
Features
- Execute Lua code directly in DCS from Jupyter notebooks
- Jupyter Magic Commands (
%dcsand%%dcs) for seamless integration with Python notebooks (demo notebook) - Standalone
DcsConnectionclass for use in Python scripts outside Jupyter - Real-time communication with running DCS missions
- Support for both Jupyter Console and JupyterLab
- Easy installation and kernel management
- Cross-platform support (Windows, Linux, macOS)
Installation
Requirements
- Python 3.11 or higher
- DCS World (Digital Combat Simulator)
Install Dependencies (Windows)
If you don't have Python and pipx installed:
-
Install Python:
- Download Python 3.11+ from python.org
- During installation, check "Add Python to PATH"
- Verify installation in Command Prompt:
python --version
-
Install pipx: Open Command Prompt and run:
python -m pip install --user pipx python -m pipx ensurepath
- Restart Command Prompt after installation
- Verify installation:
pipx --version
Install Package
# Basic installation
pipx install dcs-jupyter
# With JupyterLab and extras (vim bindings, rich output, Dracula theme)
pipx install "dcs-jupyter[lab]"
Also available via pip or uv package managers.
Basic Setup (Windows)
1. Patch DCS
In dcs_install_dir/Scripts/MissionScripting.lua, find this section (around line 16):
do
sanitizeModule('os')
sanitizeModule('io')
sanitizeModule('lfs')
_G['require'] = nil
_G['loadlib'] = nil
_G['package'] = nil
end
Add this code BEFORE the above do block:
-- Initialize DCS Jupyter before security restrictions
if not _G['dcs_jupyter_udp'] then
package.path = package.path..";.\\LuaSocket\\?.lua"
package.cpath = package.cpath..";.\\LuaSocket\\?.dll"
local socket = require("socket")
local udp = assert(socket.udp())
assert(udp:settimeout(0))
assert(udp:setsockname("127.0.0.1", 8042))
_G['dcs_jupyter_udp'] = udp
-- Pre-store DCS user directory for script loading
local lfs = require("lfs")
_G['dcs_jupyter_user_dir'] = lfs.writedir()
end
Leave the original do block unchanged. This maintains DCS security while enabling the kernel connection.
2. Install DCS Plugin
Simple method (recommended for most users):
- Download the
jupyter_kernel_connection.luafile - Open Mission Editor → Triggers → New Trigger
- Set Event: Mission Start, Action: Do Script
- Copy the entire file contents into the text box
That's it! Your mission now has Jupyter support.
🔧 Alternative installation methods (click to expand)
Method B: Do Script File action
- Place
jupyter_kernel_connection.luaanywhere - Mission Editor → Triggers → New Trigger → Do Script File
- Select the script file
- Note: File is saved internally to mission
Method C: Dynamic loading (advanced)
- Place script in your DCS user directory (under 'Saved Games')
- Use:
assert(loadfile(_G['dcs_jupyter_user_dir'] .. "/Scripts/jupyter_kernel_connection.lua"))() - Advantage: Reloads script on every mission restart
3. Configure Network Settings
The kernel uses localhost (127.0.0.1:8042) by default, which works for native Windows installations.
Usage
Quick Start with Console
dcs-jupyter-console
Automatically installs the DCS kernel if needed and starts Jupyter Console with DCS Lua kernel.
Start with JupyterLab
dcs-jupyter-lab
Automatically installs the DCS kernel if needed and starts JupyterLab.
Examples
Download Example Notebooks
Get started with these example notebooks:
- Jupyter Magic Commands Demo - Using
%dcsand%%dcsmagic in Python notebooks - Airport Terrain Demo - Explore DCS terrain and airfield data
- Vehicle Control - Control units and vehicles in DCS
Right-click "Download" links and select "Save link as..." to save to your computer.
Basic Usage
Python Notebook Usage
Load the magic extension in your Python notebook:
%load_ext dcs_jupyter.magic
# or to reload: %reload_ext dcs_jupyter.magic
Then use magic commands to execute Lua code in DCS:
# Single line magic command
%dcs trigger.action.outText("Hello from magic command!", 5)
# Multi-line magic command
%%dcs
local currentTime = timer.getTime()
trigger.action.outText("Mission time: " .. math.floor(currentTime) .. " seconds", 5)
DCS Lua Kernel Usage
When using the DCS Lua kernel directly, execute Lua code:
-- Display message in DCS (visible in game)
trigger.action.outText("Hello from DCS Jupyter!", 10)
-- Get current mission time and display it
local currentTime = timer.getTime()
trigger.action.outText("Mission time: " .. math.floor(currentTime) .. " seconds", 5)
-- Create smoke at a specific location
local smokePos = {x = 0, y = 0, z = 0} -- Adjust coordinates as needed
trigger.action.smoke(smokePos, trigger.smokeColor.Red)
-- Get all red coalition groups
local redGroups = coalition.getGroups(coalition.side.RED)
trigger.action.outText("Red coalition has " .. #redGroups .. " groups", 8)
Return current mission time:
return timer.getTime()
Get structured data for analysis:
-- Get all airfields with their properties
local airfields = {}
for coalition_id = 0, 2 do
local airfield_list = coalition.getAirbases(coalition_id)
for _, airfield in pairs(airfield_list) do
airfields[#airfields + 1] = {
name = airfield:getName(),
coalition = coalition_id,
position = airfield:getPosition().p,
category = airfield:getDesc().category
}
end
end
return net.lua2json(airfields)
Configuration
Default settings: 127.0.0.1:8042, 10 second timeout. See Advanced Setup for customization.
Troubleshooting
Connection Issues
- Ensure DCS is running with the Lua plugin loaded
- Check firewall settings allow UDP traffic on port 8042
- Verify IP address is correct (127.0.0.1 for Windows, host IP for WSL2)
Kernel Not Found
If the kernel isn't recognized:
# Reinstall kernel
jupyter kernelspec uninstall dcs-lua
dcs-jupyter-console # Will reinstall automatically
WSL2 Connection Problems
- WSL2 users need to modify IP addresses manually (see Advanced Setup)
- Use Windows host IP address instead of localhost
- Consider using native Windows installation for simpler setup
Advanced Setup
WSL2 Users
The default localhost configuration should work for most WSL2 setups, especially with mirrored networking mode (WSL2 default in newer versions). If you experience connection issues, you may need to use your WSL2 IP address:
- Find your WSL2 IP address:
ip addr- look for theinetaddress on your main interface (usuallyeth0)- Note: This is primarily for mirrored networking mode. In older NAT mode, the networking setup may differ.
- Edit IP in the patching code: Replace
127.0.0.1with your WSL2 IP address in the MissionScripting.lua patch above - Edit IP in kernel:
src/dcs_jupyter/kernel.py:SOCKET_ADDR = 'YOUR_WSL2_IP' - Configure Windows Firewall for UDP port 8042 (might be needed)
Manual Kernel Installation
# Install kernel manually
jupyter kernelspec install kernel_spec/dcs-lua --user
# List installed kernels
jupyter kernelspec list
# Start Jupyter with DCS kernel
jupyter console --kernel=dcs-lua
Custom IP/Port Configuration
Edit SOCKET_ADDR and PORT constants in both src/dcs_jupyter/kernel.py and dcs_plugin/jupyter_kernel_connection.lua with identical values.
License
MIT License - see LICENSE file for details.
Support
For issues and questions:
- Check the troubleshooting section above
- Open an issue on GitHub with detailed information about your problem
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dcs_jupyter-0.1.6.tar.gz.
File metadata
- Download URL: dcs_jupyter-0.1.6.tar.gz
- Upload date:
- Size: 87.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3378409bf7d1a0ec23ce8b71e013e2c417c7fa4dc6d9e559ebcc02a838c320af
|
|
| MD5 |
f18e377ef177cbbf4b9a903680088d1d
|
|
| BLAKE2b-256 |
54b1a105a11615152dd603e9de7c7aeaf46b698558cccb9cd2bf4b037863c474
|
Provenance
The following attestation bundles were made for dcs_jupyter-0.1.6.tar.gz:
Publisher:
publish.yml on SamiAhola/dcs-jupyter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dcs_jupyter-0.1.6.tar.gz -
Subject digest:
3378409bf7d1a0ec23ce8b71e013e2c417c7fa4dc6d9e559ebcc02a838c320af - Sigstore transparency entry: 298906059
- Sigstore integration time:
-
Permalink:
SamiAhola/dcs-jupyter@50bf850e0e9a140da6de030bc1808451d502d26f -
Branch / Tag:
refs/tags/v0.1.6 - Owner: https://github.com/SamiAhola
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@50bf850e0e9a140da6de030bc1808451d502d26f -
Trigger Event:
push
-
Statement type:
File details
Details for the file dcs_jupyter-0.1.6-py3-none-any.whl.
File metadata
- Download URL: dcs_jupyter-0.1.6-py3-none-any.whl
- Upload date:
- Size: 10.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10b37960437d9d8eaaa8843dd1b86f24b014200064d05a7609459480e10f1b20
|
|
| MD5 |
e364e93e08952072543dee854ee1c806
|
|
| BLAKE2b-256 |
92ad48b5524d3e445bf91a39c2500fe70c5c80fa5e57c8fe16e7abe0c40b8e75
|
Provenance
The following attestation bundles were made for dcs_jupyter-0.1.6-py3-none-any.whl:
Publisher:
publish.yml on SamiAhola/dcs-jupyter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dcs_jupyter-0.1.6-py3-none-any.whl -
Subject digest:
10b37960437d9d8eaaa8843dd1b86f24b014200064d05a7609459480e10f1b20 - Sigstore transparency entry: 298906083
- Sigstore integration time:
-
Permalink:
SamiAhola/dcs-jupyter@50bf850e0e9a140da6de030bc1808451d502d26f -
Branch / Tag:
refs/tags/v0.1.6 - Owner: https://github.com/SamiAhola
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@50bf850e0e9a140da6de030bc1808451d502d26f -
Trigger Event:
push
-
Statement type: