Contributing to FortressGD
Thanks for helping. Read DESIGN.md (the normative spec) and THREAT_MODEL.md before changing behavior. Security problems go through SECURITY.md, not public issues.
FortressGD needs Python 3.9+ and has no required dependencies.
git clone https://github.com/salaryman-inc/FortressGDcd FortressGDpython3 tests/run.py # the full default test suitepython3 bin/fortressgd --help # run the CLI from the checkoutpip install -e . # or put `fortressgd` on PATH from the checkoutOptional extras the default suite skips:
| Variable | Needs | Runs |
|---|---|---|
FORTRESSGD_GODOT_TESTS=1 |
Godot 4.6.2 / 4.7.2 (GODOT=/path/to/godot) |
The GDScript mangler against the golden corpus |
FORTRESSGD_DOCKER_TESTS=1 |
Docker | A build of the template image |
FORTRESSGD_UNPACKER_TESTS=1 |
KeyDot and a protected .exe (see docs/ci.md) |
The KeyDot regression test |
tests/test_generator.py compiles the pack-key reassembly with each C++ compiler it finds (g++, clang++, x86_64-w64-mingw32-g++) and fails if the optimizer folds the key into the object; set FORTRESSGD_REQUIRE_COMPILERS=g++,clang++ to fail instead of skipping a missing one.
pip install cryptography exercises the OpenSSL AES path; without it the pure-Python AES runs. CI runs both.
Layout
Section titled “Layout”The Python package is fortressgd/. The editor plugin (fortressgd/plugin/addons/fortressgd/), the engine patches (fortressgd/patches/<tag>/), the Docker build (fortressgd/docker/) and the example config ship inside it, so code must find them through fortressgd/core/paths.py, never relative to the repository root. See DESIGN.md §3.
From DESIGN.md §15, in short:
- Do not add packers, VMs, anti-debug, license servers, or network checks.
- Do not vendor Godot source. Keep engine patches small; one folder per Godot tag.
- Fail the export rather than ship a recoverable or broken build.
- Errors print
error: …and the next command to run. - Update DESIGN.md in the same pull request when behavior changes.
- Never print, log or persist the project secret or anything derived from it.
Common changes
Section titled “Common changes”- Mangler. It exists twice:
fortressgd/core/mangle.py(CLI exports) andfortressgd/plugin/addons/fortressgd/mangle.gd(editor exports). Change both, then add or update a case intests/mangle_corpus/(see its README) so CI holds them to the same output. - Config keys.
fortressgd/core/config.py,fortressgd/plugin/addons/fortressgd/schema.jsonand the GDScript parser inconfig.gdmust accept exactly the same input. - A new Godot tag. Follow DESIGN.md §4. The tag is supported only once
fortressgd/patches/<tag>/seriesexists and the patches apply. - Docs. Edit the Markdown in
docs/or at the repository root; the site indocs/(Starlight) is built from those files and deployed to GitHub Pages when they change onmain. A new page also needs an entry indocs/site.config.mjs. Seedocs/README.mdto preview it. - Version bump.
fortressgd/core/version.pyandfortressgd/plugin/addons/fortressgd/plugin.cfgmust match;doctorand the tests check it.
Pull requests
Section titled “Pull requests”python3 tests/run.pypasses.- New behavior has a test.
- Commit messages say what changed and why in plain words.
By contributing you agree that your contributions are licensed under the MIT License.