Affinity Photo — First Impressions

Affinity Photo in action

Note: if you’re interested in using Affinity Photo for processing RAW photos (i.e. its “non-destructive workflow”) you’re probably going to be horribly disappointed. See my followup article.

Affinity Photo has just come out of beta and is being sold for a discounted price of $40 (its regular price will be $50). As with Affinity Designer, it’s well-presented, with an attractive icon and a dark interface that is reminiscent of late model Adobe Creative Cloud and Apple Pro software. So, where does it fit in the pantheon of would-be Photoshop alternatives?

In terms of core functionality, it appears to fit in above Acorn and below Photoline. In particular, Photoline supports HDR as well as 16-bit and LAB color, while Affinity Photo lacks support for HDR editing. Unless you work with HDR (and clearly not many people do) then Affinity Designer is both less expensive than Photoline, and far more polished in terms of the features it does support.

Affinity Designer supports non-destructive import of RAW files. When you open a RAW file you enter “Develop” mode where you can perform adjustments to exposure, curves, noise, and so forth on the RAW data before it gets converted to 8- or 16-bit RGB. Once you leave Develop mode, you can return and second-guess your adjustments (on a layer-by-layer basis). This alone is worth the price of admission, and leaves Acorn, Pixelmator, and Photoline in the dust.

In essence you get the non-destructive workflow of Lightroom and the pixel-manipulation capabilities of Photoshop in a single package, with the ability to move from one to the other at any point in your workflow. Let me repeat that — you can “develop” your raw, go mess with pixels in the resulting image, then go back and second-guess your “develop” settings (while retaining your pixel-level manipulations) and so on.

This feature isn’t quite perfect. E.g. you can’t go back and second-guess a crop, and vector layer operations, such as text overlays, get reduced to a “pixel” layer if you go back to develop mode. But it’s a big step in the right direction and for a lot of purposes it’s just dandy.

This is just my first impressions, but there are some things that could be better.

Affinity Photo provides adjustment layers, live filter layers, filters, and layer effects — in many cases providing multiple versions of the same filter in different places. Aside from having functionality scattered and in arbitrary buckets, you get several different user interfaces. This is a mess, and it is a direct result of copying Photoshop’s crazy UI (accumulated over decades of accumulated functionality) rather than having a consolidated, unified approach the way Acorn does.

At first I thought Affinity Photo didn’t support layer styles, but it does. Unfortunately you can’t simply copy and paste layer styles (the way you can in Photoshop and Acorn), so the workflow is a bit more convoluted (you need to create a style from a selection and then apply it elsewhere — often you just want to copy a style from A to B without creating a reusable (or linked) style so this is a bit unfortunate).

I really like the fact that the RGB histogram gives a quick “approximate” view but shows a little warning symbol on it. When you click it, it does a per-pixel histogram (quite quickly, at least on my 24MP images).

I don’t see any support for stitching images, so if that’s important to you (and it’s certainly very important to landscape photographers) then you’ll need to stick with Adobe, or specialized plugins or software.

It also seems to lack smart resize and smart delete or Photoshop’s new motion blur removal functions. (Photoline also does smart delete and smart resize.)

Anyway, it’s a great first release, and definitely fulfills the promise of the public betas. It seems to me that it’s a more solid overall effort than Affinity Designer was when first released, and I’m probably a more demanding user of Photoshop-like programs than I am of Illustrator-like programs. I can understand the desire to provide a user interface familiar to Adobe products even at the cost of making them unnecessarily confusing and poorly organized, but I hope that sanity prevails in the long run.

Bottom line: a more complete and attractive package than either Photoline or Acorn (its most credible competitors) and better in some ways than Photoshop.

Email E. Neumann

Email E. NeumannHow stupid is email?

Actually, email is great. It’s robust, widely-supported, and highly accessible (in the 508 and economic senses of the word). The problem is email clients.

Security

A colleague of mine and I once considered starting up a business around a new email client. The problem though, is that it works best when someone send emails using your email client to someone else using your email client. E.g. you can easily implement PGP encryption:

  • if you’ve previously exchanged email, you both have each others’ keys — snap you’re done;
  • if you haven’t, your client asks whether you want it sent insecurely or asks you for authentication information (something you know about the person that a man-in-the-middle probably doesn’t, or an out-of-band mechanism for authentication such as calling you on the phone; and then sends an email initiating a secure authentication process OR allowing them to contact you and opt to receive insecure communication; all this can happen pretty seamlessly if the recipient is using your email client — they get asked the question and if they answer correctly keys get sent).

It’s relatively easy to create a secure encryption system if you (a) opt out of email, and (b) have a trusted middleman (e.g. if both parties trust a specific website and https then you’re done — even a simple forum will work). But then you lose the universality of email, which is kind of important.

The obvious goal was to create a transparently secure email client. The benefits are huge — e.g. spam can be dealt with more easily (even insecure email can be sent with authentication) and then you can add all the low-hanging fruit. But it’s the low-hanging fruit I really care about. After all, I figure if the NSA can hack my storage device’s firmware, my network card’s firmware, and subvert https, encryption standards, and TOR — and that’s just stuff we know about — the only paths to true security are anonymity (think of it as “personal steganography”) or extreme paranoia. When dealing with anyone other than the NSA, Google, China, Iran, etc. you can probably use ordinary caution.

Well, how come Windows Mail / Outlook and Apple Mail don’t do exactly what I’ve just said and automatically handshake, exchange keys and authentication questions, and make email between their own email clients secure? If it’s that easy (and really, it is that easy) why the hell? Oddly enough, Apple has done exactly this (using a semi-trusted middleman — itself) with Messages. Why not Mail?

OK, set all that aside.

Why?

  • Why can’t I conveniently send a new message the way I send a reply (i.e. “Reply with new subject and empty body” or “Reply all with new subject and empty body”)? When using an email client most people probably use Reply / Reply All most, then create new message and copy/paste email addresses from some other message second, and create a new message and type in the email address or use some kind of autocomplete last. Furthermore, many replies are actually intended to be new emails to the sender or sender and recipients. Yet no email client I know of supports the second — very frequent usage.
  • Why does my email client start me in the subject line? Here’s an idea: when you create a new email you start in the body. As you type the body the email client infers the subject from what you type (let’s say using the first sentence if it’s short, or the first clause with an ellipsis if that works, or a reasonable chunk of it with an ellipsis otherwise).
  • Why does my OS treat email, IMs, and SMSs as completely separate things? Studies show grown-ups use email and hardly SMS. Younger people use SMS and hardly use email. Both probably need to communicate with each other, and both are generally sending short messages to a person, not a phone number or an email address.
  • (While I’m at it, why does an iPhone treat email and IMs as different buckets? How come they had the nous to merge IMs and SMSs, and even allow semi-transparent switching between secure and free iMessages and less secure and not-necessarily-free SMSs based on whether the recipient was using an Apple device or not? I don’t ask why Android (or heaven forfend Windows) does this because (a) Android generally hasn’t even integrated mailboxes, and (b) don’t expect real UI innovation from Google; they can imitate, but when they originate it tends to be awful — aside from Google’s home page which remains one of the most brilliant UI decisions in history.
  • Oh yeah, and voicemail.

Nirvana

Now imagine a Contacts app that did all this stuff. I’d suggest it needs to be built into email because email is the richest of these things in terms of complexity and functionality, but let’s call it Contact. Consider the nirvana it would lead to:

  • Instantly, four icons on your iPhone merge into one (Mail, Phone, Messages, Contacts (the existence of the last has always bothered me, now it would make sense). Three of those are likely on your home screen; now you have more space.
  • You no longer have to check for messages in four different places (e.g. if you have a voicemail system that emails you transcripts of voicemails, you can mark them both as read in one place, or possibly even have them linked automatically.)
  • Similarly, when you reply to a given message, you can decide how to do so. (Is it urgent? Are they online? Is it the middle of the night? What is your preferred method of communicating with this person?) Maybe even multiple linked channels.
  • Message threads can cross message domains (imagine if you reply to an email with a phone call and Contacts knows this and attaches the record of the call to the thread containing the emails, SMSs, iMessages, voicemails, and so on). Some of this would require cleverness (e.g. Apple owns iMessages, so it could do things like add subject threads to messages on the side, but SMSs are severely constrained and would lose their thread context).
  • Oh, and you can use the same transparent encryption implementation across whichever bands make sense.
  • Obviously some of these things won’t work with some message channels e.g. you can’t do much with SMS because the messages aren’t big enough, but MMS, which is what most of us are using, works fine, similarly Visual Voicemail could support metadata but doing it with legacy voicemail systems isn’t going to happen.

Consider for a moment how much rocket science was involved in getting Continuity to work on iOS and OS X devices. To begin with it requires hardware that isn’t on older Macs and iOS devices. And what it does is pretty magical — I am working on a Keynote presentation, walk over to my Mac and automagically I am working on the same document in the same place. But really, how useful is this really and how often? Usually when I switch devices I am also switching tasks. Maybe that’s because I grew up in a world without Continuity.

Now consider how this stuff would require almost no rocket science and how often it would be useful.

 

 

Node-Webkit Development

I’m in the process of porting RiddleMeThis from Realbasic (er Xojo) to Node-Webkit (henceforth nw). The latest version of nw allows full menu customization, which means you can produce pretty decently behaved applications with it, and they have the advantage of launching almost instantly and being able to run the same codebase everywhere (including online and, using something like PhoneGap, on mobile). It has the potential to be cross-platform nirvana.

Now, there are IDEs for nw, but I’m not a big fan of IDEs in general, and I doubt that I’m going to be converted to them any time soon. In the meantime, I’ve been able to knock together applications using handwritten everything pretty damn fast (as fast as with Realbasic, for example, albeit with many of the usual UI issues of web applications).

Here’s my magic sauce — a single shell script that I simply put in a project directory and double-click to perform a build:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "$DIR"
cd "$DIR"
pwd
zip app.nw *.html package.json *.png *.js *.css *.map
mv app.nw ../node-webkit.app/Contents/Resources/
cp nw.icns ../node-webkit.app/Contents/Resources/
cp info.plist ../node-webkit.app/Contents/
open ../node-webkit.app

What this shell script does is set the working directory to the project directory, zip together the source files and name the archive app.nw, and then move that, the icon, and the (modified) info.plist into the right place (assuming the node-webkit app is in the parent directory), and launch it. This basically takes maybe 2s before my app is running in front of me.

info.plist is simply copied from the basic nw app, and modified so that the application name and version are what I want to appear in the about box and menubar.

This is how I make sure the standard menus are present (on Mac builds):

var gui = require('nw.gui'),
    menubar = new gui.Menu({ type: 'menubar' });
if(process.platform === 'darwin'){
    menubar.createMacBuiltin(appName);
}
gui.Window.get().menu = menubar;

And finally, to enable easy debugging:

if(dev){
    var debugItem = new gui.MenuItem({ label: 'Dev' }),
        debugMenu = new gui.Menu(),
        menuItem;
    debugItem.submenu = debugMenu;
    menubar.append(debugItem);
    menuItem = new gui.MenuItem({ label: "Open Debugger" });
    debugMenu.append(menuItem);
    menuItem.click = function(){
        gui.Window.get().showDevTools();
    }
}

So with a few code snippets you get a Mac menubar (where appropriate), a Dev menu (if dev is truthy) and a single double-click to package and build your application in the blink of an eye. You can build your application with whatever Javascript / HTML / CSS combination suits you best.

Obviously, you don’t get a real “native” UI (but the next best thing is a web UI, since people expect to deal with web applications on every platform), and this isn’t going to be a great way to deliver performant applications that do heavy lifting (e.g. image processing), but it’s very easy to orchestrate command-line tools, and of course the chrome engine offers a ridiculous amount of functionality out of the box.

I should mention that Xojo is actually quite capable of producing decent Cocoa applications these days. (It sure took a while.) But its performance is nowhere near nw in practical terms. For example, C3D Buddy is able to load thousands of PNGs in the blink of an eye; the equivalent Xojo application is torpid. Now if I were doing heavy lifting with Javascript, perhaps it would tilt Xojo’s way, but it’s hard to think of just how heavy the lifting would need to get.

The Race to Replace Illustrator: Affinity Designer

Just as Core Graphics created a race to replace Photoshop (at least for the great unwashed masses who don’t care about Color Spaces, CMYK, Lab Color, HDR, Stitching, Content-Aware Resizing and Deletion, seamless integration with other Adobe software, and so forth) there is now a race to replace Illustrator. Part of the problem is that the bewildering range of screen densities has made working primarily with bitmaps essentially a mug’s game (even Apple-targeted designers, used to supporting two resolutions, are suddenly faced with four (one of which is seriously weird).

You may recall some old stalwarts, such as Inkscape, Intaglio Designer, iDraw, Artboard, ZeusDraw, EasyDraw — of which I like iDraw — and Sketch; some of these are pretty credible Illustrator replacements (at least for casual users) but there are even more entrants in the field now, and they’re even more interesting:

Sketch 3 is the new version of Sketch — the vector-based, UI-focused drawing tool. It adds user interface refinements, symbols (“instances”), scripting via Javascript, automatic detection of colors used in a layout, and streamlined export functions. The fact that most of the new features are focused on workflow shows that BohemianCoding has been listening to professional users. I’ve not bought Sketch 3 yet because I’m a bit miffed that there’s no upgrade path for Sketch 2 owners (for which Apple is at least partially responsible) and — worse — that they pulled Sketch 2 from the App Store so I can’t conveniently reinstall the old version on my computers. Again, that might be Apple’s fault (i.e. perhaps they can’t set things up so that existing owners could continue to download and install it while taking it off the market).

Let me pause here to say this: I freaking love Sketch (2). I probably use it more than any other non-3d graphics program (I use it in preference to iDraw these days). I probably use it more than all other non-3d graphics software put together. Sketch is my go-to app for UI graphics and textures for (cartoony) 3d models.

Paintcode and Webcode are, like Sketch, focused on user interface design. The big difference between these tools and predecessors is that they’re focused on outputing your graphics as code that will recreate them at arbitrary resolutions (Paintcode will output Objective-C, Swift, or C# Xamarin, while Webcode will output SVG, Javascript (Canvas), and HTML+CSS. I’ve got a Paintcode 1.x license which seemed a bit limited (Paintcode 2 has beefed up its import and export functionality, as well as adding Swift support). Of the two, Webcode actually looks more compelling to me than Paintcode (and it doesn’t hurt that it’s much cheaper) — I’d probably pony up for Paintcode if it offered all of Webcode’s functionality, but it appears not to.

Finally, Affinity Designer comes from Serif, a company dedicated to competing with Adobe at the low-end in the Windows market, switching over to the Mac-only market with a bang. Their plan is to start with an Illustrator-killer, then proceed with Affinity Photo and Affinity Publisher. (Publisher? Really? Do they want to take on Pages and InDesign at once because that seems to me to be a losing proposition.) Of the three, Affinity Designer is clearly the most Illustrator-like, while Sketch 3 is kind of an Illustrator/Fireworks hybrid, and Paintcode/Webcode are simply unique.

iDraw is my current benchmark for wannabe Illustrator-replacements.
iDraw is my current benchmark for wannabe Illustrator-replacements.

Affinity Designer

I played with Affinity Designer briefly during the free beta, but it didn’t leave me with a strong impression. When they announced its release, I ponied up the (discounted) $40 (iDraw, my current favorite, is $25, but there’s been no significant improvements to it over the last year, and the things that annoy me about it still annoy me). The first thing I noticed when I launched Affinity Designer is that — like Illustrator — it defaults to print usage (CMYK, paper-oriented layout). It’s nice to discover that it also has web- and device-centric settings and defaults, and @2x retina support out of the box (but unlike Paintcode it hasn’t figured out what to do about the iPhone 6/Plus).

Screen Shot 2014-10-06 at 11.26.51 AM
I imported the SVG from iDraw into Affinity Designer. Everything looks great (and it even preserved layers) except for the fonts (which unfortunately are not easily fixed).

The first thing I did was take a pretty damn complicated SVG file (with layers and typography) and export it from iDraw and import it into Affinity Designer. Every font failed to import correctly (Helvetica Bold and DIN Condensed), but otherwise it seemed to do a pretty good job — overall, it did a better job than Sketch (2) at importing the same file. I think the problem lies with how SVG stores font information (Sketch had the same issue when importing the file; note that iDraw can import its own SVGs flawlessly.)

But here’s where things get ugly — when I tried to fix the font issues, I discovered that I can’t change the character style settings for more than one object at a time. (And this is not a problem in Sketch or iDraw.) As a workaround, I tried to create a style from one object and apply it to others but that didn’t work at all — styles seem to be limited to fill color and the like (and fill color doesn’t seem to be the same thing as text color). Bad start.

Time to look at the program in its own terms. One of the best things about Sketch relative to iDraw is its support for gaussian blur as a style. Affinity Designer has this and more (e.g. emboss, and a weird “3D” effect that I’m not sure what it’s supported to do). What it doesn’t do (and what Sketch and iDraw both do) is allow you to apply the same filters multiple times (e.g. much the same way you can stack box-shadow effects in CSS). Another annoyance with Affinity Designer’s effects is that important settings are buried in a modal dialog box (iDraw is annoying in a different way in that you need to disclose the settings with an extra double-click, but that’s a pretty minor annoyance). So far, I’d call this a mixed result.

Here’s an example of Affinity Designer at its worst. I draw a test bezier curve and then try to apply a stroke to it. So far so good. But it’s stroked in the center of the curve.

  • I almost always want to stroke inside the curve, and sometimes outside, but almost never centered on the curve. So I look at the stroke settings, and all that is exposed is color, opacity, and radius.
  • To access the extra properties I need to click on the little “gear” icon that lets you configure the other settings of a given filter.
  • As I’ve mentioned before, this dialog is modal; it also defaults to showing some random filter setting, not the one you were working on (which confused me a minute, since it was showing bevel/emboss options and not line options).
When I clicked the stroke "gear" I get deposited in a modal dialog with Bevel selected. WTF?
When I clicked the stroke “gear” I get deposited in a modal dialog with Bevel selected. WTF?

 

  • OK, so having switched over to the line settings, I discover that the options (inside, outside, centered) which — for some reason — is not the top setting (compositing mode is at the top).
To add injury to insult, the stroke settings don't actually work — note that I've chosen outside and it's displaying a centered stroke.
To add injury to insult, the stroke settings don’t actually work — note that I’ve chosen outside and it’s displaying a centered stroke.
  • Here’s the rub — the different options (a) don’t work and (b) appear to override and block the modeless setting (i.e. when I change radius in the modeless view, the setting no longer works. WTF?).
The basic selection / transformation affordances are nice.
The basic selection / transformation affordances are nice.

This is a freaking disaster. First of all, how can an Illustrator clone go out the door with broken strokes?

I do like the basic selection affordances. In particular rotation gets its own affordance (the little dot out on its own) rather than requiring mouse/keyboard chording. The basic Bezier drawing tools seem to be solid.

But there’s one more global observation I need to make before I move on: the tools all feel wrong. There’s a nuance to the rules that govern how 2d graphics tools, in drawing programs especially, behave. When they should be sticky vs. revert to a selection tool, and so forth. This stuff is so basic that it happens below the level of conscious decision-making. For better or (mostly) worse, a lot of us have Illustrator’s behavior in our muscle memory (where it displayed MacDraw, which was generally more intuitive).

In any event, just as iDraw and Sketch and many other Mac graphics programs get this somehow right, Affinity Designer gets this somehow wrong, and it bugs the hell out of me. If the program were in a more functional state, I might even spend the time to go figure out exactly what’s wrong and write some kind of detailed bug report for the development team, but I find the program, as a whole, to be so fractally unusable that I just can’t be bothered.

At this point, it’s not worth continuing the review. Affinity Designer is a promising and polished looking piece of software, but basic functionality is completely broken, and it has horrific workflow problems (styles don’t work with text formatting, you can’t edit multiple selections in a useful way, the wrong properties are disclosed in the modeless floater, and the modal dialog is both weird and buggy). So, in summary:

  • Some features that are lacking in iDraw (Gaussian Blur effect)
  • Single window UI (unlike iDraw which suffers from palette-itis)
  • Better SVG import than most rivals
  • Limited effects options (can’t apply multiple instances of a given effect to a single element)
  • Editing effects is clumsy (useful stuff is buried in modal dialog, which does not open on the right effect) and buggy (the settings don’t work properly).
  • Affinity Designer’s tools just feel wrong; they stick in modes when they shouldn’t (or I don’t expect them to) and it’s just infuriating.

Affinity Designer manages to be promising, attractive, and completely useless in its current form.

Note: I purchased Affinity Designer from the App Store after using the public beta a few times. I was so frustrated with the release version that I have requested a refund from Apple, and have deleted the app. (I think this is maybe the second time I have ever asked for an App purchase to be refunded.)

C# Part II

Galaxy Generated and Rendered in Unity 3D
Galaxy Generated and Rendered in Unity 3D

In the end, it took me four evenings to replicate the functionality in my Javascript prototype. I’d have to point out that I was able to do some really nice UI stuff (e.g. drag to rotate, mousewheel to zoom) in Unity that I hesitated to mess with in Javascript (the galaxy was rendered to a canvas in Javascript).

On the whole, I have some impressions.

First, C# is very strict about types, and while I can see some benefits, I think a lot of it is utterly wasted. E.g. having to constantly cast from one numeric type to another is simply a pain in the butt (I routinely expect to have to tease apart a bunch of cryptic type-related errors every time I compile a few lines of new code).

// given an array of weights, pick an index with corresponding weighted probability,
// e.g. [1,2,3] -> 1/6 chance of 0, 2/6 chance of 2, 3/6 chance of 3
public uint Pick( uint[] weights ){
    int s = 0;
    uint idx;
    foreach( uint w in weights ){
        s += (int)w;
    }
    s = Range (1, s); // returns a random int from 1 to s, inclusive
    for( idx = 0; idx < weights.Length; idx++ ){
        s -= (int)weights[idx];
        if(s <= 0){
            break;
        }
    }
    return idx;
}

And all of this rigor didn’t actually prevent or even help debug an error I ran into with overflowing a uint (I have a utility that picks weighted random numbers, but I overflowed the weights leading to an out-of-bounds error. (A simple fix is to change idx < weights.Length to idx < weights.Length – 1.) On the whole it would be nice if you could simply live in a world of “numbers” (as in Javascript) and only convert explicitly to a specific representation when doing something low level.

Second, there’s this weird restriction on naming classes within a namespace such that the namespace and class sometimes may not match and the class you want is often not in the namespace you expect. (E.g. I wanted to create the namespace LNM.PRNG and define the class PRNG in it, but this confuses the compiler, so I ended up calling the namespace LNM.Random — so code referring to this is “using LNM.Random” which mysteriously causes a class called PRNG to become available.) I don’t see why namespaces and class names can’t be the same.

Oddly enough in some cases I am allowed to name the class the same as the namespace, and I don’t know why. So LNM.Astrophysics implements the Astrophysics class, but I had to rename Badwords to BadwordFilter at some point because the compiler started complaining.

I’ve been using Monodevelop, which is an editor produced by the Mono folk and lightly customized to work with Unity. It’s a bit of a slug (if it’s developed using Mono, then it’s not a terrific advertisement for Mono). In particular, its autocomplete is great when it works, but utterly frustrating far more often. It fails to match obvious words (e.g. local variable names) and often makes it impossible to type something short (which matches something longer) on the first attempt. The autocomplete is darn useful, or I’d simply switch back to Sublime.

Flying my untextured spaceship around an undecorated, partially implemented solar system
Flying my untextured spaceship around an undecorated, partially implemented solar system

So the current reckoning is that I ended up producing the following:

  • Astrophysics.cs — defines the LNM.Astrophysics namespace and implements the Astrophysics utility class, some useful enumerations, and the Galaxy, Star, and Planet classes.
  • PRNG.cs — defines the LNM.Random namespace and implements the PRNG class which provides convenience functions for the Meisui.Random Mersenne Twister implementation I’m using.
  • Badwords.cs — defines the LNM.Badwords namespace and implements the BadwordFilter class which checks to see if any of a pretty comprehensive list of nasty words is present in a given string. (Used to prevent obscene star names from being generated.)
  • Billboard.cs — a Monobehavior that keeps a sprite facing the camera. It’s a little cute in that it tries to save CPU time by only updating a given star every 10 physics updates. There’s probably a better way.
  • FixedCamera.cs — a Monobehavior that implements a mouse/touch controlled camera that keeps a fixed view of a specified target unless explicitly moved. I’m planning on using this as my main view control throughout the game.
  • NewtonianScoutship.cs — a Monobehavior implementing an Asteroids-style player ship. I’ve also experimented with a “Delta Vee” style abstracted Newtonian ship controller but good old rotate and accelerate just feels better, and makes movement a pleasant challenge in and of itself. (It also makes becoming “stationary” in space almost impossible, which I think is a Good Thing.)
  • GalaxyGenerator.cs — a Monobehavior that instantiates a galaxy and renders it with sprites. (Right now every single star is a Draw Call, so I’m going to need to do some optimization at some point.)
  • Starsystem.cs — a Monobehavior that instantiates a Star (and its planets) and renders them, a navigation grid (to provide a sense of movement when passing through empty space) and orbits using a bunch of Prefabs.

So, while I continue to find C# quite tedious to develop with, I am making significant progress for the first time in over a year, and while C# feels much less productive than real Javascript, I do think it’s very competitive with Unityscript, and it’s been quite easy to get over the hump.