Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: The standard Mac application structure  (Read 881 times)

Vigil

  • Escaped Lunatic
    • View Profile
    • http://washboardabs.net
The standard Mac application structure
« on: March 02, 2008, 08:31:00 am »

Hi all, first post! As a PC->Mac switcher and wannabe application programmer, I wanted to highlight some of the differences in how Mac applications are usually arranged compared to PC applications. Please don't take this as a why-didnt-you-do-this, but as an it-would-be-nice-if.

Currently, Dwarf Fortress works like most other PC->Mac game ports: a barebones .app file is generated for the game, containing nothing but the executable and the icon, and the directory structure common to the PC version is carried over intact. This requires the user to store the application, its support files and its savegames in a single folder. As I say this is par for the course for ported games, but it doesn't fit in well with the Mac way of doing things.

A Mac .app package is actually a carefully-arranged bundle of folders presented as a single file. This bundle wraps up the application's executable, its icons, its metadata (file associations, title, version etc.), its interface strings (including all localizations), any frameworks it depends on, and and any other resources the application needs in order to run: in the case of Dwarf Fortress, the contents of the data folder. Literally all you need to launch a standard Mac application is the .app file itself, which you can store wherever you like in the filesystem or give to someone else or whatever, without worrying that you need to install additional files or libraries or that you've left something out when distributing it.

The .app file should not modify itself at runtime however, which means that support files have to be stored externally to the .app package. Preference files for applications are stored in ~/Library/Preferences/. Modifiable files that the application depends on (such as savegames or world data) are stored in ~/Library/Application Support/<Application>; this is also where any override files such as plugins or replacement tilesets would be placed by the user. Temporary cache files are stored in  ~/Library/Application Support/Caches/<Application>, which allows them to be safely wiped by the system during maintenance or cleanup. Files exported by the user, like screenshots or map dumps, should end up in ~/Desktop where they're most accessible. Note that all of these folders are per-user: ~/ is a shortcut to the user's home folder, as on other Unix-based systems.

Native Mac applications generate their own support files and folders if they are missing (i.e. the first time that user runs the application), so this structure is transparent to the user - all they need to be concerned about is the .app file itself.

Of course for a ported game project, all this means a lot of extra programming work: special paths specific to the Mac port and automatic creation of missing support files (the least disruptive way to handle this would be to copy default preferences and support files stored in the .app bundle). It means additional documentation for how to hack on the game, Mac-specific notes for mods as to where to place their files, and so on.

As far as I know, none of the cross-platform toolkits make the Mac-native folder structure obvious or easy - instead they seem to actively obstruct it - so it's no wonder that so few ported games bother or are even aware of the standard structure. The benefits to the user from this application structure are less important from a development perspective than the game itself as well. Nevertheless, there are considerable benefits to the user - so please bear these conventions in mind for future versions when or if the time becomes available.

And keep up the good work of course!

Logged

peterb

  • Bay Watcher
    • View Profile
Re: The standard Mac application structure
« Reply #1 on: March 02, 2008, 10:16:00 am »

Vigil is right.  I agree that this falls into the "not at all essential, but would be nice" category.

DF on OS X is technically already an application bundle, so it wouldn't require a lot of work to finish this up.  One typical way to do this for an application would be:

-anything that should go into the "application bundle" (eg, most of the stuff in the "data" and "raw" folders, not including the save and movies subfolders) would get added to the "Resources" folder in the Xcode project file.  Xcode should then move all that stuff into the Resources folder in the Dwarf Fortress bundle.
-the user-specific stuff, as Vigil implies, gets created (if it doesn't exist) in ~/Library/Application Support.  There is API (see below) to programmatically find "the right place", so you don't have to hardcode strings throughout your app.

From a practical standpoint, the way I'd do this is as follows:
1. everything that looks for a resource or a directory to write to (eg for saves) calls a method asking for the right path to the resource.
2. On Windows, those methods would return whatever they currently do now.
3. On OS X, the "resource" methods would return CFBundleCopyResourcesDirectoryURL() and the "user-specific" methods would return CFBundleCopySupportFilesDirectoryURL() (assuming your wrapper is in C/C++.  if it's in Objective C, you could use something like [[NSBundle mainBundle]sharedSupportPath] to find the applications support directory.

Then as long as your own code uses your internal accessors, you should get everything else "for free" (and it probably becomes easier to port to Linux, later, too.

NSBundle guide: http://developer.apple.com/doc umentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/Reference/Reference.html#//apple_ref/doc/uid/20000214
(That's objective-C.  The corresponding C/C++ class is CFBundle, here:  http://developer.apple.com/documentation/CoreFoundation/Reference/CFBun dleRef/Reference/reference.html)

Again, I agree with Vigil that this isn't going to stop anyone from playing DF, and I'd expect the priority would be super-low.  But I wanted to share the info anyway, just so you can sort of see the mindset Mac developers live in:  assume a slightly greater code complexity in return for making the end-user experience as simple as possible.

[ March 04, 2008: Message edited by: peterb ]

Logged

Toady One

  • The Great
    • View Profile
    • http://www.bay12games.com
Re: The standard Mac application structure
« Reply #2 on: March 02, 2008, 11:54:00 pm »

So how would something like the raw creatures be handled?  I suppose there'd have to be additional options to specify how it's done?  If a person supplies half of the creatures, the game wouldn't know if it should generate them itself (as I gather it would if nothing is supplied) or if the creatures were intentionally left out by the player.  That sort of distinction seems like it would really demand quite a bit of the World Generation Parameters Arc to be completed before it could be implemented properly, while with the current format it's easy.  Is that what you mean by more code complexity?  It sounds like a potentially large project.
Logged
The Toad, a Natural Resource:  Preserve yours today!

Vigil

  • Escaped Lunatic
    • View Profile
    • http://washboardabs.net
Re: The standard Mac application structure
« Reply #3 on: March 03, 2008, 06:10:00 am »

Thanks for the insider's perspective peter!  :)

So I take it that currently, if a user deletes a raw creature file then that creature will be left unused - and you mean that DF would be unable to tell the difference between a deleted creature file and a creature file it hasn't created yet?

One solution (which sounds like it would fit with how the game works at the moment) would be to check for the existence of the raw folder in DF's application support folder, rather than checking for individual files. If the folder isn't there, create it and populate it with the default creature files; if the folder is there though, then assume that whatever is in there is what the player wants to use.

That would cause problems when upgrading though... if new (default) creature files are added by future versions of DF then the game wouldn't know to update the raw folder with them.

Logged

Morlark

  • Bay Watcher
    • View Profile
    • Morlark's Blog
Re: The standard Mac application structure
« Reply #4 on: March 03, 2008, 08:18:00 am »

Eh, much of this is true of Windows structure too, e.g. anything user-modifiable, or anything that gets modified when the user runs the program is supposed to go in ~/Application Data/<Application> (even though Windows doesn't actually use ~ for the home directory, it's quicker than looking up and typing out what the relevant environment variable is called, and you know what I mean anyway). Although even then, many Windows applications ignore this and just put stuff in ~/My Documents/<Application>, and I note that many applications that are ported over from Unix-type OSes put stuff directly in ~/.<Application> so there's a whole lot of inconsistency in where programmers actually put stuff on Windows.

Edit: Erm, seems I managed to leave out the point I was actually trying to make. Which is that since the structures are fairly similar between Mac and Windows anyway, it's probably slightly less extra work to make both systems use a consistent structure rather than using two completely different structures. (Of course the DF fan in me wants things to stay as they are, so that Toady can move on to adding more awesome new features, but the OS purist in me thinks that everything must go in its correct place. Up to Toady I guess.  :p)

[ March 03, 2008: Message edited by: Morlark ]

Logged

numerobis

  • Bay Watcher
    • View Profile
Re: The standard Mac application structure
« Reply #5 on: March 03, 2008, 07:34:00 pm »

quote:
Originally posted by Toady One:
<STRONG>So how would something like the raw creatures be handled?</STRONG>

I don't understand how these suggestions change anything w.r.t. the raws.  They just move from being siblings of the .app to being subdirectories of the .app.  If modders want to mod, currently, they have to change the raws in the DF directory, and thenceforth the DF executable reads the modded raws.  That behaviour is identical in peterb's (and, I think, vigil's) suggested repackaging.

Doing otherwise would be kind of nice, so you can have a single DF install and many mods; but that's, as you point out, not entirely trivial.

Logged

Drunken

  • Bay Watcher
    • View Profile
Re: The standard Mac application structure
« Reply #6 on: March 03, 2008, 08:04:00 pm »

As someone who uses both macs and PCs on a regular basis, I want to point out that the PC->Mac Port method of doing things works far better for me. I hate in either system when when my software tells me where in my file structure I should put things. I have my own system of organising my machines and it is based on what is practical and convenient for me, not what is practical and convenient for some hypothetical average user. The main difference being that as a hardcore gamer I always have a whole hard disk dedicated to all my game data. In both osx and windows applications are expected to go into your operating system drive in a specific place (c :program files or applications) and all your application user data to another separate folder (c: my documents or /library/application support). This drives me nuts and the idea that someone would post complaining about a software designer *not* forcing this arbitrary system on them seems a little strange. I'm not criticising though, what works for me is not necessarily for everyone. On Mac OS at least you don't have to periodically reformat your operating system drive, but I still prefer my OS drive to only contain OS specific software. My game and media drives are interchangeable between computers and can simply be inserted into another machine when I upgrade in lieu of copying all the data over ethernet.
Logged
A stopped clock is right for exactly two infinitessimal moments every day.
A working clock on the other hand is almost never ever exactly right.

Nesoo

  • Bay Watcher
    • View Profile
Re: The standard Mac application structure
« Reply #7 on: March 03, 2008, 09:41:00 pm »

I agree completely, Drunken. I use one hard drive for my system and (with some exceptions) saved documents, and another for all my installed programs (read: games), and it drives me nuts to open My Documents (to find, you know, a document that I stored there) only to find a dozen game folders in there (usually filled with init/setting files, save games, etc.). Use the flipping folder I installed you in, dang it!

In other words, I like how DF does it now, none of this ~\Application Data\<App> or ~\My Documents\<App> crap. (I just looked again, several of them are also using ~\My Documents\My Games\<App>. Argh!)

Logged
000508 □ [dwarf mode][flows] flooding over a full pond will kill the fish inside

peterb

  • Bay Watcher
    • View Profile
Re: The standard Mac application structure
« Reply #8 on: March 03, 2008, 10:00:00 pm »

quote:
Originally posted by Nesoo:
<STRONG>
In other words, I like how DF does it now, none of this ~\Application Data\<App> or ~\My Documents\<App> crap. (I just looked again, several of them are also using ~\My Documents\My Games\<App>. Argh!)</STRONG>

The raison d'etre of "the mac way" is that for 99% of users it changes the application from "folder with an executable and a bunch of data files" to "a file"(*).  The practical consequence of that is that you reduce the chances of the user accidentally breaking their app install by partially overwriting files, moving things around, etc, and it means the user can put the application wherever they want and it should work just fine.

-peterb
(*) It's _not_ a file, of course, it's really a directory with files in it yadda yadda.  It's just hidden from the average user who doesn't know how to use the "Yes, I know what I'm doing" right-click menu option.

[ March 03, 2008: Message edited by: peterb ]

Logged

peterb

  • Bay Watcher
    • View Profile
Re: The standard Mac application structure
« Reply #9 on: March 03, 2008, 10:04:00 pm »

quote:
Originally posted by Toady One:
<STRONG>So how would something like the raw creatures be handled?  I suppose there'd have to be additional options to specify how it's done?  If a person supplies half of the creatures, the game wouldn't know if it should generate them itself (as I gather it would if nothing is supplied) or if the creatures were intentionally left out by the player.  </STRONG>

I don't know how the raw creatures stuff works currently -- is it some sort of plugin/user editable data?  Vigil's suggestion seems workable.  Alternatively you could imaging doing it a slightly different way:  "Use the raws in the app bundle if you don't find anything, but substitute the user's raws if they exist" (which is essentially what you ship with today, except if the user deletes the raw files you get nothing at all, right?)  That "should"(*) only be maybe 5 lines of code - your "give me the path to the raws" method checks for the existence of the user-specific raws directory, and returns it if it exists, or returns the bundle path if it doesn't.

-peterb
(*) Note use of FAMOUS LAST WORDS.

Logged

Vigil

  • Escaped Lunatic
    • View Profile
    • http://washboardabs.net
Re: The standard Mac application structure
« Reply #10 on: March 04, 2008, 09:47:00 am »

Regarding the whole where-files-go thing... while I understand the reasons behind wanting everything in one place (especially on Windows), there are good reasons behind these OS conventions, the most practical of which is multi-user support. I know this is irrelevant to most people who play games, since they usually don't share a computer (at least not with other game-players), but it's a vital component of modern operating systems and there's no really good reason why games should act differently from other applications in this regard. For what it's worth, I hate playing older (non-multiuser) games on my wife's PC and having to dodge her savegames and replace her keyboard binds with my own - this comes up quite often too.

(Drunken: if you want to keep your personal files and OS files *really* separate on MacOS, I believe you can change your home folder's location to another volume entirely. I haven't tried this myself though.)

Peterb, your suggestion about checking for a user-created raw folder (and falling back on the one in the app-bundle if one doesn't exist) sounders like a safer and more sensible solution to the problem.

[ March 04, 2008: Message edited by: Vigil ]

Logged