Development and Build
Develop on a PC, synchronize changes to a phone, build archives, and debug reloads.
Development and build
The productive Elyx loop is:
- edit the complete project on a PC
- synchronize changed files to the installed plugin directory
- let Elyx unload and reload the plugin
- inspect errors and continue editing
Prerequisites
- a recent exteraGram build with plugin support
- the current plugin SDK available to the IDE
- Python 3.11 for bytecode-compatible builds
- ADB when connecting a USB device or emulator
- an Elyx archive installed once on the device
Enable the plugin engine and developer mode in exteraGram's plugin settings.
The built-in development server listens on 127.0.0.1:42690 by default.
Connect over ADB
Forward the phone's loopback server to the PC:
Verify the device first if needed:
Only one process can use a local forwarded port. Remove and recreate the forward if another device was previously connected:
Initial installation
The structured live-reload protocol updates an Elyx plugin which is already known to the running engine. Before starting a watcher:
- build an
.elyxor.eafarchive - install it through exteraGram
- enable it at least once
- confirm that its
idmatches localmetainfo
Custom elyx_dev_client.py
Use the custom client from the project root. Client revisions may expose different flags, so inspect the script's own help:
A client normally needs:
- server host and port, usually
127.0.0.1:42690after ADB forwarding - the local project root
- the plugin
id - ignore patterns for
.git,.elyx,builds,__pycache__, and IDE files
The intended behavior is incremental: compare file hashes, send created, modified, moved, and deleted paths, then wait for the engine to reload the plugin.
The client is not bundled in this SDK repository
Keep the client version used by your team alongside the plugin or in a shared
development-tools repository. Its command-line interface is not part of the
runtime elyx API.
Development protocol reference
The server exchanges consecutive JSON objects over a TCP connection. Elyx commands use:
@for the action name#for the request iddatafor base64-encoded, zlib-compressed JSON
Supported Elyx actions:
| Action | Purpose |
|---|---|
elyx_ping | Check that the Elyx server patch is active |
get_elyx_plugins | Return metadata for loaded Elyx plugins |
elyx_compare_folder | Compare client hashes with installed files |
elyx_changes | Apply file changes and reload a plugin |
Low-level tools should keep request ids unique and wait for the response with
the matching #.
Change records
An elyx_changes payload contains:
Event types are:
createdmodifieddeletedmoved
Created and modified files carry base64-encoded bytes. Moved entries use
path and dest_path. Paths are relative to the plugin root.
After applying the batch, Elyx unloads the plugin, clears its imported modules,
loads the project again, and reports success plus an errors list.
Build with ElyxBuilder
ElyxBuilder can generate the entire initial project as well as package it:
Run it from the directory containing refmap.yml:
For a compiled Python 3.11 build:
See ElyxBuilder for elyb new, watch mode,
incremental compilation, ignore lists, project statistics, and the official
ElyxBuilder documentation.
Build with Python 3.11
The phone runtime in this SDK is Python 3.11. Use Python 3.11 whenever the
release contains .pyc files.
Build a plain archive
For source distributions, any ZIP tool is enough when it preserves paths.
Archive the project contents so refmap.yml is at the ZIP root, then rename
the result:
Before publishing, inspect the archive:
Do not ship:
.git/.elyx/cache/builds/__pycache__/- desktop virtual environments
- secrets, API keys, signing material, or local logs
Reload-safe code
Elyx clears local Python modules, hooks, and menu items. Your plugin remains responsible for resources it creates:
Avoid starting permanent work at module import time. Put initialization in
on_plugin_load and cleanup in on_plugin_unload.
Release checklist
- install from a clean archive, not only through live reload
- test the default locale and English fallback
- test with missing network access when dependencies are involved
- disable and re-enable the plugin
- update from the previous public version
- verify every declared asset and localization path
- inspect the archive root for accidental wrapper directories
- confirm
id, version constraints, and dependency links