Facepalm, sigh, nervous finger tapping…more sighs and facepalms. That’s how will I remember the experience of porting the Courier of the Crypts from Windows to Mac OS.
I want to share the story of the whole porting procedure with you, what problems did I have and how did I feel through the whole experience as a MAC virgin. Maybe, it will also help the future me and others with the same problems.
Before I start, I want you to know that I have near 0 experience from OSX and Macs. I had a game development lesion at the university where we had to work on MACs but that was a really short thing and it really didn’t bring much to my current problem. Thanks to Matej Jan (Retronator) who gave me his old Macbook to port Courier of the Crypts so I could take the time and start working on the port which I have promised to everyone when I started taking the pre-orders for the game.
I was building the game engine with cross platforming in mind (SDL, OpenGL, FMOD…) so I was quite optimistic about everything. It should be done in a week or so – oh boy was I wrong…
The first problem I had but didn’t realize it until later was creating a new project of the wrong type – Command Line Tool instead of Cocoa Application (which creates .app file required by Steam). More details about this later.
The next logical step for me was to copy all the data and code to the project and just trying to run it. Setting up precompiled headeres and defining main.cpp file was easy but of course the compilation failed with bunch of errors, some from the code and some from the libraries. Next to minor code errors ( commenting styles, slashes etc.) I was missing libraries so I set up to find MAC libraries. Some of them were pre-built while I had to build others manually but I didn’t have a single idea how. It had something to do with homebrew and running some scripts and honestly, I’m still not sure how this is done because my co-worker helped me to go through this step. Ok, I had libraries, this was set.
The a vicious opponent appeared – Apple Mach-O Linker error. All my managers included in main.cpp file had it. I was googling around like crazy but couldn’t find a solution to the problem. “Ok, co-worker may know something about it…” I said to myself and took the Macbook to work the next day. It turned out I didn’t include .cpp files for compilation – you don’t have to do this in Visual Stuidio, because I agree this is somewhat logical that all the code in the project is compiled but not for Xcode. You need to specify all the .cpp files you wish to compile. Libraries DONE, compile sources DONE, let’s build the project.
More code errors – most of it came from windows specific functions and #include not finding the library headers. Visual studio always threw a warning using sprintf or fopen that it’s not safe to use it and that sprint_s and fopen_s is what I should go with. Well, it turned out those two are windows specific so I had to replace all the safe ones with classic C methods.
After I went through the code I tried to run the game again and IT WORKED! Oh the joy, main menu was on and crow calls were echoing through the crypt valley.
Everything worked really well surprisingly! Well, almost, fonts were missing some characters and they simply weren’t displayed.
I was using FreeType font library, which takes any font file and generates textured glyphs real time. It is very nice library but for some reason it was causing troubles to MAC version. I did some googling but it looked like it is only me with that problem and most likely it was my problem but I was planning to do an implementation of my own Bitmap font system because it’s much easier to work with (exact size, customizable glyphs with more than 1 color etc.). I did the implementation on Windows and move it to MAC later and it worked perfectly, the font was even more clear and readable. But with that change, I had to go through all the code where old text was used and replace the calls with the new text system. (dialogues, text scrolls, speech bubbles, shop inventory, menu text…) Also, I had to align the text properly. That took me a hefty amount of time but it was well worth it for now and for the future.
Everything was ready. I launched the game and made a complete walkthrough for the test to see if it fails somewhere. It didn’t so everything was good, let’s make a build and try to run it from outside the Xcode. It was an error launching the applications, libraries were not found. “What the hell? How? They are with the executable…”
That was one of the major problems I had with porting because I had to do a big search over the internet to find the solution to it. It included the usage of install_name_tool and otool in script inside the Xcode. Interesting thing is, that it was hard to find an explanation about the tools and what they do exactly. A lot of people answering the problems but no one explaining in details. I had to do some trial and error in order to get this right.
It looks like when building the libraries, the path to them is saved somewhere and you need to change the place where the application should look for them – in my case, to the game directory. When I overcame this I finally launched the executable outside the Xcode successfully. I read through Steam documentation to see if there are any special procedures for uploading the MAC build – so far it was all about the different procedures and I knew I’m in for more.
From Steam Documentation:
“What app? I don’t have an app, only a directory with executables, libraries and data. How do I make an app?“.
With these question I went to consult with uncle google. I was happy to see that other people are asking similar questions but there was no answer that would help me do it. Those suggestions that should work did not for me or at least not with my Xcode version. I decided to write another StackOverflow question about my problem. TL;DR; I did a mistake creating Command-line-tool project instead of Cocoa Application. How should I know that? I thought Cocoa Application is only for objective-c projects like it says in the descriptions when creating a new project. I was really afraid that I would have to go over the whole process and yes, I did at the end but I cut some shortcuts. Hopefully I only had to make a new Target of Cocoa Application type but I still had to set up everything again. I had some more problems with linking the libraries because .app files has a bit different structure but it wasn’t such a problem. The CourierOfTheCrypts.app file was there waiting to be launched. Excited, forgetting that the whole experience was full of land mines I tried to execute it and BAM, not working. Crashing! At least it wasn’t the library problem this time…
I had to add a lot of printf-s to the code in order to find the issue. Again, to cut it short, the game didn’t find any files I’m loading in the game(Textures, Settings etc.) and I couldn’t understand why and why does it work from the Xcode. It looks like fopen doesn’t look for files where the executable is so I had to read the relative path and use it for opening files. This means that I had to change all the methods where I’m writing or reading something specific for MAC. Maybe I don’t understand something here and I did more work than necessary but I didn’t have the energy nor time to study the whole issue. After that, even the .app file worked, yay!
I had to do some more hair-pulling to upload the .app file on Steam (Uploading the game on Steam isn’t the most friendly thing in the world.) and finally I had the Courier of the Crypts in my Steam Library on Steam. With a giant smile I was looking at the download bar and run it, IT WAS WORKING! Well, almost, the music was not playing. I figured that I forgot to edit the fopen calls I was talking before for loading the music:
Back to Xcode, do the fix, build the .app file, upload it to steam, release the update, try, agian. (common procedure by the way).
I made sure twice that everything works. It did, perfectly! I’ve moved the build from testing branch to public and start writing a Steam announcement for the MAC version release. I also shared the news on Twitter and Facebook. Some fresh game purchases already came in from MAC users and I was just about to turn off the computer, leaving for bed with satisfaction when an acquaintance hit me on Facebook that MAC build won’t run on Steam for him. “Whaaaaat?? Really?” I couldn’t believe it. All the problems I went through and it was still not an end to them all. Thanks to him for taking the time I got this report:
This is the similar error I had a while back and I couldn’t understand why is it happening but thankfully I knew the solution or at least something similar to it. I wrote a install_name_tool script line for every library I’m using as I did for the previous one that was causing problems. I uploaded another build but it looked like it still only works for me…I really didn’t have the energy and I had to get some serious sleep for the next day at work. I really felt bad because I knew people already put money in for the game when it doesn’t run at all! I didn’t know what to do…I had to sleep it through and wait for the next evening to get through with the problem. TL;DR; next day in the evening, I’ve made the game running on MAC for everyone. Next to the missing script lines I forgot to add a Library to the project. With this added, I put one more build to the Steam, this time it worked for everyone (as far as I know). I was relieved and I immediately put an announcement that the game works. The MAC porting battle was really over, and MAC users could play the game. I felt great, I passed another milestone for the game knowing that the game is accessible to more players and that I don’t have to worry about the MAC port anymore because I have the experience now how to do it (although I’m sure there will be more problems with it in the future…this experience taught me that).
I know that most of the problems I had was because I lacked the knowledge of MAC systems and Xcode IDE. Reading more about it beforehand I could dodge many problems I had. Because of the limited time I have lately I also couldn’t really think through every problem I had so there are points that I really don’t understand how it works but I will have to conquer that knowledge one day. The experience of porting was terrible if I’m honest but the feeling at the end was so much better because of that. Now that I understand more I will be able to write more cross-platform friendly code that will work on either systems.
If your code is already cross-platform and if you understand how the Xcode and MAC system works you can port the game in a day or two without additional problems.
It took me about 3 weeks to port the game where
Have you ported the game to MAC before? What was your experience? If you are porting the game from Windows to MAC and you have any similar problems you can always contact me and I will gladly share my knowledge with you.