# Licensing arena builds a container image out of other people's work. This covers what those licences require and what we do about it. Short version: **publish our changes, stay non-commercial, and keep the control plane a separate process.** A different architecture would not avoid any of it. ## What is in the image | | licence | what it asks | |---|---|---| | MegaMek code | GPL-3.0 | ship our modifications as source | | MegaMek data & assets | CC BY-NC-SA 4.0 | non-commercial, attribution, share-alike | | Suramadu | AGPL-3.0 | as GPL, **plus** offer source to network users | | Java runtime (Temurin) | GPLv2 + Classpath Exception | nothing; the exception covers normal use | | Chakra Petch | OFL 1.1 | ship the licence text with the font | | arena's own code | GPL-3.0 | ours, matching MegaMek | ## What we have to do **1. Publish this repository.** Patches, configs, scripts, all of it. Suramadu is AGPL and we serve it over a network, so §13 requires us to offer source to the people using it. Publishing removes the question entirely, and we have no reason to keep any of this private. 26.4.7 also puts that offer on the page itself, as a fixed source notice in the war's `index.html`. We serve our own copy of that page, so the notice is carried across in `suramadu/web/index.html` and styled in `theme.css`; dropping it would drop the one thing a network user actually sees. **2. Keep the container and the control plane separate processes.** headquarters talks to arena over HTTP and never links a Suramadu jar. That boundary keeps the control plane outside the AGPL's reach, and it is a reasonable design in any case. See `docs/launch-manifest.md` in the headquarters repo; the manifest is that boundary. **3. Stay non-commercial.** Two separate obligations require it: MegaMek's asset licence and Microsoft's Game Content Usage Rules. Accepting donations for hosting is generally considered fine; selling access is not. ## Suramadu, not Webswing We use [Suramadu](https://github.com/manticore-projects/suramadu), the AGPL-3.0 community fork by manticore-projects continuing from Webswing v20.2.5, the last release under that licence. We have **no affiliation** with the commercial product at [webswing.org](https://www.webswing.org). The fork was called "Webswing Lite" until 26.4.6, when it took the Suramadu name and renamed its artifacts with it — the archive, the war, `suramadu.config`, `suramadu.properties` and the frontend bundles. That rename is what removes the confusion the old "always write it in full" rule existed to manage, so the rule is gone. What did **not** rename is the part a build actually binds to. The whole `webswing.*` system-property namespace survived intact — all ~200 of them, from `webswing.appId` to `webswing.window.theme.titleHeight` — as did every `org.webswing.*` package and the server's `token_cookie`. Upstream kept them so existing installations keep working, and we must keep writing them too: | stays `webswing` | where we use it | |---|---| | `org.webswing.*` Java packages | `-Dawt.toolkit`, the log4j2 stats logger | | `org.webswing.window.theme.*` | window colours in the app config | | `webswing.drawDelayMs`, `webswing.dd*CacheSize`, `webswing.trustedFontDirs` | client JVM tuning | | `webswing.websocketMessageSizeLimit` | server JVM flag in the entrypoint | | `org.webswing.server.*` | `jetty.properties` keys | | `webswing-loader-stub.js`, `data-webswing-*`, `window.webswing` | the served `index.html` | A `webswing` string in this repo should be one of the above. Anything else is a leftover. The trap runs the other way too: a `suramadu` string that upstream does not use is just as wrong, and harder to spot because it reads correct. `webswing-embed.js` did become `suramadu-embed.js`, but `webswing-loader-stub.js` beside it did not. Check the artifact before renaming; `suramadu/verify-web.sh` catches the ones that reach `index.html`, and nothing catches the rest. The fork's README asks for attribution to the Webswing team for the original architecture, and we give it. The distribution ships no LICENSE file. We redistribute it, so the Dockerfile's `suramadu` stage fetches the AGPL text into the bundle, and **fails the build** if it cannot. ### Why AGPL matters more than GPL here Plain GPL would not reach a hosted service: running modified MegaMek on our own servers triggers no disclosure by itself. AGPL's §13 adds the network case, which is the case we are in. It is also not cleanly separable from MegaMek. Suramadu does not proxy a separate process — it injects into the application JVM: -Xbootclasspath/a:...suramadu-app-toolkit.jar:...modpatch-java-desktop.jar --patch-module java.desktop=...modpatch-java-desktop.jar -Dawt.toolkit=org.webswing.toolkit.WebToolkit11 MegaMek runs inside a JVM whose `java.desktop` has been patched with Suramadu code. Whether that combination counts as one work is an open question, not a clear no. That is why we publish, and why none of our code runs inside that JVM: `MatchHost` and `MatchWatcher` are separate processes using MegaMek's normal network protocol. GPL-3.0 and AGPL-3.0 are compatible — GPLv3 §13 allows the combination — so there is no conflict, only the network clause to comply with. ## Our patches Nine, in [megamek/patches/patchset/](megamek/patches/patchset/), stored as unified diffs rather than copied source files. A copied file would silently discard upstream changes on the next release; a diff fails to apply instead, which is the behaviour we want. Each one fixes a MegaMek bug rather than adapting MegaMek to our environment, so all nine should go upstream. An accepted PR costs nothing to maintain; a carried patch costs something every release. `megamek/verify-patches.sh` runs on every build and checks that the patched jar differs from stock in exactly those classes and no others. Three more, in [suramadu/patches/](suramadu/patches/), applied to the frontend bundle inside the Suramadu war: keyboard input sent immediately, mouse input flushed faster, and frames acknowledged on receive rather than after paint. Suramadu is AGPL-3.0, so the same rule applies with more force — we serve the modified code over a network. The patches ship inside the image at `/opt/arena/patches` (Suramadu's under `patches/suramadu/`), so the source of our modifications is distributed with the binaries that contain them. ## BattleTech IP MegaMek operates under Microsoft's Game Content Usage Rules. Its notices state: > MechWarrior, BattleMech, 'Mech and AeroTech are registered trademarks of The > Topps Company, Inc. Catalyst Game Labs and the Catalyst Game Labs logo are > trademarks of InMediaRes Productions, LLC. MechWarrior Copyright Microsoft > Corporation. In practice: - **Keep the marks out of our own naming** — BattleTech, BattleMech, 'Mech, MechWarrior, AeroTech, Alpha Strike, Clan names, Catalyst product names. This is why the domain is `lance.blue`: generic military vocabulary, no mark. - Lore vocabulary inside internal identifiers is lower risk than in a brand or a domain, but keep it out of anything public-facing. - We ship no artwork or unit data of our own. We run MegaMek's, under MegaMek's terms. ## The boot screen's font `suramadu/web/fonts/` holds Chakra Petch 700, the one face on the loading screen, under OFL 1.1. The licence asks for two things and both are already true: its text travels with the font, in `OFL-Chakra-Petch.txt` beside the woff2 files, and the font is not sold on its own. The whole of `suramadu/web/` is copied into the image, so the licence reaches players by the same route the font does. There is no Reserved Font Name on this family — the copyright line in that file carries no such clause — so a modified copy could keep the name. We ship unmodified downloads anyway, which keeps the question closed. The insignia beside it, `suramadu/web/insignia.svg`, is our own artwork, copied from headquarters. Nothing is owed on it. ## Before adding a dependency 1. What is the licence, **checked in the artifact or the repo** — not from a search result or from memory? This project has already got that wrong once. 2. Is it AGPL, or otherwise network-triggering? 3. Does it require non-commercial use, and does that change anything? 4. Does it run in-process with MegaMek, or at arm's length? 5. Is it easily confused with a commercial product of a similar name — and if so, is the distinction stated everywhere?