Spacecrash day 6 of 7: installers and more
So let’s do the last remaining piece of the puzzle. If you are going to deliver your game to players, you will have to package it nicely for them to download and install. The packaging process is different for newer platforms such as iOS or the Android Google Play marketplaces, but for Windows and OS X, this means building an installer. This will package everything nicely together in a single file that the user can download and double-click, and which will leave the game in the conventional location for installed apps on their system.
Since we are doing Windows and OS X mainly, I will build installers for these. I use package managers for Linux, but I haven’t really looked into how those are built – if anyone can shed some light about this in the comments, together with how to tackle the multiple-incompatible-Linux-package-managers issue, I will be grateful!
Installer for Windows
I have been developing and selling ViEmu for many years, and the best solution I’ve found to easily build installers is Microsoft’s own open and free WiX toolset. This system allows you to build an install script in XML format according to the WiX documentation, and can then compile this into an MSI installer package which users can just double-click to get it installed. You may prefer to have an EXE installer, and this is doable using a small “stub file”, but to keep things simple, we will go with the MSI format. This is the official Microsoft-sanctioned installer format, and it is recognized on all versions of Windows in the last decade or so.
First thing you need to do is to download the toolset and install it. Next thing to do: create a “winsetup” directory under the main project root directory. We are going to put two files in here: a “deploy.bat” script that does the process, and a “spacecrash.wxs” which is the actual WiX installer script. We also need to put a subdirectory called “Binary” with a few standard resources for the installer (mainly icons).
Here is the deploy.bat file for you to see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
md release md release\SourceDir md release\SourceDir\Spacecrash md release\SourceDir\Spacecrash\data md release\Binary copy Binary\*.* release\Binary copy spacecrash.wxs release\spacecrash.wxs copy ..\scwin\release\scwin.exe release\SourceDir\Spacecrash\scwin.exe copy ..\scwin\release\scwin.pdb release\SourceDir\Spacecrash\scwin.pdb xcopy /S ..\data release\SourceDir\Spacecrash\data cd release "%WIX%bin\candle" spacecrash.wxs "%WIX%bin\light" spacecrash.wixobj cd .. |
This is pretty simple. It relies on the executable having been compiled by Visual Studio in ..\scwin\release. It creates a “release” subirectory where it copies everything, and it then invokes “candle” and “light”, the compiler and linker from the WiX toolset to build the installer. The process will leave the MSI file inside the “release” directory. You may want to rename it to include the version number, but that’s about it.
On the other hand, building the spacecrash.wxs installer script can be a bit tricky. I have relied on the installer base I have which I use for ViEmu, which in turn was based in a sample installer Microsoft provided. Since what we want is actually very simple (just copy the files in a “Spacecrash” subdirectory in “Program Files”, and add a start menu shortcut to launch the game), doing this is fairly trivial.
Here is a small sampling of the spacecrash.wxs file, so that you have an idea of how it looks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<?xml version="1.0" encoding="utf-8"?> <?define Manufacturer = "Symnum Systems SL" ?> <?define FullVersion = "0.9.0" ?> <?define ShortVersion = "0.8" ?> <?define MaxUpgrade = "0.7.99" ?> <?define ProductCode = "{0E9B86AD-D4A1-411C-BD41-9EBA94BCB120}" ?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Product Id="$(var.ProductCode)" Language="1033" UpgradeCode="5B057D5E-38B7-48EA-99AB-C4DC2DDB3741" Version="$(var.FullVersion)" Name="Spacecrash for Windows $(var.ShortVersion)" Manufacturer="Symnum Systems SL"> <Package Keywords="Installer, MSI, Database" Description="Spacecrash" Comments="Spacecrash for Windows $(var.ShortVersion)" Manufacturer="Symnum Systems SL" InstallerVersion="110" Languages="1033" Compressed="yes" SummaryCodepage="1252" ReadOnly="no" /> <Property Id="MYUPGRADEACTIONPROPERTY" Secure="yes" /> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="SCDIR" Name="Spacecrash"> <Component Id="SCCore" Guid="E2C82921-0DAD-45DF-AFAE-37781DF7B64E" Location="either"> <File Id="scwin.exe" Name="scwin.exe" KeyPath="yes" DiskId="1" /> </Component> <Directory Id="DATADIR" Name="data"> <Component Id="SCData" Guid="8A39402B-8D60-48B2-A509-A90DBD3E6552" Location="either"> <File Id="bkg0.bmp" Name="bkg0.bmp" KeyPath="yes" DiskId="1" /> <File Id="x171671__fins__success_1.wav" Name="171671__fins__success-1.wav" DiskId="1" /> <File Id="x410__tictacshutup__thump_1.wav" Name="410__tictacshutup__thump-1.wav" DiskId="1" /> <File Id="x94185__nbs_dark__explosion.wav" Name="94185__nbs-dark__explosion.wav" DiskId="1" /> <File Id="Drone0.bmp" Name="Drone0.bmp" DiskId="1" /> <File Id="Drone1.bmp" Name="Drone1.bmp" DiskId="1" /> <File Id="Drone2.bmp" Name="Drone2.bmp" DiskId="1" /> <File Id="Energy.bmp" Name="Energy.bmp" DiskId="1" /> <File Id="Fuel.bmp" Name="Fuel.bmp" DiskId="1" /> <File Id="Juice.bmp" Name="Juice.bmp" DiskId="1" /> <File Id="Kromasky.bmp" Name="Kromasky.bmp" DiskId="1" /> <File Id="Mine.bmp" Name="Mine.bmp" DiskId="1" /> <File Id="Particle.bmp" Name="Particle.bmp" DiskId="1" /> <File Id="Pearl.bmp" Name="Pearl.bmp" DiskId="1" /> <File Id="Rock0.bmp" Name="Rock0.bmp" DiskId="1" /> <File Id="Rock1.bmp" Name="Rock1.bmp" DiskId="1" /> <File Id="Rock2.bmp" Name="Rock2.bmp" DiskId="1" /> <File Id="Rock3.bmp" Name="Rock3.bmp" DiskId="1" /> <File Id="Rock4.bmp" Name="Rock4.bmp" DiskId="1" /> <File Id="Rocket.bmp" Name="Rocket.bmp" DiskId="1" /> <File Id="ShipC.bmp" Name="ShipC.bmp" DiskId="1" /> <File Id="ShipL.bmp" Name="ShipL.bmp" DiskId="1" /> <File Id="ShipLL.bmp" Name="ShipLL.bmp" DiskId="1" /> <File Id="ShipR.bmp" Name="ShipR.bmp" DiskId="1" /> <File Id="ShipRR.bmp" Name="ShipRR.bmp" DiskId="1" /> <File Id="Star.bmp" Name="Star.bmp" DiskId="1" /> <File Id="ffff.wav" Name="ffff.wav" DiskId="1" /> </Component> <Directory Id="tiles" Name="tiles"> <Directory Id="sp" Name="sp"> <Component Id="tiles_sp" Guid="CAB41852-2E21-4542-A853-4BED2E043F96" Location="either"> <File Id="pppp.bmp" Name="pppp.bmp" KeyPath="yes" DiskId="1" /> <File Id="ppps.bmp" Name="ppps.bmp" DiskId="1" /> <File Id="ppsp.bmp" Name="ppsp.bmp" DiskId="1" /> <File Id="ppss.bmp" Name="ppss.bmp" DiskId="1" /> <File Id="pspp.bmp" Name="pspp.bmp" DiskId="1" /> <File Id="psps.bmp" Name="psps.bmp" DiskId="1" /> <File Id="pssp.bmp" Name="pssp.bmp" DiskId="1" /> <File Id="psss.bmp" Name="psss.bmp" DiskId="1" /> <File Id="sppp.bmp" Name="sppp.bmp" DiskId="1" /> <File Id="spps.bmp" Name="spps.bmp" DiskId="1" /> <File Id="spsp.bmp" Name="spsp.bmp" DiskId="1" /> <File Id="spss.bmp" Name="spss.bmp" DiskId="1" /> <File Id="sspp.bmp" Name="sspp.bmp" DiskId="1" /> <File Id="ssps.bmp" Name="ssps.bmp" DiskId="1" /> <File Id="sssp.bmp" Name="sssp.bmp" DiskId="1" /> <File Id="sp_ssss.bmp" Name="ssss.bmp" DiskId="1" /> </Component> </Directory> ... |
There is one missing thing here yet: our executable doesn’t have an icon! It’s easy to fix this, just prepare and add an .ICO file to the Visual Studio project, and you will be done. I will try to do this before the final release.
In any case, you can download the current Windows installation file here: Spacecrash-0.8.msi.
Important note about runtime DLLs: I changed the configuration of the Visual Studio project to make sure the program doesn’t need any C runtime DLLs. The way to do is it to go to project properties, C/C++, Code Generation, and configure Runtime Library to “Multi-threaded (/MT)” for Release, and “Multi-threaded Debug (/MTd)” for Debug. This eases our installation work since everything is contained in the scwin.exe file.
Installer for Mac OS X
On the Mac, the common format for applications is the “app bundle”, which is just a package that contains all the application code and resources (it’s actually a directory, although the user isn’t necessarily aware since it looks like a file). This package can just be dragged to the main “Applications” folder and the installation is done.
Somewhat surprisingly, this is quite easy to set up. The easiest way is to create a new Xcode project (from scratch), this time selecting “Cocoa application” instead of command-line application. The reason this helps is that Cocoa application projects are set up to be built into an “app bundle” by default, and we can use that mechanism. Remove all the files that the system puts into the project, and add back all the cpp and h files we had in the previous project: game.cpp, base.h, core.h and core.cpp, sys.h and sys_osx.cpp, and stdafx.h. Now, do the same adjustments we did for the original project: add the “-lglfw” linker flag, add “/usr/local/include” to the Header Search Paths and “/usr/local/lib” to the Librayr Search Paths, and make sure the following four frameworks are added: Cocoa.framework, IOKit.framework, OpenGL.framework and OpenAL.framework (you can add these easily in the “Build Phases” tab, “Link Binary With Libraries” section). One last important thing you have to do: right click on the root “Spacecrash” folder in the project, click “Add Files to Spacecrash…”, find the “data” subdirectory where all textures and sound files are, and select the option “Create folder references for any added folders”. Now when you click “Add”, a blue folder will appear in the project tree (instead of the standard yellow folder). This means this folder with all its contents will be copied to the app bundle resources, keeping the directory structure. That way, when the game looks for a file with the name “data/tiles/sp/ssss.bmp”, it will find it there, since the resources directory is the default directory when running the application.
Finally, with all this set up, choose “Product”, “Archive” from the menu. This will build the project and open the organizer (you can open the organizer manually too with the button on the top-right of the main Xcode window). If you click on the “Spacecrash” archive you will have there, click “Distribute…”, “Export as Application”, and ask not to re-sign, you can select where to put the bundle. So we got the redistributable bundle! Double-click on it and you will see that the game starts up perfectly. Moving it to your “Applications” directory would be all that’s needed for full installation (all Mac OS X users are accustomed to doing that).
There is only one last step missing: bundles cannot be directly distributed, you need to create a DMG disk volume to distribute it. This is how to do it: first thing, note the size of the app bundle (right-click and “Get info”, in my case, 3.9Mb). Then, open the OS X built-in “Disk utility”, and select “New Image”. Select the smallest size that fits the size we need (so for us, 10Mb), leave all options by default (no encryption, read/write, Mac journaled) and click ok. You can now use finder to drag the Spacecrash app bundle to the volume and unmount the volume. As a final step, select the new DMG image in Disk Utility (it’s on the left pane), click on “Convert” on the tool bar, and select “compressed”. This will compress the image and let you upload a small file for distribution. Deal done!
Here you have the current OS X DMG installation file here: Spacecrash-0.8.dmg.
Two notes: first, also in OS X, we are missing an application icon. I will try to do this last step before the full final official 1.0 release tomorrow. And second, we could have used this type of “Cocoa app” project template instead of a command-line template. It’s a bit different when debugging, since you can’t force the working directory (it always uses the path where the bundle is built), but since the data is copied anyway, you should be fine. I just tend to the non-OSX way of working here, with code and data completely separated.
Next steps
I’ve completeted my goal for today, which was building the installers. But I’m still not done. Here is my pending task list for you to realize where we are in the development of the game:
Fix bugs:
- Random bkg TexId crash bug
- UI drawn to main menu
- Sound should stop in in-game menu
- Dont modify bkg random terrain probability while in main menu
In-game UI:
- Do!
Gameplay:
- Remove fuel
- Remove braking
- Balanced, structured, compelling challenge generation
- Drones’ behavior
Pending things:
- Sound effects
- Explosions
- Save options & progress to file
- Music
Polish:
- Icon!
- “Spacecrash” banner in main menu
- “Mission completed” and “Get ready” banners
- Darker color for unavailable levels in menu
- Reorganize the code a bit
As you see, plenty of stuff to do. I can’t do everything between today and tomorrow, but I’ll try to prioritize the most critical things and get to something decent by the end of tomorrow. It seems likely that I will prioritize the bugs & the missing things (sound, music, explossions), and get a stab at the other things as time permits. This way, there will be a complete game by the end of tomorrow, one week as promised, and representative of what can be done in a week with the proper focus. Again, I’m sure to put in one or two extra days next week, to turn the gameplay into a compelling challenge and progression, and do those last-minute polish details that add so much to a game experience!
But for now, it’s Saturday evening, I’m exhausted after the long week, and the top priority for me is to disconnect a bit. See you tomorrow!
And if you want to be notified when new articles to help you become a games developer are ready, just fill in the form below:
[…] Spacecrash day 6 of 7: installers and more […]