Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

November 21, 2019
Press Releases
November 21, 2019
Games Press

If you enjoy reading this site, you might also want to check out these UBM Tech sites:

# Product Review: Metrowerks’ CodeWarrior 9 for Palm OS

March 15, 2003

Non-native platform or embedded systems development is never a pleasant task. It is often fraught with coercing primitive tools to do your bidding and constant frustration at the pressures of non-programmers observing the target platform as a "simple system" not as complex as Microsoft Windows or UNIX. Palm Pilot, no different to any other non-host development platform, has until the very recent past been poorly catered when it comes to development tools. Many developers are still forced to use primitive tools that have not really evolved in 25 years. I've been struggling with Palm Pilot development the same way I was struggling with the Acorn Atom in 1981, how to be an effective and empowered developer without writing all my own support tools. All the commercial solutions I am working with leave so much to be desired and I finally cobbled together a workable environment, piecemeal, using OSS tools and two commercial integrated development environments (IDE), task switching back and forth between them.

In the Autumn of 2002 Metrowerks, makers of the CodeWarrior series of development tools, announced version 9.0, capable of supporting the new ARM hosted Palm OS 5 and still retaining backwards compatibility with previous Palm OS versions. Their all new, all singing, all dancing IDE was the awaited update to their current product line. Reviewing a product that covers the scope of an IDE, compiler, debugger, emulator, resource tools and accompanying manuals is an interesting challenge. Unless you're familiar with the legacy of a product of this size you can't really appreciate the effort that goes in to upgrading it and bringing something fresh to the end user.

When I'm looking for a compiler, I'm looking for the "best" compiler. But when I'm considering an IDE, e.g. Metrowerks CodeWarrior, I'm looking at every feature and every nuance. Tools are a very personal agenda. They must work in the same way that I as a developer work, so that I never feel restricted by them. I should never have to work around them. To paraphrase a cliché, tool providers have to realize that using a screwdriver to hammer in a nail is inappropriate. Being a hardcore command line user who enjoys a properly configured makefile and build script, what I want from an IDE is being able to do everything from the keyboard, and possess the capability to script and customize every action. Microsoft Developer Studio is the only IDE to date that came close to those desirable qualities. As a complete gear head geek I'm always interested in "cool new development tools", but also being a seasoned pragmatist I'm wary of any "silver bullets", especially from any company that I consider to have put out substandard software, doing themselves and the development community a severe disservice.

 CodeWarrior 9 for Palm OS is designed around a flexible plug-in architecture.

Metrowerks' CodeWarrior (CW), which I've used on-and-off since the earliest Apple Mac days, was an also-ran for the longest time, the choice of last resort and I had very few good words to say about it. I've suffered through numerous projects on Gameboy Advance, Gamecube, PSX and PlayStation 2 and always floundered about the CW environment. For PlayStation development it was always the tool of last resort for when the DOS-based SNSys debugger was crashing constantly, refusing to talk with the DTL-2000, or GCC was having linker palpitations. The same held true for Palm Pilot. I had CodeWarrior 8 for Palm Pilot installed for months and I would open it about once every two months for an hour or so to figure out why some piece of code was failing. My development setup was less than ideal. From the earliest days, each revision of CW I would dutifully download, look at the feature list, install the demo, and come away from the whole experience disillusioned and disappointed. "Must try harder" would be my quip when asked for a summation.

CW9 has addressed a lot of the concerns and problems I had, but there are still niggling issues with it. Development tools always come down to personal preferences, and my biggest issue is "It's not DevStudio 6" which really Metrowerks can do nothing about. Realizing this, I can appreciate the effort that has gone into CW9 to try and make it a tool that users will want rather than lament. Version 9 changes a lot of the underlying architecture, but leaves in place everything that is familiar to people who use it frequently on a day to day basis.

CW9 is still showing its Mac roots but slowly they are being engulfed by the real aims of Metrowerks, to fulfil the not insignificant task of creating a cross-platform host development environment (currently Apple Mac and Microsoft Windows) for an undefined number of target platforms, the list of which, when reading, feels like it would consume an entire magazine page just to iterate.

To achieve their goal with any consistent chance Metrowerks has adopted a completely flexible, and most importantly, copiously documented, plug-in architecture. Their philosophy began appearing in earlier versions and 9.0 completes the transition. Now, almost everything in the IDE, including the compiler is a replaceable plug-in, which is how it should be. The integrated editor can also be replaced but only on the Mac version. Replacing the editor on the Windows version just calls an external editor, e.g. UltraEdit, which would appear with normal use.

Your first impression is the installer, snazzy in some respects, e.g. it understands multiple sub-folders when creating the Start Menu icons; and showing its age in other small ways, some of which I will cover. The installer may not seem to be that big a deal to most people but it's where you begin. An audio clip plays when you insert the CD.

Be sure to select "Custom Install" if you want C and C++ files to still open in another package, e.g. Microsoft Developer Studio, otherwise your default file mappings will be usurped, and whilst CodeWarrior allows you to change the mappings after installation to either CW, or default, there is no way to remap the source file handling back to how you had it without the tedious use of Windows Explorer. During installation there are no less than six separate "click-wrap" license agreements you have to wade through, quite literally tens of thousands of words of legalese and sub-sub-clauses of the third party agreeing to the first party; who has time for this? I understand that Metrowerks needs to include these for all of the SDKs that ship with their product but I no longer felt like I was only agreeing to give up my first born, now I was giving up my whole family. You may want to have your company lawyer look over the agreements beforehand to ensure one of your developers didn't just agree to a big corporate no-no.

The installer is gracious enough to warn you if you attempt to install CW9 over an older install and that incompatibilities may arise. At the end of installation an "automatic" updater executes, also usable at any time after installation, which actually only checks for an update, requiring you to visit the Metrowerks web site to actually download, and separately install the new update.

Installed and running, you are presented with what should seem familiar to most developers, a project window on the left, a blank area for your code window, and a comprehensive array of menus, sub-menus and option dialogues. The menu bar layout can be toggled between "Macintosh mode", which should be familiar to users of previous versions, and "Windows mode", making the application feel more like a host platform native.

I have several sizable Palm Pilot projects so the first thing to do was exercise the IDE and get something compiled. Developers are too proud to care about the shipped examples except to rummage for re-usable source code, seasoned developers also realize that Mickey Mouse publisher samples don't really exercise the toolset. What's it doing? How is it doing it? What are these options for? You want to see the compiler perform on a familiar code base and how it handles your project's unique problems.

I'm probably Metrowerks worst nightmare when it comes to end users. I'm also their target audience. I want to reconfigure the IDE. I want to change the code editor fonts to use some miniscule 6 point custom bitmap font I've created. I want custom colors for all of the text. I want fast code generation. I need four targets, "Debug", "Optimised Debug", "Final" and "Release". I want all compiler warnings on. I want ANSI C++ compliance off. I want my tweaked version of the Palm Pilot emulator. I don't want to read the manual. I want… I want… I want…

Twenty minutes later I'm kind of happy and kind of disappointed. No, I haven't read the manual, not yet, manual reading comes later. I haven't floundered yet either. I have a familiar project, my project, 300,000+ lines of code, 160 C++ source files (not including headers); compiling, linking, and executing under the emulator. The environment can occasionally feel a little non-standard and non-Windows. Some of the dialogue boxes make me stop and do a double take due to the inverse meaning of the wording, or the fact that the button layout or captions are not what I was expecting.

After playing around now it's time to start tweaking options. There are a lot of Motorola 68K options, and very few for the new ARM. Also, the compiler only accepts inline 68K, even though it is possible to generate ARMlets, Palm Pilot's half-hearted and crippling attempt at exploiting the power of the ARM processor, but this can only be done at the module level, not the function level in CodeWarrior. Also, whilst being a game developer and desiring to screw every little bit of speed out of the target platform that I can is considered a "good thing", the Palm Pilot adopts the exact opposite philosophy, optimize for size first and speed last. The CW9 compiler defaults to optimize for speed for all source modules in the project. It can be changed on a module by module basis, but you need to be aware that you're compiler is generating large, fast chunks of code as default behavior. The compiler supports a lot of pragmas, many compatible with Microsoft's VC++, and all pragmas are well documented so now I can turn off that annoying "performance warning" when converting a float to a Boolean in a one off initialization function that I'm unable to in GCC.

Metrowerks has finally seen fit to move away from the God-awful Constructor by shipping the eminently usable PilRC resource editor. Just as well, all of my resources were in PilRC format. Still, realizing that some developers are still using Constructor for projects currently under development, it is installed and available from the Windows Start Menu but the focus is now on PilRC. Constructor, for those that aren't familiar with it, is a legacy application that has shipped with CW almost from the beginning and I cannot imagine using it in a production environment involving any reasonable amount of graphics or text, i.e. games development. It's incapable of importing bitmap files directly so you have the tedious, time consuming and error-prone process of cutting and pasting from your art package in to Constructor. Imagine copying and pasting several hundred bitmaps by hand. Then doing it all over again when the artists have updated the art. Constructor also stores data in a binary format so that version control systems loathe it and you cannot have multiple artists/creative types working on the same resource file simultaneously. So out it goes! Add one to the score for the Metrowerks team for their adoption of a "Palm Pilot industry standard" tool. PilRC does everything you would expect an application resource editor to do.

The CW9 IDE allows the developer to import and export IDE configuration data, and has done so for several versions, in a well-documented manner. Are you listening Microsoft? Manipulating IDE configurations via a script for a project is a feature of which I've made extensive use. CW9 also stores the configuration data in easily parsed XML rather than an obscure, un-documented, ever changing binary format.

The CW9 IDE offers the usual complement of workspace features that you would expect; multiple edit windows, multiple simultaneous workspaces - useful for co-dependent projects such as a library and an application - and multiple build targets with the attendant source, library & asset/resource files for generating dependencies and the final executable. The workspace can be toggled between SDI and MDI mode ala Microsoft Visual BASIC with dock-able windows. The workspace window allows you to sort your files in the order they were added, alphabetically, by the amount of code each file generates, the amount of data it generates, whether it needs re-compiling, and lots of other sorting criteria by clicking on the header columns. A feature that is sorely lacking in a certain other IDE I use on a daily basis.

A newly created workspace has difficulty recognizing some of the de facto standard C/C++ file types such as .INL to denote an inline source file that is to be included and the IDE explicitly excludes you from adding these files with an obscure "at least one file could not be added to the selected target(s)" which is also the same error given if the file already exists in a workspace. This could cause some frustration and head scratching on very large development projects. You can fix the problem by manually adding the specific file types to the workspace options but you have to add the file type for each build target, and the custom file types are specific to each workspace. Create a new workspace for another project and you have to add those custom file types all over again. Create a new build target within that workspace -- and on commercial projects there are often at least four build targets and often many more - and… Yes, you guessed it.

The compiler does seem to generate code a little slowly. And that is a double entendre. I've only had a week too really get into the new version and I was determined to spend the entire week immersed in it, effectively abandoning my familiar tools and environment, where possible, for CodeWarrior. Due to time and scheduling constraints I haven't had opportunity to perform proper compiler timings other than cursory stopwatch experimentation and the results are that CodeWarrior takes longer to output the same amount of code than GCC would for the same target CPU. I have GCC configured to generate dependencies, including those for art resources, process several large makefile includes, and output detailed information from the map file, essentially doing a lot more work than what I'm demanding of CW9, and GCC is still several tens of seconds faster. My current project isn't yet at the point where I would notice frame slow-down on an ARM CPU, and uncapping the frame sync didn't prove anything conclusive to my satisfaction so until I have more time to actually perform proper code generation comparisons I'm keeping quiet on any hard data but from my observations the code that CW9 generates is marginally slower, and I really must emphasise "marginal" until I've done proper timings. Previous versions of CodeWarrior have generated outstandingly slower code than GCC.

Until CW9 it was difficult to perform many tasks via the keyboard. Every time I have to lift my hand from the keyboard to reach for the mouse and select some obscure submenu option is valuable seconds taken away from productivity, it can also ruin a train of thought. Every action I can perform with the mouse I should be able to perform with the keyboard. In the latest version almost but not quite everything can now be mapped to a key, and just as importantly, all key bindings are user-definable so it's possible to have Microsoft Developer studio keys, BRIEF emulation, or even Atari ST C-Breeze if you're inclined.

CW9 supports two flavors of version control, extensible through the plug-in architecture, Microsoft's Visual SourceSafe (VSS), and Concurrent Versions System (CVS). At home I stick with the simple VSS, at work I'm usually using CVS, whichever solution you require you still don't move completely away from the native toolset, the CW plug-in merely allows the IDE to talk to the back-end versioning system.

Palm Pilots arrive in a variety of hardware and OS configurations, and not all target platforms support all features. The usual way of developing Palm OS applications is to run your code inside of an emulator or for OS 5 in the simulator, with the appropriate ROM files for the particular machine, satisfactory for Dinky applications but the real world requires you to download to hardware regularly to track down some obscure error. Metrowerks has done its best by providing several ways to connect CW9 to the target. This is where CodeWarrior usually shows strength, the integrated source level debugger, and when I say source level that means C or C++, with native support for Dragonball xZ 68K CPU line. Metrowerks touts how strongly this new release supports Palm OS 5 and the new ARM CPUs so I was expecting to be able to debug my ARM code and ARMlets -- reading the datasheets you certainly receive this impression -- but I spent fruitless hours attempting to step in to an ARM assembly module without much success. On feedback from Metrowerks they state that CW9 is incapable of debugging anything ARM related which puts me back to old tried and true methods and left me with the feeling that CW9 was a half-hearted effort at a Palm Pilot development tool.

Connection can be made to a hardware device via the docking cradle utilizing RS232 serial or USB. Unfortunately it's not possible to debug all hardware configurations, some USB Palm Pilot devices do not allow remote debugging, the list of which can be found in the CW9 documentation and on their website. This incomplete coverage posed a particular problem for me as I'm currently developing an application for the Sony NX70V and am unable to debug either my GameCon peripheral or the camera code. The only way to debug is directly on the device itself using good old-fashioned techniques of printing out relevant variable values to the screen where possible. It would be nice if Metrowerks could ship a target platform debugger too. CW9 now supports an external debugger, so if you have a familiar debugger, e.g. Insight running on top of GNU GDB, you are able to use that as an integrated part of the environment rather than having to task switch out. The CW9 native debugger supports multi-session debugging, allowing you to debug a piece of software running on two separate instances of the emulator, or the emulator and a hardware device but I didn't avail myself of the opportunity to investigate this feature as none of my projects make use of multi-machine communications yet.

The older versions of the CodeWarrior editor have always been the product's biggest weakness, and I would say the most used feature for all users. And unfortunately, Metrowerks disappoints once again. The code editor kind of provides most of the features I expect in a modern IDE, but in a half-hearted way. Editing functionality is so-so. Code completion - had to change the default key to something more "DevStudio friendly" that actually worked on my laptop keyboard, who has hands big enough to stretch from the Alt key to the full stop on the numeric pad? Code completion usage was clunky at best and it's unable to tell you neither the parameters a function expects nor the members a class or structure has defined. Auto-indenting - the most basic of what you would consider auto-indenting to be in the twentieth century, and that's the last century for people not keeping up. Syntax highlighting - not enough options for highlighting different pieces of text, it's about twenty options short by my estimate. Brace/bracket balancing -- very annoying typing delay in the default configuration and woefully inept in use and fond of losing typed text, the greatest sin of all. Open #include - this is a niggle, one of those "features" that makes you take one extra small step before completing a task, instead of placing the insertion point inside of a string enclosed in quotes or angle brackets and right click and selecting "Open file" like in every sane editor that is smart enough to figure out that it's a #include filename, you have to actually highlight the entire filename and then right click to open, it works only if you highlight the base name file, sans extension, as long as you don't have a file with "multiple extensions", e.g. "foo.bar.h" Can you believe there's no "Delete Line" capability in the text editor? It also lacks a basic one-key reformatting feature. I'll stop now before I run out of space. Hopefully Whole Tomato, makers of VisualAssist will consider porting their plug-in to the CodeWarrior environment to round out the code editor feature set and bring it up to the classification of "usable".

The comprehensive Palm documentation has been integrated in to the IDE, which is how online help in an IDE should work. The documentation is accessible from the code editor, highlighting an API call or structure name and pressing F1 brings up the appropriate help page. Unfortunately you actually have to highlight the word, not just merely have the insertion point somewhere within the word, and part word searches don't work, for that you have to open the appropriate help file and search. There doesn't appear any way to add your own documentation to the list of searchable help files either.

The Metrowerks supplied documentation covers a lot of ground, CW9 ships with several help files that are worth reading through, including the use of C & C++ compilers on embedded systems, covering the specific differences in the Metrowerks CodeWarrior compiler with pointers on optimising for size and improving compiler performance.

CW9 includes the usual wizards for generating new projects, useful for first time users to get the compiler's default options for a shared library or basic application with simple code for processing messages, displaying a form, a menu and an about dialogue. The documentation also includes comprehensive tutorials on using the wizards and setting up projects.

The IDE contains an integrated "graphical" file diff/compare utility. It's very nice, it also generates a text list of all the differences too, unfortunately there is no actual way to export this text and the way it works is a little unfamiliar in how it applies the differences so for file compares and diffs I'll be sticking with WinMerge and HexEdit.

A powerful feature of CW9 is its support for Windows Scripting Host (WSH), available only on the Windows version. Using any WSH 2.0 compatible scripting language, e.g. VBScript, Perl or JavaScript, you can exert automated control over your project, the IDE, and the compiler; especially useful if you have a singular machine designated as the build monkey to generate all the various target configurations or require pre-build or post-build steps. I only exercised this feature a small amount, putting together some simple scripts to iterate over the project files and ensure the latest versions had been retrieved from VSS. Coupled with the new command line features this helps CW9 to integrate in to a professional development environment where someone is not always around to click on the mouse.

Along with the standard Palm SDKs Metrowerks ships almost all of the available Palm Pilot APIs, including Sony's; featuring their HighRes & GameCon API, along with a trial version of Bachmann's Print Boy shared printing library, a public version of the Palm Pilot installation package, Catapult from Beiks Software, the full version of Hands High Font Bucket and of course the obligatory Huebner's MathLib.

With version 9 Metrowerks is attempting something different by shipping the Palm Object Library (POL), a kind of MFC for Palm Pilot without all the Microsoft messiness. POL wraps many of the Palm API calls and structures in logical C++ classes. How wise this is I cannot say, I used it a little bit but I wasn't going to refactor my project to test out an untried API. I think the library needs more maturity and real-world usage before I would consider using it in a commercial project.

Metrowerks CodeWarrior retails for an MSRP of $399 per seat for new purchases, and$199 for people upgrading from a previous version.

After a week of using CodeWarrior I'm still not changing my one-liner. I've returned to using my old development environment, not because of lack of familiarity with CW but because they still have a long way to go before they come close to something I would willingly use on a day-to-day basis and most of my resistance stems from the incapable code editor.

Palm Pilot Development Kits & ROMs http://www.palm.com/
Metrowerks CodeWarrior http://www.metrowerks.com/
Bachmann PrintBoy http://www.bachmannsoftware.com/
Beiks Catapult http://www.beiks.com/
Hands High Font Bucket http://www.handshigh.com/
Ben Combee's Palm OS Development Site: http://www.palmoswerks.com/

After this review went to press, Ben Combee, CodeWarrior for Palm OS technical lead responded. Ben works mainly on the compilers, linker, debugger and resource tools with brief excursions in to the CW IDE code base. Ben feels that some of my criticisms were premature and I'd like to take this opportunity to let him respond.

Ben Combee: "With regards to compile speeds, I don't think you made effective use of the precompiled header capabilities of CodeWarrior. While straight code compilation may be slower than GCC, using a precompiled header to cache symbol definitions from the Palm OS headers or even local headers can dramatically speed up build times."

Justin: "That is a valid point, and it's one of the first things I checked. Even with pre-compiled headers GCC was still managing to out perform the CodeWarrior 9.0 compiler. I think this has a lot to do with the way I construct my projects and makefiles though and when it comes down to it, twenty seconds on a five minute build is neither here nor there."

Ben Combee: "I think your criticisms of the 68K/ARM aspects of the tool didn't accurately reflect where the Palm OS market is today. Most applications are 68K, and 68K code works very well for everything but speed-critical apps. The current API for Palm OS is 68K-based, and ARMlets only barely made it into Palm OS 5 -- PalmSource originally had no plans to allow user-level ARM code to execute in that OS version. We focused on 68K development with this release both because traditionally the Palm OS tools were 68K only, and for Palm OS 5, the majority of code will still be 68K-based. There are only a limited number of ARM-based devices out there right now; any game developer wanting to target the Palm OS market really needs to do 68K first, since that's where the majority of users are."

Justin: "I agree. I didn't mean to mislead the reader in saying that CodeWarrior was deficient in that area. Reflecting on it I'm positive I was venting my own frustrations at PalmSource's technical solution and perhaps using CodeWarrior as the platform. I retract my earlier point."

Ben Combee: "The external debugger comment seemed odd. While the IDE supports that, there are no external debuggers that support Palm OS with CW-generated programs. As for remote debugging, the lack of support is generally the fault of the device manufacturers -- we have tried to get Palm, Handspring, Sony, and other companies to support USB debugging, but it's never been a high priority. For the record, the NX70V does support remote debugging with a serial cable, but you need to get that from a third-party, such as http://shop.brando.com.hk/."

Justin: "I never had the chance to investigate the external debugger IDE. Specifically that was a feature bullet on the advertising literature I was sent. Also, when the review was submitted to Metrowerks for fact checking it came back that I had forgotten to mention the external debugger feature so it was added at the last moment. Which is why it seems "tacked on" to the review. So point noted, CodeWarrior 9.0 supports an external debugger but there are no 3rd party debuggers that handle Palm OS programs generated by CodeWarrior 9.0.

With regard to the remote debugging issue I did speak with Metrowerks tech support concerning this and they offered no solution, and yes, you are right to point out that it is mainly the fault of the manufacturers not providing proper support. Within a day of Game Developer publishing the review a Metrowerks representative accosted me while I was attending Game Developer Conference and informed me I could debug on the NX70V with the use of the cable you mention."

Ben Combee: "Did you try the product in the MDI configuration of the IDE? There were no comments on docking windows support, which I think is a pretty major IDE feature added in this release. There was also no mention of workspace support in the IDE."

Justin Lloyd: "I think a lot of what was covered got cut in the magazine version due to space restrictions. Check through the full-length review and you'll see I do mention the workspace."

Ben Combee: "On the topic of POL -- while this is the second release of CW with this library (POL 3.x was part of the CW for Palm OS 8 Enterprise Edition release), the library has been used by developers since early 2001 and is quite mature. I've personally used it for several side projects, and it has worked very well."

Justin Lloyd: "Ironically, an announcement concerning the future of POL was released in the past few weeks that it is to be discontinued. I'm sure that any OS 5 apps will have to be updated to work on OS 6 but the burden would surely be heavier if the developer also had to migrate away from POL."

Ben Combee: "Finally, I also wish you had looked at the online support reputation of Metrowerks with regards to this toolset. I've personally setup a comprehensive web resource at www.palmoswerks.com to provide communications from the dev team here at Metrowerks to developers, and some of your objections could have been addressed via articles at this site. Our team is also very active in the Palm OS developer support forums, including the newsgroups from www.falch.net and the mailing lists hosted by palmos.com

Thanks for your time, and I do appreciate the review, even with my criticisms of it. If you still have the product, be sure to look in the Extras folder of the CD for some videos that were shot here at MW using the NX70V's camera."

Justin Lloyd: "Thank you very much for the feedback Ben, the criticisms are welcomed. I think that when Metrowerks brings its editor up to date that the CodeWarrior IDE will offer the best all round solution for cross-platform and embedded platform development."

 CodeWarrior 9 for Palm OS Metrowerks Price: $399 for new users,$199 for upgrades System Requirements : Intel Pentium or AMD K6 equivalent and 64MB of main memory. Windows 98/Me/2000/XP or NT 4.0 with SP6, CD-ROM drive for installation, and 380MB of free hard drive space. Pros: 1. Familiar environment when you move to other target platforms. 2. Large amounts of documentation including a well-documented plug-in architecture. 3. Source leve debugger supporting C, C++, 68K, and ARM. Cons: 1. Incredibly primitive code editor. 2. More support for 68K than ARM. 3. Did I mention the incredibly primitive code editor?

______________________________________________________

### Related Jobs

LOKO AI — Los Angeles, California, United States
[11.20.19]

Senior Unreal Engine Developer
Free Range Games — Sausalito, California, United States
[11.20.19]

Senior Engineer (Unreal)
Disbelief — Cambridge, Massachusetts, United States
[11.20.19]

Senior Programmer, Cambridge, MA
Supergiant Games — San Francisco, California, United States
[11.19.19]

Engine Programmer at Supergiant Games