Phil Hassey - game dev blog
Phil Hassey as Syndrome
"Look, stores don't sell
costumes like this to just anyone."

Archive for the 'development' Category

Paid game betas aren’t for everyone

Friday, January 7th, 2011

So, I just sent out my “hey everyone, come get a refund” email to all the people who purchased the Stealth Target beta. There are a number of pretty high-profile indie games that have built an entire business upon being a paid beta. Minecraft, Wolfire’s Overgrowth, Data Realm’s Cortex Command are a few that come to mind.

Here’s some analysis on the subject, and why it didn’t work for Stealth Target .. and at the same time, the factors I think that would be important to having a successful paid-beta project.

  • Commitment to a larger vision. In the case of Stealth Target, I had a larger vision, but I eventually realized it was too grand for me to realize.  I’m more of a small-scale game kind of guy at this point.  Perhaps later in my game development career I’ll be doing larger projects, but right now, a “Galcon-sized” game is about as large as I can manage.  I think paid-beta games need to be larger to justify the whole “user-buy in to help fund an epic game” concept.
  • Commitment to regular updates. I’m only one dev, and when I take a month to work on Galcon updates, and then take another month to take a break, suddenly the beta users haven’t heard a peep from me about the game in 3 months.  Pretty weak “paid beta”.  If I had a team and I had someone always working on the beta so it kept living despite my other obligations / plans, it might have gone better.
  • Building a development team. Yeah, I just touched on that, but it really does make sense.  I could have a team, but my lifestyle doesn’t allow for it at the moment.  My hours are too random and my work schedule too unpredictable.  To have a team you have to have some consistency in your life, otherwise (I’m pretty sure) your team-members will get pretty tired of you.  I think having a team would help deliver the quantity and quality of content and updates to make a paid beta make sense.
  • You can’t change your mind and be crazy. I still plan on finishing Stealth Target, however, I’m no longer planning on doing a desktop release of the game.  The paid beta was for a desktop version of the game.  So changing to a iOS-only plan really isn’t possible.  The only way to cleanly resolve this was to terminate the entire beta and issue refunds.  Really, for a paid-beta to make sense, the users have to have something they can depend on, and changing platforms mid-stream is just asking too much.

Anyway, to wrap it all up, here’s the email I sent out to folks who already bought the game today:

Hi,

Turns out the business model of doing a pre-beta-sale really doesn’t make sense for me.  I’m more of a “do what I feel like” kind of guy, and committing to making some sort of super-great-game in some kind of pre-beta-sale promise just isn’t something I can really do.  I think in the case of “Stealth Target” I bit off way more than I can chew.

I’m hoping to finish Stealth Target this year, but I’m probably only going to release it to mobile platforms, so I don’t even think I’m going to be launching a desktop version.

Either way .. I’m offering refunds to anyone who wants one!  Just reply to this email and say so.

Thanks for coping with a crazy indie-dev 🙂  Your support is greatly appreciated and I hope I can churn out some cool games that you’ll enjoy in 2011!

Cheers!
-Phil

P.S. Also, thanks for all the feedback you have given me so far on Stealth Target.  I’ve been taking notes on just about everything! You’ve been a huge help!

And, who knows what the future will hold for Stealth Target.  If the mobile version comes out feeling really good, I might try and release it for the desktop.  But the important thing for me is to know that I’m not obligated to produce a “desktop-sized” title when I’m really making a “mobile-sized” game.  I’ve got a lot of things I want to do this year, and I want to do them in the order that I want them to.  A paid-beta project would have “cramped my style” so to speak, and I don’t want to subject my users to a shoddy paid-beta experience.

Thanks!
-Phil

Part-time iOS game maintenance job for Galcon

Wednesday, November 17th, 2010

jobadI’m looking for someone who wants to do maintenance on my Galcon games for the iPhone. There are a ton of great features that really need to be added to the game, but I just don’t have time to do them all myself!

Galcon has large fanatical on-line multiplayer base who would absolutely love you if you were the one to help bring the features to the game that they are begging for!

While working together we would meet at least once a week to make plans and we would work towards being on a rather frequent app update schedule. The skills I’m looking for are:

– Proficient in C / C++ code and OpenGL.
– Strong experience with ObjectiveC / iOS.
– Knowing how to work with In App Purchases, Game Center, and iOS 4.x features a plus.
– You must own a Mac.
– You must own an iPhone / iPod touch. An iPad is a plus.
– Roughly 10-20 hours/week to start, this is flexible.
– Python or PHP experience is also a plus.
– Location: Anywhere! We’ll stay in contact virtually.

Contact me if you are interested, and tell me why you’re the best for the job! Payment would be hourly based on experience. This job has the potential to grow into a full-time position.

Thanks!
-Phil

Galcon for Sixense

Thursday, August 12th, 2010

I spent the first few days this week integrating Galcon with the Sixense motion controllers! It was a nice break from the work on the Android as I waited for a G1 to get shipped to me (I’m not sure if Galcon will work on the low-end phones yet, but I’m going to find out soon!)

galconsixense

Working with the Sixense was very different, the controllers are great, and it really provides a completely unique Galcon experience. I modified the game to allow all modes to be played Co-Op with multiple users (mouse + up to 4 Sixense controllers). And I also added a special Sixense Multi-player mode where you are divided into two teams and can play against each-other.

Like with any interface design I always try and fit Galcon to the device. In this case, I had to modify a few subtle things in the user interface to make it work just right with the Sixense. I also set one of the controller’s buttons to be a “Select-all” and a “Deselect-all” button, which makes it easy to do those common actions. So I think I’ve done a pretty good job matching the Sixense controller interface with the Galcon interface. You can also see in the screenshot that each controller gets a different color for their planet selection / action choices, and the crosshairs contains the Ships % information. The mouse player still goes off the standard Ships % that’s show in the bottom right corner.

All-in-all, I think this variant of Galcon is going to be a ton of fun! I have no idea when it will be available for people to play, but I’m sure it’ll be good times when it is!

-Phil

Porting to Palm / WebOS

Wednesday, July 14th, 2010

I’ve just completed and submitted my port of Galcon to the Palm. The entire process took 2.5 days. Here’s my play-by-play of the porting process. A huge thanks goes out to Mike Kasprzak for hand-holding me through the process and co-writing this post.  If you’re doing a Palm port, be sure to read the whole blog post over before you begin so you get the big picture.  Also, not everything is exactly in the right order, so that’ll give you the birds-eye view.

Day 1: Preparing the device for Development

11:00

– Unbox the Palm Pre Plus.

– Figure out how to plug in the USB.  This is a bit tricky, you gotta really yank on that plastic tab on the side to get it off.

11:30

– Use WebOS Doctor to flash the device with latest OS

http://ws.palm.com/webosdoctor/sorry.htm

12:00

– Activate phone.  If your phone isn’t activated, you use a program that can bypass activation

http://developer.palm.com/index.php?option=com_content&view=article&id=2051&Itemid=30

12:15

– Connected to local WiFi on activated device

12:30

– Final preparation of the device for development.

http://developer.palm.com/index.php?option=com_content&view=article&id=1973&Itemid=336

“Card view” is the view where you can see a view of all the open apps minimized. Apps are called Cards.

12:45

– ssh onto the device, password is blank

$ ssh -oPort=10022 root@localhost
root@localhost’s password:
root@palm-webos-device:/var/home/root#

1:00

– Install the Palm SDK and PDK, read whole document so you know where the cross-compiling binaries are located. It varies depending on windows / mac.

http://developer.palm.com/index.php?option=com_content&view=article&id=1970&Itemid=335

1:30

– Install a SSH key.  This way I don’t have to keep pressing return on the password entry during SSH sessions.

$ pdk-ssh-init localhost:10022

1:45

– Verify installation by using a Palm demo app.  This is an important step!  This step shows you where the example code and scripts are and you’ll be referring to those when you build your own build/deploy/packaging scripts for your own app.  And if it works, you know your Palm is ready to go!

http://developer.palm.com/index.php?option=com_content&view=article&id=1974&Itemid=336

– Errors about not finding various .so files can be ignored

– [This should be irrelevant as Palm gets their SDK’s and firmware all synced across the networks] The PDL_Init error is actually the device talking back to you.  I had to go into the src folder and comment out PDL_Init to get it to run. This error is due to the 1.4.1.1 firmware on my Palm Pre Plus .. 1.4.5 is required for apps.  Had to do some hacks to get around this, won’t bother explaining, as this shouldn’t matter in a few days.]

3:00

– Rebuild simple sample app with PDL_Init included, works fine

3:30

– Got a copy of Mike’s app and tried it out.  Works nicely.

Day 2: Porting the App

– 10:30

Hacking up the /opt/PalmPDK/share/samplecode/simple/mac example building, packaging and deployment scripts.  Mostly just getting them to work with my code.  Was pretty straightforward if you know shell stuff.  I’m doing my work on the Mac, so I have a bash shell at hand all the time.

– 11:30

Got it compiling with a few tweaks. using rsync over ssh to deploy my game 🙂  I’m a big fan of rsync.  Here’s my “deploy” script:

rsync -v -urt –exclude ‘*~’ –exclude tmp –exclude .svn -e “ssh -oPort=10022” ./out/ root@localhost:/media/internal/galcon

– 12:00

I had trouble loading images to textures.  But this was mostly due to my own dumbness.  Ended up being really straightforward.  Used SDL_image to load, converted it to 32 bit, then loaded it in.

– 1:30

.mp3’s won’t play with SDL_Mixer, so you must use oggs instead, check out this hack that I use to covert my “.mp3” extensions to “.ogg”:

sprintf(f,”%s/%s”,DRIVER_DATADIR,fname);
int l = strlen(f);f[l-3]=’o’;f[l-2]=’g’;f[l-1]=’g’;

– 1:45

SDL keyboard events not passing numbers when I use the Palm number presser key.

This is a palm bug, I should file a bug report. If the user holds down the NUMBER key, and then pressed a letter, they get the proper number.

-5:30

Handled SDL_ACTIVEEVENT to switch game into pause mode when being minimized.
if ((e.active.state&SDL_APPACTIVE)!=0 && e.active.gain == 0) { /* pause game */ }

– 6:00

Added a few PDL_ calls.  I’m really liking the set of lightweight functions they give you.  They cover most all the stuff you need for game integration in just a few calls.

http://developer.palm.com/index.php?option=com_content&view=article&id=1990&Itemid=340

#include “PDL.h”

PDL_Init(0); // in init function
PDL_GetCallingPath(char *buffer, int bufferLen); // to find out where our app is being launched from so i can find my data files
PDL_GetDataFilePath(char *dataFileName, char *buffer, int bufferLen); // find out where my app can write save games and settings.. the buffer is a fullpath to where we can save a file to
PDL_LaunchBrowser(const char* Url); // go to interwebs
PDL_Quit(); // wrap it up

Here are a few tips from Mike that I found really helpful:

About the Palm itself:

  • There’s a touch strip beneath the LCD screen. Gesture up or down from the middle of the strip to bring up the menu.
  • To “Card” (minimize) a running application, gesture upward or tap on the gesture strip
  • To close an application, throw the card away (up)
  • To delete an application, hold down the keyboard button with a square on it, then tap the icon of the app you want to remove.
  • When you plug a device in, Just Charge is the ideal mode. USB mode is useful for copying files via drag+drop, but you can’t run things while in USB mode

Linkable Libraries

  • -lSDL
  • -lGLES_CM (for OpenGL ES 1.1)
  • -lGLESv2 (for OpenGL ES 2.0)
  • -lSDL_mixer
  • -lpdl (Palm specific calls)

SDL Tips

The following call is required BEFORE setting your graphics mode, yet after initializing SDL

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);

The number represents the OpenGL ES version. 1 for 1.1, 2 for 2.0.

webOS actually supports blending what you do against hardware decoded video. Unfortunately, this feature is on by default. The alpha value in the frame buffer decides weather video will bleed through or not (even if no video is displayed). To disable writing Alpha to the framebuffer, use this call.

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);

Day 2.5: Packaging the App

Time to figure out how to package this into a sellable .. package!  I used Mike’s app and found that we really don’t need all the skeleton stuff palm-generate can generate for you.

http://developer.palm.com/index.php?option=com_content&view=article&id=1976&Itemid=375

You need an appinfo.json file in your distribution folder. It should contain something like this:
{
“id”: “com.galcon.app.igalcon”,
“version”: “1.9.8”,
“vendor”: “GALCON.COM”,
“type”: “pdk”,
“main”: “galcon”,
“title”: “Galcon”,
“icon”: “icon.png”,
“requiredMemory”: 48
}

I ssh’d in and used top to figure out my required memory.

And also a framework_config.json containing:
{
“logLevel”: 99,
“debuggingEnabled”: true,
“timingEnabled”: false,
“logEvents”: false,
“escapeHTMLInTemplates” : true
}

And lastly, I gotta include icon.png . Palm specifies this:

“Application icons should be 1 in. square, 64 x 64 pixels, encoded as a PNG with 24 bit/pixel RGB and 8 bits alpha. The icon’s image should be about 56 x 56 pixels within the PNG bounds.”

And lastly create this file:
package.properties containing:
filemode.755=your_app_binary

Then just copy all those files, and the app files into a folder named the same as your app id (com.galcon.app.igalcon for example) then run palm-package against that folder and you’re done!  Here’s a checklist from Palm that helped me through a few things:

http://developer.palm.com/blog/2010/07/a-quick-pdk-submission-checklist/

Then you just send that app package off to Palm! Have fun!

-Phil

Galcon Fusion for the iPad

Saturday, April 3rd, 2010

galcon-ipad-rainbowSo Galcon Fusion is available for the iPad.

Here’s a bit of tech stuff for ya! The port itself took about 3 days. If you check out the screenshots, you can see I letterboxed the desktop version of Galcon Fusion, and used that extra area to put the iPad specific controls (the pause button, the chat activation button, and the ships % “mouse wheel”)

I don’t have an iPad yet, but I think it’s going to work pretty well. The multi-touch interface design was all done ages ago for the iPhone, so I just used that code for this. It should work great!

The biggest challenge in porting was dealing with OpenGL stack limits on the iPad which appear to be 16 levels. My GUI used quite a few Push/Pop’s to achieve various theme effects and whatnot, but that was blowing the stack. It took me a bit, but I was able to find a number of places where I was able to remove those uses of the stack and things seemed to work fine. (There are some edge cases where my changes wouldn’t be safe, but none of my code uses those, so no harm!)

Anyway, I’m really looking forward to getting an iPad and seeing how the iPad users stack up against the mouse users. This will really pit two different interfaces against each other, which should be really neat. Both interfaces have their own advantages!

As always, python proved useful in this project as I had to update all my graphical assets for the game to work with the iPad. Since my asset pipeline was written in python and pygame, it only took a couple minutes to add in the code I needed to fix a few issues. And thankfully these fixes will go forward and improve my desktop version as well, so all and all, a good deal.

-Phil

P.S. In other news, I’ve been playing with django lately for my non-games business. It’s slick!

Update: Since I was unable to test Galcon Fusion on a REAL iPad it has bugs 🙁 Apparently the multi-player game crashes and the framerate is low. I’ll be getting my iPad on Monday and fixing those issues ASAP! There’s probably some kind of “testing on real hardware is smart” kind of lesson in this somewhere …

FEAR THE PANDA

Tuesday, March 2nd, 2010

Yeah, you better …

pandapromo

This image represents the last few days of work.  I have ported some 3000 lines of python code to tinypyC++ code.  Fear it.

-Phil

The Galcon Fusion beta testers rocked

Thursday, February 11th, 2010

Galcon Fusion has arrived.“Yay, it’s finally here! Check out Galcon Fusion today! We’ve got a free demo and it works on Windows, Mac OS X, Linux, and Steam! It features some crazy nice hi-res graphics and soundtrack. And epic multi-player battles like you’ve never seen ‘em before! Have fun!” <– marketing blurb 😉

Okay, for some dev thoughts. Man, it was a long week! Adding the “demo” feature to the build was a ton of work. And then doing all that other ‘stuff’ that sort of comes up. I think the one serious lesson I’ve learned in this whole process is that beta-testers are awesome.

Really awesome. I had about 50 people who I passed out 10 builds of the game to over the past 3 months. Some of these people put in several dozen hours of play time. All this was a huge help for me, as this was my first desktop ‘3D’ game, so I had a lot of learning to do in terms of graphics capabilities. As in, I was able to get the game to run on my computer which is a pretty nice MacBook Pro .. but not everyone else’s.

The beta tester feedback was huge, I was able to get the game running on old PPC macs, various linux netbooks, and who knows what else .. as long as it had a somewhat reasonable 3D card. I changed the memory requirement for graphics from about 200 MB down to < 64MB. Without any noticeable reduction in graphics quality even in HD video modes. In fact, that reduction changed the loading time on my computer from 5-8 seconds down to about 1 second 🙂 Anyway, I think I'm going to take a nap. It's been a long week, and I really appreciate everyone who helped me get this game put together. Give it a whirl, and thank the beta testers!

5 awkward and 5 awesome things about lua …

Friday, January 29th, 2010

Hey,

I’ve been spending some time checking out lua, because I’m thinking about using it for scripting in games.  I’m looking at it instead of tinypy because tinypy is slow and really needs some more TLC to be totally useful to me.  However, after looking at lua for a while, I’m finding the things that make it feel awkward to me.

  1. List indexes starting at 1.
  2. For loops use [a,b] intervals
  3. No += operator.
  4. do / end keywords instead of { }
  5. List and Dict types combined into one

At the same time, I’ve found that lua is totally awesome.  I mean, wow.  Really slick stuff!  Here’s 5 awesome things:

  1. Small codebase
  2. Faster than other dynamic languages
  3. Easy API integration
  4. Coroutines <- these are neat!
  5. State is serializable

So here are my thoughts:

  • The first 4 awkward things are superficial, I could probably hack those into shape in a day or two.  The 5th item (List + Dict) as one item is probably not something I can fix, but I could probably live with it.
  • If I changed the language like that, and provided it for users to create mods for my games I would not be able to give them a link to the lua documentation, since it would not be accurate anymore.

Not quite sure what to do here.  Lua seems great, though a few language design decisions seem awkward to me.  I could change the language easily enough, but then I would be breaking all the lua documentation for my users.

Anyone got some language-design thoughts on this one?

-Phil

Galcon Fusion announced – Finally!

Friday, January 29th, 2010

Hey,

So, I’m finally announcing Galcon Fusion to the world.  Fusion is a port of iPhone Galcon + Galcon Labs to the desktop.  This time with hi-def graphics and a full interactive soundtrack.  It’s going to be coming to Steam and direct on my website on Feb. 11.  Users who supported me when I was first starting (as in, you bought desktop Galcon), your license is compatible with Galcon Fusion.  Thanks!

fusion-pink-green

There are a few technical things that were challenging, dealing with endiannes for my network code, supporting fullscreen vs widescreen resolutions, and supporting a wide range of resolutions (from 800×600 all the way up to 1920×1080.)  To make it short, here are a few conclusions: best to support endiannes from the start, fullscreen vs widescreen is a pain, and baking lots of image data into your binary is a pain because it requires a ton of recompilation.  Oh, and installing VC++2008 is waaaay easier than installing mingw32, but keeping code working on both takes more effort.

I think my biggest conclusion comes along with this announcement, is that doing “secret dev” work isn’t really that sensible.  If you look at that last paragraph, there are a ton of issues I could have documented in my blog that I didn’t because I was all being secretive.  And hey, since I was so mum on this, nobody has heard about it until today.  I guess there might be some benefits to this (??) but I can’t think of what they are.  I think blogging about my progress is a good way for me to be able to see what I’m doing and not get lost in the haze myself.  My recent article on VC++2008 is a great example of something I’m going to get quite a bit of value out of just for my own reference.

One big different thing I’m doing with this project is my wife Nan is doing the PR for it.  She’s contacting all the reviewers, the general press, the newsletters, the announcement blog, twitter, and everything.  I’m trying to take a more dev-only role in the announcement.  This is nice, because I’m not very good on PR.  I try .. but I really don’t do it as well as I want to, largely because on a launch of a product I’ve always got about 50 technical things I’m trying to do along with the PR!

-Phil

VisualC++ 2008 for gcc / SDL people

Thursday, January 14th, 2010

I’ve had to port a project to VC 2008 from my usual mingw setup.  Here’s what I did.  This covers quite a few things, in particular where to find common GCC settings in VC land.

Setting up the project
  1. New project
  2. Type: win32
  3. Template: Win32 console if you want a console.  Or just Win32 Project if you don’t want the console to pop up.
  4. Choose a name for your project
  5. The solution name is the folder everything gets put in.  In VC, you can have several projects within a single solution.
  6. On App settings, I choose Windows application, Empty project

Adding the source files

  1. I right click on my project name and Add>New filter, and use that to bundle a few different sets of source files together
  2. This is done so that VC will compile the files, but keep in mind that the separations don’t seem to mean anything to VC.  It’s just for your visual convenience.
  3. Note that if there are two files with the same base name “dostuff.c” and “dostuff.cc” this will cause VC to choke during compilation as it will create two .obj files with the same name and fail during linking.
  4. VC doesn’t support C99 so any C99 files will have to be Right Click > Properties > C/C++ > Advanced > Compile as > C++ Code

Note: a Project can have a number Configurations (Debug, Release ..) If you are targeting a certain distribution site with some special requirements you can add more Configurations via Solution > Properties > Configuration Manager >

Compilation Options

Adding some project compile time options (mainly -D and -I equivalents for specific defines and include folders.)  Keep in mind which Configuration you are modifying at all times.  You can also switch to “All Configurations” for global changes.

  1. (GCC -I)  To add in include folders, Project > Configuration Properties > C/C++ > General > Additional Include Directories > … I found with include folders you often need to stack on a few ../../’s to get it to point at what you want it to point at.  (In my project I’ve got my VC project separate from all my source code, so everything is up and over a few folders.)
  2. (GCC -D)  To add in defines, Project > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions > .. I often add a few of these to tell the code what build we’re doing.  (iPhone vs, Windows, vs Linux, etc)
  3. (GCC -W)  Although warnings might be useful .. They made it impossible to see the errors.  You can turn down the warnings from level 3 to 1 in Project > Configuration Properties > C/C++ > General > Warning Level >
  4. (GCC -l)  Linked libraries are probably going to be needed.  Again in my project I’ve often got a few ../../’s in the paths.  Here’s where you add this stuff: Project > Configuration Properties > Linker > Input > Additional Dependencies >
  5. .. an alternate way is to add #pragma comment(lib,”MyLib.lib”) into your main.cpp.  By doing this you can refer to a lib right within your source if you prefer.
  6. For whatever reason, you may need to exclude some libs from being compiled into your project.  (If you see errors like “_tolower already defined in MSVCRTD.lib, etc).  You can exclude a lib in Project > Configuration Properties > Linker > Input > Ignore Specific Library > .. (in my case, I had to add msvcrt.lib and libcmt.lib)
  7. For my project I needed to expand the size of my stack, due to having excessive amounts of static data compiled into the project.  You can do this via Project > Config Properties > Linker > System > Stack (Reserve&Commit) Size > .. I changed them both to 4000000 and things worked.

Final packaging

I found that running right from VC didn’t always work. (Maybe I should find out why, but I haven’t.)  But I can run from the command-line.  Before doing so, I needed to:

  1. Copy in required dlls from SDL, etc
  2. Copy in game data files
  3. Copy in the VC Runtime files from: C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT
  4. For a release build I’m sure to build against SDLmain_nostdio.lib so that the game won’t crash Vista/Win7 where writing out stdout.txt and stderr.txt may result in some kind of fail.

Saving to Your_Favorite_Version_Control_System

  1. You may leave out all your ‘Debug’ folders or other Configuration folders, those seem to only contain generated files.
  2. You may leave out the .ncb and the .COMPUTER.username.blah file, they seem to be used by VC for stuff that can be regenerated, etc.

Hopefully this will be helpful to anyone who does the same thing.  Between you and me, I found the install of VC 2008 to be pretty nice in comparison to trying to install mingw, which tends to require considerable muscling.  Also, since everyone provides their libs as MSVC libs, building against those vendor libs is not only easy, but possible.  (With mingw, many MSVC C++ libs are unusable due to binary incompatibility.)

-Phil

P.S. Adding an Icon to your Project

This is pretty easy.  Add a Project.rc to your project.  The Project.rc should include this line:

IDI_PROJECT       ICON         “path/to/icon256.ico”

You can create an Icon with IconFX .

P.S.S. Creating a windows Installer

I’ve used Innosetup in the past.  It seems to work.

P.S.S.S. Dealing with LPCTSTR conversions

If your whole project is using C-strings, you can go into Project > Properties > Configuration Properties > General > Character Set > and change it to “Not Set” so that VC will no longer try and use Unicode strings to some of its functions (like ShellExecute.)

P.S.S.S.S. Dealing with conflicting .obj files

If you get a linking error about a bunch of undefined symbols and you have say “game.c” and “game.cpp” in your project, they are both being compiled down to “game.obj” .. To set one of them to compile to a different filename, say “mygame.obj”, you need to Right Click > C/C++ > Output Files > Object File Name > “$(IntDir)\mygame.obj”

Alternately, you can just rename some of your source files so there are no name conflicts by default.