{"id":19964133,"url":"https://github.com/overfl0/pythia","last_synced_at":"2025-08-22T00:43:13.685Z","repository":{"id":37686508,"uuid":"72045747","full_name":"overfl0/Pythia","owner":"overfl0","description":"An extension for Arma 3 that lets you write extensions in Python 3","archived":false,"fork":false,"pushed_at":"2024-12-04T13:09:56.000Z","size":6775,"stargazers_count":74,"open_issues_count":8,"forks_count":8,"subscribers_count":9,"default_branch":"next","last_synced_at":"2025-03-31T14:14:37.313Z","etag":null,"topics":["arma","arma3","extension","python","python3"],"latest_commit_sha":null,"homepage":"","language":"C++","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/overfl0.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}},"created_at":"2016-10-26T21:25:00.000Z","updated_at":"2025-02-15T18:59:52.000Z","dependencies_parsed_at":"2023-02-16T15:30:32.555Z","dependency_job_id":"bb327885-4777-447a-a7ca-c85c9d3aaed7","html_url":"https://github.com/overfl0/Pythia","commit_stats":{"total_commits":459,"total_committers":5,"mean_commits":91.8,"dds":0.04793028322440085,"last_synced_commit":"389534f2179180b33f90b6d074fad5b82463cd32"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overfl0%2FPythia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overfl0%2FPythia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overfl0%2FPythia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overfl0%2FPythia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/overfl0","download_url":"https://codeload.github.com/overfl0/Pythia/tar.gz/refs/heads/next","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247694876,"owners_count":20980733,"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","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":["arma","arma3","extension","python","python3"],"created_at":"2024-11-13T02:19:35.020Z","updated_at":"2025-04-07T17:09:00.015Z","avatar_url":"https://github.com/overfl0.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"assets/logo-200px.png\" alt=\"Pythia logo\" title=\"Pythia\" align=\"right\" width=\"200\" height=\"200\" /\u003e\n\nPythia\n======\n\n[![Build Pythia](https://github.com/overfl0/Pythia/actions/workflows/build.yml/badge.svg)](https://github.com/overfl0/Pythia/actions/workflows/build.yml)\n\nAn Arma 3 extension that lets you to write python extensions for Arma 3. And it's really simple and straightforward to\nuse!\n\n[Pythia's Discord server](https://discord.gg/Pp6ac56).\n\nTL;DR:\n------\n\nCreate a function:\n```python\ndef my_function(some_string, number, the_truth):\n    return ['awesome', 42, True, (1, 3.5)]\n```\n\nCall it from Arma:\n\n    [\"MyAwesomeModule.my_function\", [\"arg1\", 3.14256, False]] call py3_fnc_callExtension\n\nThis will return this to your SQF code:\n\n    [\"awesome\", 42, True, [1, 3.5]]\n\nSee the [examples directory](examples/) for example mods performing simple functions.\n\nWhat Pythia does NOT do:\n------------------------\n\nPythia does NOT replace SQF for modding Arma. You will still have to call your\nPython code from SQF.\n\nIf you're looking for something to extend Arma just like with C++ extensions\n(access \\[remote\\] files, databases, generate images, perform advanced\ncomputations) but in Python, then Pythia is the right tool for you!\n\nFeatures:\n---------\n\n- Full type conversion both ways: pass in an SQF array of ints, get a python array of ints. Return a tuple of a float,\na bool and a string, get an SQF array containing the float, bool and the string\n- Embedded python installation (you don't have to install anything; just run the mod)\n- Python code stored inside `@YourOwnMod` directory\n- Python modules can call and reuse each other, even between separate Arma mods\n- Background Python threads\n- Cython and other compiled python extensions \"just work\" (C-like speed for performance-critical modules)\n- Extendable python environment through pip\n- Proven to work with libraries such as numpy, scipy, matplotlib, PyQt5, etc...\n- Automatic python code reloader for easier development\n- Allows returning more than 10240 characters from the extension transparently\n- Annoys sloppy SQF developers with correct code indentation since Day One ;)\n\nExample mods:\n-------------\n\nThe following are mods that use Pythia to accomplish their goal.\n\n### Frontline\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"assets/Arma_3_2017.08.18_-_02.45.27.39_2.gif\" alt=\"Dynamic Frontline in action\" /\u003e\n\u003c/p\u003e\n\n[Frontline](https://steamcommunity.com/sharedfiles/filedetails/?id=882328821) is like *Squad* but done in Arma. Like *Project Reality: Arma 3* but better. With\n a *Dynamic Frontline* feature that moves as you conquer terrain (and a bunch of other features).\n\nThe frontline computation is done in Python, with the use of `numpy`, `scipy`, `matplotlib` and custom `Cython` code.\n\n### ObjectPlacementTBH\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"assets/ObjectPlacement.jpg\" alt=\"ObjectPlacementTBH\" /\u003e\n\u003c/p\u003e\n\nIt's just a tool for object placement, to be honest... ;)\n\nPythia is used for loading in xml files, file IO, writing images using `PIL`, loading layers.cfg (using [Armaclass](https://github.com/overfl0/Armaclass)).\nThe newest version is using `PyQt5` to [display Qt widgets over the Arma window](https://www.youtube.com/watch?v=Jt4eFG1sM50).\n\nStatus\n------\n\nCurrent status: It's working, it's stable, you can use it :).\n\nYou can contact me to ask for planned changes, on [Pythia's\nDiscord server](https://discord.gg/Pp6ac56). I don't bite :).\n\nExample usage\n------\n\nSee the [examples directory](examples/) for example mods performing simple functions.\n\nYour directory structure:\n```\n@MyAwesomeMod/\n├── Addons/  # (...)\n└── python_code/  # Can be named however you want; you can have more than one\n    ├── $PYTHIA$  # Contains the name of your python package, for example: MyAwesomeModule\n    ├── __init__.py\n    ├── module.py\n    ├── cython_module.cp310-win_amd64.pyd  # Compiled Cython code, because we can!\n    └── cython_module.cp310-win32.pyd      # Same code but for 32-bit Arma\n```\n\n`__init__.py`:\n```python\ndef my_function(my, arguments):\n    return [\"awesome\", 42, True, (1, 2)]\n```\n\n`module.py`:\n```python\nfrom .cython_module import stuff  # You can import code from other modules, obviously\n\ndef call_stuff():\n    return stuff()\n```\n\nNow run Arma 3 with `-mod=@Pythia;@MyAwesomeMod` and execute the following:\n\n---\n\n*Console:*\n\n    [\"MyAwesomeModule.my_function\", [3.14256, False]] call py3_fnc_callExtension\n\n*Result:*\n\n    [\"awesome\", 42, True, [1, 2]]\n\n---\n\n*Console:*\n\n    [\"MyAwesomeModule.module.call_stuff\"] call py3_fnc_callExtension\n\n\n*Result:*\n\n    [\"Hello world from a Cython module!\"]\n\n*Note: `MyAwesomeModule` is the string that was in the `$PYTHIA$` file. You can use any string you want here,\nobviously.*\n\nPerformance:\n------------\n\nThe code is written with performance in mind, meaning that function lookups are cached to limit the number of\n`getattr`s, for example. However, keep in mind that the accessibility requirements (SQF \u003c=\u003e Python type conversion) and\nthe general overhead caused by BIs design choice of allowing passing only strings to `callExtension` must take its toll.\nI'm open to implementing an alternate set of restricted commands that swap convenience for speed, if required, though...\n\nAs such, it is suggested to limit the number of python calls in each frame. It is still faster to call one function with\ntwo sets of arguments than two functions, one right after the other.\n\n#### Concrete numbers:\n\nThe test below was executed by calling `pythia.ping` with different types of arguments, meaning that each list of\narguments had to be converted to python and the return value had to be converted back to SQF. Each test was conducted 3\ntimes and the lowest value was written down.\n\nThe exact arguments for each test can be found in [the Benchmarks](https://github.com/overfl0/Pythia/wiki/Benchmarks).\n\n|  #  | Type of arguments | 3 arguments | 10 arguments |\n| --- | ----------------- |:-----------:|:------------:|\n|  1  | Integers          |  0.0137 ms  |  0.0197 ms   |\n|  2  | Floats            |  0.0152 ms  |  0.0229 ms   |\n|  3  | Booleans          |  0.0109 ms  |  0.0130 ms   |\n|  4  | Strings           |  0.0112 ms  |  0.0151 ms   |\n|  5  | Arrays with ints  |  0.0174 ms  |  0.0327 ms   |\n|  6  | Empty arrays      |  0.0107 ms  |  0.0131 ms   |\n\nNote that you will probably usually pass a number of arguments lower than 10 (and if you don't, your function will most\nprobably be slower than the (de)serializing overhead) so you can assume that **each Pythia call takes less than 0.02\nms** on a recent computer.\n\nThis allows for **under 150 Pythia calls per frame** if you want to stay under the 3ms arbitrary limit (arbitrary\nbecause the callExtension calls are not really limited by the engine, they just block execution until finished).\n\n*Note: You may get away with calls that take even 100 ms server-side, if they happen rarely enough.*\n\n*Note: If your code is REALLY big and slow consider using a background Python thread. See below.*\n\nYour own mod development\n========================\n\nCode reloader\n-------------\n\n*Note: The reloader currently only works for native python code!*\n*If your code uses Cython or custom C extensions (dll/pyd files) you will get errors when reloading.*\n\nTo turn the reloader on, simply call:\n```\n[\"pythia.enable_reloader\", [True]] call py3_fnc_callExtension\n```\n\nThe reloader will then watch all the imported Pythia modules for changes and if any source file is updated, **every\nloaded module** will be reloaded on the next Pythia call. Builtin python modules and modules installed with pip are\nexempt from reloading.\n\n**Important: objects in the global namespace will stay as they are. If such an object points to data inside a module,\nthat data will point to the old (not reloaded) module instance, even after the reload!** (the module will not be\ngarbage-collected as long as there is something pointing to it).\n\nThis can lead to situations where you have two instances of the same module loaded in-memory. The recommended way is to\ncreate pre_reload/post_reload hooks for your module and reinitialize your new module and global variables with the data\nfrom the old module, on reload. See below.\n\n#### Keeping your module data between reloads\n\nTo prevent losing data during reload your module needs to have `__pre_reload__` and `__post_reload__` hooks declared.\n`__post_reload__(state)` will be called with the exact same arguments as have been returned by `__pre_reload__()` before\nreloading the module.\n\nThe reloader works as follows: (simplified pseudo-python code)\n```python\ndef reload_all_modules():\n    for module in pythia_modules:\n        modules_state[module.__name__] = module.__pre_reload__()\n\n    reload_modules(pythia_modules)\n\n    for module in pythia_modules:\n        module.__post_reload__(modules_state[module.__name__])\n```\n\nCreating those functions is purely optional.\n\nNote that using the reloader causes a time penalty for each call and shouldn't be used in production.\n\nThreads\n-------\n\nYou can spawn Python Threads if you want to have functions running in the background or your functions take more than a\nfew milliseconds to complete and you don't want to lock the game.\n\nSee [examples/@PythiaThread/](examples/@PythiaThread/) for details.\n\nInstalling\n----------\n\n- Subscribe to it [on Workshop](https://steamcommunity.com/workshop/filedetails/?id=1751569185) (highly recommended), or...\n- Get a [prebuilt version from Github](https://github.com/overfl0/Pythia/releases), or...\n- Build the mod yourself\n- Copy `@Pythia` to `Arma 3` directory\n\n#### Installing Python requirements\n\nIf any of your Pythia mods contains a `requirements.txt` file, simply drag it onto `@Pythia\\install_requirements64.bat`\nto install all the requirements to both python installations before running the game.\n\nPythia development\n==================\n\nNote: **You do NOT need to compile Pythia yourself** if all you want is create Python extensions.\nAll you need for that is to subscribe to the mod [on Workshop](https://steamcommunity.com/workshop/filedetails/?id=1751569185),\ninstead.\n\nBuilding requirements\n---------------------\n\n- Any Python 3 installation\n- Visual Studio Community 2019\n- WSL2 with clang and Docker installed and configured\n- MakePBO\n\nBuilding\n--------\n\n#### First-time build:\n\nRun this on Windows (requires WSL2 and Docker to be installed and configured!)\n\n    python -m pip install -r requirements.txt\n\n    # Setup WSL for both x86 and x64 architectures\n    wsl /bin/bash -ic \"sudo dpkg --add-architecture i386\"\n    wsl /bin/bash -ic \"sudo apt update\"\n    wsl /bin/bash -ic \"sudo apt install python3-pip patchelf libcrypt1:i386 clang gcc-multilib\"\n    wsl /bin/bash -ic \"python3 -m pip install -r requirements.txt\"\n\n    python tools\\rebuild_all.py\n\nThis will fetch and install all the python interpreters required both for\nbuilding Pythia and then used by Pythia itself at runtime. See `build.py` which\nis used by `rebuild_all.py` for details.\n\n#### Later, for modifying and building the DLLs/SOs:\n\n- In Visual Studio: File -\u003e Open -\u003e CMake: `CmakeLists.txt`, Build -\u003e Build All. Remember to build for all\n  configurations!\n\n#### Later, for building everything else:\n\n- `python tools\\build.py --help`\n- See `rebuild_all.py` for usage\n\nCommon errors\n-------------\n\n#### Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock\n\nYour Docker environment is misconfigured. You probably need to add yourself to the `docker` group and restart the\nshell.\n\n    sudo usermod -aG docker $USER\n\n#### FileExistsError: [Errno 17] File exists: '@Pythia/python-310-embed-linux32'\n\nDocker/WSL2 is probably throwing a fit. Restart WSL by typing this command.\n\n    wsl --shutdown\n\nContributing\n------------\n\nAll contributions are welcome! Is something in the documentation unclear? Feel free to submit a PR or drop a note on\n[Pythia's Discord server](https://discord.gg/Pp6ac56).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverfl0%2Fpythia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foverfl0%2Fpythia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverfl0%2Fpythia/lists"}