Rsclub2_2 e44436750b Speak the operator's language
The interface is German or English, chosen per operator profile on the GUI tab, in force at
once in every open window, and remembered across restarts. 376 texts in both languages.

The texts are ordinary .properties files that nobody has to compile: a contributor copies the
English one, translates the values, and opens a pull request. A third module -- build tooling
that never ships -- turns them into Kotlin before anything compiles, which is what makes a
mistyped key and a wrong argument count compile errors rather than things an operator
discovers. It lives in the main build rather than buildSrc because buildSrc's tests do not run
on `./gradlew build`, measured, and a generator whose tests never run is the exact failure it
exists to prevent.

Incompleteness is allowed and incorrectness is not. A missing key warns and falls back to
English, so a partial contributed language can be submitted at all; an orphan key, a
placeholder the translation drops, a duplicate key or an unreadable file fail the build with
the generator's own message naming the file. The argument count always comes from the English
base. German is held complete by a test because it ships; a contributed language is not.

What is deliberately not translated is the harder half. Protocol frames and chat commands
would break the connection or go unread; the beacon texts, auto answers, snippets and
shortcuts go to other radio amateurs and sit in every operator's stored profile; the 273
println calls in core are diagnostics, and a German stack trace is worse for whoever reads the
bug report; and QRA, QRG, QTF, LOS, Fresnel and wkd read the same in either language. Three
tests guard the boundary by measuring behaviour rather than text: the protocol frames built
under three locales, every preference default compared by reflection, and no translation value
being a protocol command. The reflective one is the only one that covers what nobody thought
of.

One insight turned up three times. Anything built outside a composition freezes the language it
was built in: the window title, the settings tab strip and every column header are all
constructed once at startup -- the columns from Java -- so each now holds a function read when
it is drawn. That also fixed something older and unrelated to language: the main window's title
was a fixed "KST4Contest (Compose)" for the whole session, where the JavaFX window had carried
the live connection line. It carries it again.

A column's id is never translated. It is what the remembered widths and order are keyed on.
2026-10-05 22:36:01 +02:00
2026-10-05 22:36:01 +02:00
2026-10-05 22:36:01 +02:00
2026-10-05 22:36:01 +02:00
2023-11-10 08:33:17 +01:00
2026-10-05 22:33:28 +02:00
2026-10-05 22:36:01 +02:00
2026-10-05 22:36:01 +02:00
2024-01-16 22:51:30 +01:00
2023-11-09 22:53:59 +01:00
2023-11-14 00:50:10 +01:00
2023-11-10 08:33:17 +01:00
2026-10-05 22:36:01 +02:00

KST4Contest

KST4Contest is a Java-based client for the ON4KST chat, developed for coordinated VHF, UHF and microwave contest operation.

The application is developed by Marc Fröhlich (DO5AMF) and since 2026 Philipp Wagner (DN9APW).

Start here

What KST4Contest does

KST4Contest combines the ON4KST chat with information that is useful when coordinating contacts during a contest.

Among other things, it can:

  • display and filter stations from the supported ON4KST chat categories;
  • derive band and frequency information from chat messages and station names;
  • maintain Worked and NOT QRV information for the available bands;
  • calculate station priorities from distance, activity and other available information;
  • manage internal skeds and received Win-Test skeds;
  • use AirScout information when evaluating possible aircraft-scatter contacts;
  • display stations, paths and additional propagation information on maps;
  • exchange information with supported logging programs, Win-Test, PSTRotator and a local DX Cluster interface;
  • provide configurable automatic replies for recurring chat requests.

Calculated scores, aircraft-scatter information and path assessments are operating aids. They depend on the available data and should not be treated as guarantees that a contact is possible.

Installation

Ready-to-use packages are available for Windows, Linux and macOS. These packages include the required Java runtime, so a separate Java installation is normally not necessary.

Use the central download page to select the appropriate build:

  • Stable is intended for normal contest operation.
  • Beta contains changes that are being prepared for a stable release.
  • Nightly contains the latest automated development build and is mainly intended for testing.

Open the download page

Documentation

The documentation is available in German and English:

The Markdown sources used for the wiki and the generated PDF manuals are stored in github_docs.

Changes to operating behaviour should be documented together with their purpose and limitations. This is especially important for functions whose result depends on external data, heuristics or information derived from chat messages.

Building from source

Building KST4Contest requires JDK 21. The Gradle Wrapper included in the repository should be used, so a separate Gradle installation is not required.

Linux and macOS:

./gradlew clean build

Windows:

.\gradlew.bat clean build

Repository structure

  • core/ – domain, controller and network code, free of user-interface technology
  • app-desktop/ – the Compose Multiplatform user interface and the packaging tasks
  • github_docs/ – German and English manual sources
  • website/ – project website sources
  • packaging/ – platform-specific packaging files

CI status

Documentation

Publish wiki

Docs PDF

Builds

Nightly Runtime Artifacts

License

KST4Contest is distributed under the GNU General Public License v3.0.

S
Description
No description provided
Readme GPL-3.0
1 GiB
0 Stars 1 Watchers 0 Forks
Languages
Java 54%
Kotlin 36.3%
JavaScript 5%
Nunjucks 1.8%
CSS 0.9%
Other 2%