At the beginning of 2021, ArenaNet announced that they would no longer be supporting the macOS client for Guild Wars 2. As a longtime player, I found this… unfortunate.
There are several ways to run the Windows client on a Mac including dual-booting Windows with Bootcamp, but that’s not an option for me. Running in a virtual machine like VMWare or Parallels is too slow, so that leaves some form of Wine which is a Windows compatibility layer. The old macOS 32-bit Guild Wars 2 client actually used a version of Wine to run. It wasn’t as good as when they released a 64-bit native client, but it worked for a time.
I tried several ways to run Guild Wars 2 using Wine before finding one that works for me. In this post I’ll explain how to set it up.
Note (23 July 2022): I have an updated version of this post for handling DX11.
Over the past couple of months I have been porting an existing Unity game to macOS. It is a shoot-em-up called Blue Rider developed by Ravegan from Córdoba, Argentina. It was originally released on PC (Steam), XBox, Playstation 4, and Switch.
I spent quite a lot of time getting it ported and running smoothly only to find that I couldn’t get past Apple’s notarization procedure because of the version of Unity I am using (5.6.7f1).
The binary uses an SDK older than the 10.9 SDK.
Notarization is required as of macOS 10.15 to distribute games in the Apple Store and it may become necessary on Steam. It may also be useful to notarize games for standalone distribution to avoid confusing warnings when users try to run your game.
(I am going to hold off a whole rant about Apple and their BS requirement to do this code signing/notarization at all. And I will try not to rant too much about their incredibly complicated process, documentation, and implementation.)
In this post I’ll describe the main problem I ran into and how I solved it. Hopefully it will help someone else.
I recently had a customer describe some very random crashes with my software. There didn’t seem to be a pattern or a way for me to reproduce the problems locally to debug them. So my first thought was to get him to install a version with some kind of crash reporting tooling so I could get a stack trace to help track down the issue.
I’d looked into implementing some form of crash reporting quite a while ago, but it was never a very high priority for me because I don’t get a lot of bug reports. In this case though it seemed like it would be easiest if I could produce a version of my software with some built-in stack tracing.
The first thing I did was to look at what libraries were available for this. My criteria were:
- simple to use/integrate with a Qt application
- works with the MinGW 32-bit compiler on Windows and the clang compiler on macOS
- inexpensive (or free!)
- usable in commercial software
The most promising were BreakPad (older) or CrashPad (newer) from Google. From what I understand, Breakpad no longer works on macOS which is why they switched to CrashPad. Unfortunately CrashPad doesn’t handle 32-bit MinGW builds. The reason I’m stuck with the 32-bit version is that Qt currently ships its MinGW builds of the libraries and toolchain using the 32-bit MinGW 4.9.2 compiler.
So after a lot of searching and piecing things together, I’ve created something that works and fits my criteria. It’s very simple – all it does is save the stack trace to a file that the user can send me – and requires some instructions to the user to work with it. If I wanted to get fancier I could have it automatically post the information to a web server, but for now this is simple and it works.
It might work on Linux too since the code path for macOS should be POSIX compliant, though I haven’t tried it. It could also be extended to handle MSVC compiles (or maybe it already does!), but I don’t use that compiler so I can’t test it.
I used many different sites in my search, but my primary sources were Catching Exceptions and Printing Stack Traces for C on Windows, Linux, & Mac by Job Vranish, Printing a Stack Trace with MinGW by Daniel Holden, and the C++ name mangling article on Wikipedia.
I was inspired while watching a talk by Kevin Ottens about refactoring OpenGL code in Qt to take a look at gcov & lcov. gcov is used to analyze code coverage – which lines of code have actually been executed while running an application. lcov is a tool that can produce HTML reports from the gcov output.
If you have a suite of unit tests that you run on your code, you can use these tools to see which the lines of code are covered by your tests and which are not.
I couldn’t find a decent primer on how to set this up properly for my Qt projects on macOS so I could run it from Qt Creator, so I thought I’d write up how I did it.