{"id":30855311,"url":"https://github.com/samiahola/dcs-jupyter","last_synced_at":"2025-09-07T11:05:03.253Z","repository":{"id":305710882,"uuid":"1021348313","full_name":"SamiAhola/dcs-jupyter","owner":"SamiAhola","description":"Jupyter kernel for live connection to DCS (Digital Combat Simulator) scripting environment","archived":false,"fork":false,"pushed_at":"2025-08-15T06:07:31.000Z","size":600,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-04T10:57:18.541Z","etag":null,"topics":["dcs","flight-simulation","jupyter","lua"],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SamiAhola.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-17T09:06:25.000Z","updated_at":"2025-08-11T10:00:49.000Z","dependencies_parsed_at":"2025-07-21T17:30:15.207Z","dependency_job_id":"31205047-e0ee-41c4-8ca7-471a5f5d1d4d","html_url":"https://github.com/SamiAhola/dcs-jupyter","commit_stats":null,"previous_names":["samiahola/dcs-jupyter"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/SamiAhola/dcs-jupyter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamiAhola%2Fdcs-jupyter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamiAhola%2Fdcs-jupyter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamiAhola%2Fdcs-jupyter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamiAhola%2Fdcs-jupyter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SamiAhola","download_url":"https://codeload.github.com/SamiAhola/dcs-jupyter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamiAhola%2Fdcs-jupyter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274026718,"owners_count":25209740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dcs","flight-simulation","jupyter","lua"],"created_at":"2025-09-07T11:04:40.000Z","updated_at":"2025-09-07T11:05:03.244Z","avatar_url":"https://github.com/SamiAhola.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DCS Jupyter\n\nA [Jupyter](https://jupyter.org/) kernel for live connection to DCS (Digital Combat Simulator) scripting environment. Execute [Lua](https://www.lua.org/) code in Jupyter notebooks that communicates directly with a running DCS mission via UDP socket connection.\n\n## Features\n\n- Execute Lua code directly in DCS from Jupyter notebooks\n- **Jupyter Magic Commands** (`%dcs` and `%%dcs`) for seamless integration with Python notebooks ([demo notebook](https://github.com/SamiAhola/dcs-jupyter/blob/main/example/notebook/test_magic.ipynb))\n- **Standalone `DcsConnection` class** for use in Python scripts outside Jupyter\n- Real-time communication with running DCS missions\n- Support for both [Jupyter Console](https://jupyter-console.readthedocs.io/) and [JupyterLab](https://jupyterlab.readthedocs.io/)\n- Easy installation and kernel management\n- Cross-platform support (Windows, Linux, macOS)\n\n## Installation\n\n### Requirements\n- Python 3.11 or higher\n- [DCS World](https://www.digitalcombatsimulator.com/) (Digital Combat Simulator)\n\n### Install Dependencies (Windows)\n\nIf you don't have Python and [pipx](https://pipx.pypa.io/) installed:\n\n1. **Install Python:**\n   - Download Python 3.11+ from [python.org](https://www.python.org/downloads/)\n   - During installation, check \"Add Python to PATH\"\n   - Verify installation in Command Prompt: `python --version`\n\n2. **Install pipx:**\n   Open Command Prompt and run:\n   ```cmd\n   python -m pip install --user pipx\n   python -m pipx ensurepath\n   ```\n   - Restart Command Prompt after installation\n   - Verify installation: `pipx --version`\n\n### Install Package\n\n```bash\n# Basic installation\npipx install dcs-jupyter\n\n# With JupyterLab and extras (vim bindings, rich output, Dracula theme)\npipx install \"dcs-jupyter[lab]\"\n```\n\nAlso available via [`pip`](https://pip.pypa.io/) or [`uv`](https://docs.astral.sh/uv/) package managers.\n\n## Basic Setup (Windows)\n\n### 1. Patch DCS\n\nIn `dcs_install_dir/Scripts/MissionScripting.lua`, find this section (around line 16):\n\n```lua\ndo\n  sanitizeModule('os')\n  sanitizeModule('io')\n  sanitizeModule('lfs')\n  _G['require'] = nil\n  _G['loadlib'] = nil\n  _G['package'] = nil\nend\n```\n\n**Add this code BEFORE the above `do` block:**\n\n```lua\n-- Initialize DCS Jupyter before security restrictions\nif not _G['dcs_jupyter_udp'] then\n    package.path = package.path..\";.\\\\LuaSocket\\\\?.lua\"\n    package.cpath = package.cpath..\";.\\\\LuaSocket\\\\?.dll\"\n    local socket = require(\"socket\")\n    local udp = assert(socket.udp())\n    assert(udp:settimeout(0))\n    assert(udp:setsockname(\"127.0.0.1\", 8042))\n    _G['dcs_jupyter_udp'] = udp\n    \n    -- Pre-store DCS user directory for script loading\n    local lfs = require(\"lfs\")\n    _G['dcs_jupyter_user_dir'] = lfs.writedir()\nend\n```\n\n**Leave the original `do` block unchanged.** This maintains DCS security while enabling the kernel connection.\n\n### 2. Install DCS Plugin\n\n**Simple method** (recommended for most users):\n1. Download the [`jupyter_kernel_connection.lua`](https://raw.githubusercontent.com/SamiAhola/dcs-jupyter/main/dcs_plugin/jupyter_kernel_connection.lua) file\n2. Open Mission Editor → Triggers → New Trigger\n3. Set Event: Mission Start, Action: Do Script\n4. Copy the entire file contents into the text box\n\nThat's it! Your mission now has Jupyter support.\n\n\u003cdetails\u003e\n\u003csummary\u003e🔧 Alternative installation methods (click to expand)\u003c/summary\u003e\n\n**Method B: Do Script File action**\n- Place `jupyter_kernel_connection.lua` anywhere\n- Mission Editor → Triggers → New Trigger → Do Script File\n- Select the script file\n- *Note: File is saved internally to mission*\n\n**Method C: Dynamic loading (advanced)**\n- Place script in your DCS user directory (under 'Saved Games')\n- Use: `assert(loadfile(_G['dcs_jupyter_user_dir'] .. \"/Scripts/jupyter_kernel_connection.lua\"))()`\n- *Advantage: Reloads script on every mission restart*\n\n\u003c/details\u003e\n\n### 3. Configure Network Settings\n\nThe kernel uses localhost (`127.0.0.1:8042`) by default, which works for native Windows installations.\n\n## Usage\n\n### Quick Start with Console\n\n```bash\ndcs-jupyter-console\n```\n\nAutomatically installs the DCS kernel if needed and starts Jupyter Console with DCS Lua kernel.\n\n### Start with JupyterLab\n\n```bash\ndcs-jupyter-lab\n```\n\nAutomatically installs the DCS kernel if needed and starts JupyterLab.\n\n\n## Examples\n\n### Download Example Notebooks\n\nGet started with these example notebooks:\n\n- **Jupyter Magic Commands Demo** - Using `%dcs` and `%%dcs` magic in Python notebooks\n  - [Download](https://raw.githubusercontent.com/SamiAhola/dcs-jupyter/main/example/notebook/test_magic.ipynb) | [View with outputs](https://github.com/SamiAhola/dcs-jupyter/blob/main/example/notebook/test_magic.ipynb)\n- **Airport Terrain Demo** - Explore DCS terrain and airfield data\n  - [Download](https://raw.githubusercontent.com/SamiAhola/dcs-jupyter/main/example/notebook/airport_terrain_demo.ipynb) | [View with outputs](https://github.com/SamiAhola/dcs-jupyter/blob/main/example/notebook/airport_terrain_demo.ipynb)\n- **Vehicle Control** - Control units and vehicles in DCS\n  - [Download](https://raw.githubusercontent.com/SamiAhola/dcs-jupyter/main/example/notebook/vehicle_control.ipynb) | [View with outputs](https://github.com/SamiAhola/dcs-jupyter/blob/main/example/notebook/vehicle_control.ipynb)\n\n*Right-click \"Download\" links and select \"Save link as...\" to save to your computer.*\n\n### Basic Usage\n\n#### Python Notebook Usage\n\nLoad the magic extension in your Python notebook:\n```python\n%load_ext dcs_jupyter.magic\n# or to reload: %reload_ext dcs_jupyter.magic\n```\n\nThen use magic commands to execute Lua code in DCS:\n```python\n# Single line magic command\n%dcs trigger.action.outText(\"Hello from magic command!\", 5)\n\n# Multi-line magic command\n%%dcs\nlocal currentTime = timer.getTime()\ntrigger.action.outText(\"Mission time: \" .. math.floor(currentTime) .. \" seconds\", 5)\n```\n\n#### DCS Lua Kernel Usage\n\nWhen using the DCS Lua kernel directly, execute Lua code:\n```lua\n-- Display message in DCS (visible in game)\ntrigger.action.outText(\"Hello from DCS Jupyter!\", 10)\n\n-- Get current mission time and display it\nlocal currentTime = timer.getTime()\ntrigger.action.outText(\"Mission time: \" .. math.floor(currentTime) .. \" seconds\", 5)\n\n-- Create smoke at a specific location\nlocal smokePos = {x = 0, y = 0, z = 0}  -- Adjust coordinates as needed\ntrigger.action.smoke(smokePos, trigger.smokeColor.Red)\n\n-- Get all red coalition groups\nlocal redGroups = coalition.getGroups(coalition.side.RED)\ntrigger.action.outText(\"Red coalition has \" .. #redGroups .. \" groups\", 8)\n\n```\nReturn current mission time:\n```lua\nreturn timer.getTime()\n```\n\nGet structured data for analysis:\n```lua\n-- Get all airfields with their properties\nlocal airfields = {}\nfor coalition_id = 0, 2 do\n    local airfield_list = coalition.getAirbases(coalition_id)\n    for _, airfield in pairs(airfield_list) do\n        airfields[#airfields + 1] = {\n            name = airfield:getName(),\n            coalition = coalition_id,\n            position = airfield:getPosition().p,\n            category = airfield:getDesc().category\n        }\n    end\nend\nreturn net.lua2json(airfields)\n```\n\n## Configuration\n\n**Default settings:** `127.0.0.1:8042`, 10 second timeout. See Advanced Setup for customization.\n\n## Troubleshooting\n\n### Connection Issues\n\n- Ensure DCS is running with the Lua plugin loaded\n- Check firewall settings allow UDP traffic on port 8042\n- Verify IP address is correct (127.0.0.1 for Windows, host IP for WSL2)\n\n### Kernel Not Found\n\nIf the kernel isn't recognized:\n```bash\n# Reinstall kernel\njupyter kernelspec uninstall dcs-lua\ndcs-jupyter-console  # Will reinstall automatically\n```\n\n### WSL2 Connection Problems\n\n- WSL2 users need to modify IP addresses manually (see Advanced Setup)\n- Use Windows host IP address instead of localhost\n- Consider using native Windows installation for simpler setup\n\n## Advanced Setup\n\n### WSL2 Users\n\nThe 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:\n\n1. **Find your WSL2 IP address:** `ip addr` - look for the `inet` address on your main interface (usually `eth0`)\n   - **Note:** This is primarily for mirrored networking mode. In older NAT mode, the networking setup may differ.\n2. **Edit IP in the patching code:** Replace `127.0.0.1` with your WSL2 IP address in the MissionScripting.lua patch above\n3. **Edit IP in kernel:** `src/dcs_jupyter/kernel.py`: `SOCKET_ADDR = 'YOUR_WSL2_IP'`\n4. **Configure Windows Firewall** for UDP port 8042 (might be needed)\n\n### Manual Kernel Installation\n\n```bash\n# Install kernel manually\njupyter kernelspec install kernel_spec/dcs-lua --user\n\n# List installed kernels\njupyter kernelspec list\n\n# Start Jupyter with DCS kernel\njupyter console --kernel=dcs-lua\n```\n\n### Custom IP/Port Configuration\n\nEdit `SOCKET_ADDR` and `PORT` constants in both `src/dcs_jupyter/kernel.py` and `dcs_plugin/jupyter_kernel_connection.lua` with identical values.\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Support\n\nFor issues and questions:\n- Check the troubleshooting section above\n- Open an issue on GitHub with detailed information about your problem\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamiahola%2Fdcs-jupyter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamiahola%2Fdcs-jupyter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamiahola%2Fdcs-jupyter/lists"}