Enigma is currently only compatible with Windows. For a long time, I assumed that the vast majority of astrologers used Windows. That the Windows share was declining, both due to the popularity of Apple and mobile platforms, was of course well known. But this process is moving faster than I thought. On June 25, 2024, I posted a survey in a popular Dutch Facebook group about astrology. My question: which environment was preferred for working with astrological software. 77 people responded, yielding the following score:
- Windows (desktop/laptop): 51%
- Apple MacOs (desktop/laptop): 10%
- Linux (desktop/laptop): 3%
- Apple iOs/iPadOs (smartphone/tablet): 25%
- Android (smartphone/tablet): 11%
A survey like this is improvisational but you can glean some important conclusions from it:
- half of the astrologers prefer Windows.
- over a third work with Apple equipment.
- and a third of astrologers work with Apple or Android mobile devices.
I draw the conclusion that it is insufficient to develop Enigma only for Windows. You can, of course, run Windows applications on an Apple computer via emulation software like Parallels. However, that is a stopgap solution and, moreover, it does not work on mobile devices. What you need is a cross-platform application, a program that works on desktops with Apple, Linux or Windows and also on mobile equipment with Apple or Android.
Realizing this will take a lot of time. So much time that for now I will continue to develop Enigma in the C# programming language, so only for Windows. In parallel, I am starting to convert to another environment that is cross-platform. At the latest by the time Enigma is ready for release 1.0, and the main functionality is built, I’ll make the switch. This will probably take a year or two.
Technical Choices
To move to a new way of working that supports cross-platform development, I need to make three important choices:
- What will be the core programming language.
- How do I approach the Swiss Ephemeris.
- What techniques do I use to build the GUI.
Programming Language
I have looked not only at supporting cross-platform development but also at general aspects of programming languages. Almost always, I worked with object-oriented languages such as Java, Kotlin and C#. This had the advantage that I was better able to write larger and complex programs. But object orientation also has a disadvantage: you have to be very careful about over-engineering. I started looking for alternative languages and found two candidates: Rust and Go. Rust is a language that is especially suitable for critical applications and for applications that need to work in real time, like system software. I worked with Rust for a short time and found it to be a well-thought-out language. But Rust is complex and is known for its “steep learning curve”. Go is less rigorous than Rust but offers sufficient guarantees of reliable applications. Go is less suitable for time-critical applications because – unlike Rust – it works with a garbage collector. The big advantage of Go is that it is a minimal language. As a result, you can easily learn Go. Moreover, the small instruction set is pragmatic and you have a large amount of libraries you can use. Due to the lack of much syntax sugar, Go compiles very quickly and has excellent performance. The choice therefore is Go, with Rust as an alternative.
I do not consider languages like C and C++, even though they offer easier access to the Swiss Ephemeris (see next section). The chance of wrong memory allocations is very high in these languages; Rust would be a better alternative. Python is also not considered, in my opinion it is difficult to write large projects in Python, in addition Python offers much lower performance than native compiled languages.
Swiss Ephemeris
The Swiss Ephemeris (SE) is written in C. To access it from another language, there are three options:
- a port: completely rewriting the SE in the desired language.
- a wrapper: placing the original C code of the SE in a wrapper of the desired language.
- JNI: Java Native Interface, a standard way to access compiled code from another environment.
Writing a full port is very much work but is possible. Thomas Mack wrote a port of the SE in Java, years ago, and it worked very well. But the SE consists of tens of thousands of lines of code, if you write a port you spend a lot of time both building and maintaining it: you also want to support future versions of the SE. A possible option but certainly not attractive.
A wrapper is easier to write, especially in Go and Rust. Wrappers in Go, that I can reuse, already exist. This seems like a useful solution.
JNI in itself is ideal but only works with languages that use the JVM: Java, Kotlin etc. Kotlin in particular is an excellent language but does carry the risk of over-engineering.
GUI
The current version of Enigma uses WPF for the GUI. WPF is complex but allows for a highly scalable GUI. Unfortunately, WPF is only suitable for Windows. An alternative like MAUI is still too immature and also does not support Linux GUI’s.
Broadly speaking, there are two alternatives:
- an on-line application.
- a web-based application, but packaged as a native application.
- a cross-platform native library.
An on-line application has its problems: you would not have good capabilities for using a database and only limited capabilities for storing user preferences. Moreover, an Internet link does not give the feeling of an application: you build a relationship with the users to a lesser extent.
A Web-based native application does behave like a real application but requires the use of JavaScript; I see that as a major drawback. You can choose from platforms like Electron.js and Tauri. But Electron.js does not support mobile platforms. Tauri plans to do so in the future but is not yet that far. Tauri does require the use of Rust.
A well-known cross-platform native library is Flutter. Originally intended for mobile applications, Flutter now supports all relevant desktop variants. Flutter uses Dart, an object-oriented language. Dart is not suitable for the backend; for that you are better off using Go. Flutter and Go work very well together.
Conclusion.
- Programming language backend: Go
- Frontend programming language: Dart
- GUI: Flutter
- SE: wrapping.
I hope to regularly publish findings on the progress of this project. Enigma will remain open source, the code, including future cross-platform code, you can use in your own project, as long as your own code is also open source.