High Resolution CC-0 Licensed Galaxy Brain Images

Here’s the short version: I’ve made a Creative Commons licensed version of the Galaxy Brain meme images. I’m releasing these images under the CC-0 license, which means you can use them in just about anything, including commercial works. I’ve made versions with both a masculine and feminine figure. More notes below!

If you like these, please consider supporting the work we do on Yarn Spinner, the friendly tool for dialogue trees, on Patreon.

If you just want a template you can make memes with, use one of these!

If you want high-resolution PNGs (1920 by 1080, PNG) of each of the images, download this zip!

These images are licensed under CC-0. They contain material from the following sources; if you’re using them in your own works, you’ll need to acknowledge the CC-BY elements:


We made these because we’re in the middle of writing Head First Swift, to be published by O’Reilly Media. The Head First series of books is intended to be a lighthearted and fun way to teach technical content, and my co-author, Paris, asked if we could add a galaxy brain meme in the book. Unfortunately, the nature of memes means that not only do we not have permission to publish the material in a book, it’s next to impossible to try and track down the rights-holders for those images. So, I made my own.

While I was making them, I made a couple of changes to the commonly-used formula. The initial image in most galaxy brain sequences shows an x-ray image with a picture of a scaled-down brain; I’ve always found this to be pretty ableist, especially since the meme is frequently deployed to make fun of people with bad opinions. Bad opinions are rarely the result of brain physiology. So, I opted to make the first image simply a non-glowing brain.

After posting the images on Twitter, I received several requests for a version of the images that didn’t just use the standard masculine model. Hot takes aren’t the exclusive domain of men, so I put together an additional set. (When I made these, I was glad that I didn’t make the first image use a small brain, because that would have made that image much more likely to be used in isolation as a sexist trope.)

Thanks for reading this far, and I hope these pictures bring you joy!

Symbolic Analysis with Python and Z3

This is a text version of a talk that I gave at PyCon AU 2019.

Let’s say you’ve got this program:

pie_price = 3.14

num_pies = int(input("How many pies?"))

pie_owing = pie_price * num_pies

if pie_owing > 10:
    print("You're over the pie budget")

How do you test that the line that prints “you’re over the pie budget” can run? One way is to just run the program, type in a large number, and verify that you see it.

But what if you couldn’t ask for input? For example, maybe this part of the code is buried deep within a larger process, and reaching it is tricky; maybe the code under test is operating in a continuous integration environment, and no user input is available. What do you do then to ensure that this line is reachable?

Why, producing a formal proof, of course. It’s the only sensible way.

In this post, we’ll walk through the theory and practice of using symbolic execution, a static analysis technique, for bug discovery. In particular, we’ll focus on a specific type of bug: how can we prove that a line of code is, or is not, reachable?

How to solve it

Let’s start by reframing the question into something more formal:

For any given line of code, is there a set of inputs for the program that causes that code to be reached?

Or, to put it another way:

What are the constraints on the input that cause a line of code to run?

Let’s work the problem by doing it by hand. Here’s the code again:

pie_price = 3.14

num_pies = int(input("How many pies?"))

pie_owing = pie_price * num_pies

if pie_owing > 10:
    print("You're over the pie budget")

We know from the first line that pie_price is 3.14. However, we don’t know the value of num_pies, because it depends upon user input. In order for any of the rest of the code to work, though, we need to have a label for the value stored in num_pies.

This is where the symbol in symbolic execution comes in: we’ll introduce a symbolic value – let’s call it 🥧 – and declare that the variable num_pies contains 🥧. We don’t know anything about what’s stored in 🥧, but we do know some facts about it.

Specifically, we know a single fact about it right now: 🥧 is an integer, which means that it supports any operation that other integers support: addition, multiplication, comparison, and so on.

Our next line, pie_owing = pie_price * num_pies, has a similar problem: we can’t know the value of pie_owing, because it’s the result of a multiplication between a known (or concrete) value and the symbolic value 🥧. So, what do we store in pie_owing? We’ll store the entire expression pie_price * 🥧 in there.

The final line of code before the print statement is a conditional: if pie_owing > 10. If we proceed on to the next line, then it follows that the value of pie_owing – whatever it is – is greater than 10.

We now have enough information to put together a collection of logical assertions that must be true in order to reach the print statement. They are:

  • pie_price = 3.14
  • num_pies = 🥧
  • pie_owing = pie_price × num_pies
  • pie_owing > 10

Great. Our next question is: can we demonstrate that these equations can all be true at the same time?

Could we even do it… with a computer?

Proving it with Z3

The Z3 Theorem Prover is a library from Microsoft that’s capable of, among many other things, answering this problem. It also has bindings to lots of popular languages, including Python.

To answer our question, we’ll construct several equations that represent the constraints on the input that are in place when the print line is reached, and feed them into a solver; we can then ask the solver to check to see if they can be true at the same time.

from z3 import *

# Create the solver
s = Solver()

# Declare our variables: "pie_price", which we know the 
# value of, "num_pies", which we don't, and "pies_owing", which depends upon the values of the other two
pie_price = Real('pie_price')
num_pies = Int('num_pies')
pies_owing = pie_price * num_pies

# Assert that pie_price is equal to 3.14
s.add(pie_price == 3.14)

# Assert that pies_owing is greater than 10
s.add(pies_owing > 10)

# Ask if these these can be true at the same time
s.check() # returns "sat" - they can be!!

We’ve now demonstrated that in order to reach the line, print("You're over the pie budget"), a set of equations must be true at the same time; additionally, Z3 indicates that they can indeed be. Therefore, we’ve proved that the line is reachable, and we never needed to ask the user for input.

Incidentally, we can ask Z3 to produce a model of its solution, which means it will produce a value for all of the variable in question, including num_pies – the value we’d ordinarily get from the user. That is, Z3 can produce a value for num_pies that would result in the print statement to run.

s.model()[num_pies] # 4

Generating the Equations Automatically

In the previous example, we had to read through the code and manually produced the equations that are in place. Wouldn’t it be nicer, though, if we could have a system do this for us?

To do this, we’ll take advantage of the fact that Python is very easy to decompile into byte code. Using the dis module, we can take any Python function, and produce the byte code that represents it. Converting the code to byte code is important, because byte code is significantly simpler, and easier to analyse.

Once we have the byte code, we need to find a way to determine the possible paths through the code that execution can take, depending on the inputs given the program. We then need to determine the constraints on the variables that affect the path; if at any point the constraints are not compatible with each other, the path is impossible. If all paths that reach a line of code are impossible, then the line of code is unreachable under any circumstance.

For example, consider this snippet of code:

i = 1

if i == 0:

There is theoretically a path of execution that goes from line 1, through line 2, and ends at line 3, but if you think about it, it would require the variable i to be equal to 0 and also to 1. This is impossible, and as a result, the path is impossible; because this is the only path that reaches line 3, that line is unreachable.

This means that our next problem is: given a block of code, how do we calculate the possible paths through that code?

Basic Blocks and Control Flow Graphs

As before, let’s start with a chunk of code, which we’ll use as our example.

def test(a):
    x = 0

    if a > 0 and a < 5:
        x = 1

    b = a + 1

    if x == 1 and b > 6:

Our question for this code is: can the final line of code, print("Hello"), ever be reached? And can the process of discovering this be automated?

Let’s start by asking dis for the byte code.

import dis

This produces something like this (I’ve truncated it to the first few lines):

  2           0 LOAD_CONST               1 (0)
              2 STORE_FAST               1 (x)

  3           4 LOAD_FAST                0 (a)
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               4 (>)
             10 POP_JUMP_IF_FALSE       24
             12 LOAD_FAST                0 (a)
             14 LOAD_CONST               2 (5)
             16 COMPARE_OP               0 (<)
             18 POP_JUMP_IF_FALSE       24

  4          20 LOAD_CONST               3 (1)
             22 STORE_FAST               1 (x)

  5     >>   24 LOAD_FAST                0 (a)
             26 LOAD_CONST               3 (1)

Each one of these lines is a low-level instruction to the Python virtual machine. The Python VM is a stack machine, which means that the instructions work by pushing and popping values on a stack. For example, the LOAD_CONST and LOAD_FAST operations push values onto the stack (either a constant value or a value stored in a variable), while the COMPARE_OP operation pops two values off the stack, compares them, and pushes the result back onto the stack. Additionally, certain instructions are responsible for controlling the flow of execution: the POP_JUMP_IF_FALSE instruction pops a value off the stack, and if it evaluates to False, jumps to a numbered instruction; if it evaluates to True, it proceeds to the next instruction instead.

How, then, can we find the possible paths through the code? One popular approach is to decompose the stream of instructions into basic blocks: runs of instructions that are only ever entered at the start, and only ever exit at the end (that is, it is impossible for the program to jump to a point that’s in the middle of a basic block).

To determine these basic blocks, the instructions are scanned, and certain instructions are marked as leaders:

  • The first instruction is a leader.
  • Instructions that are the destination of a jump are leaders.
  • Instructions following a conditional jump are leaders.
  • Instructions following a ‘stop’ instruction are leaders.

Once you know the leaders, you can then group up the instructions according to the most recent leader.

Next up, you form the connections between the blocks. Blocks have successors (blocks they lead to), and predecessors (blocks that lead to them.)

  • Blocks that end in an unconditional jump have one successor – the target of the jump.
  • Blocks that end in a conditional jump have two successors – the target of the jump, and the next instruction.
  • Blocks that end in a ‘stop’ instruction have no successors.
  • All other blocks have a single successor: the following instruction’s block.

With these rules in mind, we can take the byte code for our example function, and figure out the blocks.

The basic blocks in the program.

Given these blocks and the way they link together, we can generate the control flow graph of the program. This graph shows how the blocks connect, and allows us to find the paths that execution can take through the program.

The control flow graph of the program.

We’re now ready to start testing the paths that lead to the print("Hello") function call, which is the second-to-last basic block (it’s the blue block, second from the right of the above image.) For the purposes of this article, we’ll select one of them arbitrarily, and prove that the path is valid or not; the same steps apply for testing any path.

A specific path through the control flow graph.

Finding impossible paths

In order to perform normal execution of the code, Python steps through each instruction, and performs them as normal – loading data into memory, requesting that the system get input, and so on. However, this only works when we’re running the entire program, which includes all of the work done to decide what parameters to use when calling the function test. When we perform symbolic execution, and are examining only portions of the program, we no longer have the ability to know concrete values for every variable.

Let’s take a closer look at the first basic block:

  2           0 LOAD_CONST               1 (0)
              2 STORE_FAST               1 (x)

  3           4 LOAD_FAST                0 (a)
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               4 (>)
             10 POP_JUMP_IF_FALSE       24

The third instruction in this disassembly loads the contents of the variable a, and pushes it onto the stack. However, a is a parameter to the function, which means it’s not possible to get a concrete value for the variable when considering the code in isolation.

This means that when we encounter the instruction LOAD_FAST a, we need to introduce a new symbolic value. That’s not the only symbolic value we need to track, though: on lines 1 and 2, we load the number 0, and store it in the variable x. This means that we need to declare to Z3 that the variable x exists, and assert that it is equal to 0.

Additionally, if we’re testing a specific path through the code, we already know whether the POP_JUMP_IF_FALSE will jump or not. In the case of our selected path, if we’re proceeding from the first block to the second, it means that we’re taking the path in which the value on the stack is True. This mean that we also assert that the result of comparing if a is greater than 1 is True.

In effect, setting a variable now means creating and recording an assertion that the variable contains a certain value, and when encountering a conditional jump, we assert that its condition is true (if we’re taking the true path), or false (if we’re not).

We continue this execution, creating additional constraints on the values as we encounter instructions that interact with them, and at the end of each block, we feed them into Z3 and ask if the assertions are compatible with each other. If they’re not, then the path is impossible, and we try again with a different path. If all of the paths that reach a block are impossible, then that block is unreachable under any circumstances.

In the specific case of our example, the line print("Hello") is unreachable. For it to be reached, it would require either the value of a to be both greater than 5 and less than 5 at the same time.


Symbolic execution is really fun and useful, but it isn’t without its drawbacks. In particular:

  • It’s vulnerable to an explosions in the number of paths, especially when looping (and especially if the code can potentially loop infinitely)
  • If the same region of memory is referred to by two variables, it can be challenging for the analyser to detect this condition
  • Elements in a collection require special handling; do you treat the collection itself as a value, or the values in the collection as individual values?
  • It’s a lot more challenging in dynamically typed situations, where you don’t necessarily know the operations that can be performed on the values that you receive.

Nonetheless, it’s a fascinating field to play in, and can be tremendously rewarding. The video of the talk that I gave at PyCon AU 2019 is embedded below.


Power-Saving in Unity

Learn how to reduce the power consumption of a non-game Unity application, for mobile.

Recently, we were asked to build some software using Unity. That is, we weren’t asked to build a game, but instead, the client wanted an app.

There are a few reasons why you’d want to use Unity to build non-game software.

  1. Cross-platform support. One of Unity’s biggest selling points is the fact that you can write your code once, and Unity makes it easier to bring that code over to multiple platforms, like iOS and Android, as well as desktop platforms.
  2. Graphics support. Being a game engine, Unity is very good at tasks that involve processing either 2D or 3D graphics. In our case, we were asked to build an app for building comic book pages, and that means working with lots of sprites.
  3. C# coding environment. It’s almost always better to write your code in the native language for your chosen platform, but in cases where that’s not feasible, C# is quite good for most platforms. Unity provides a good, performant, and featureful implementation of the language, as well as the .NET runtime.

However, there are a few things that keep Unity from being a great tool for making non-game apps. In this post, we’ll look at one of them, and how to reduce its impact: power consumption in Unity-based apps

This post is largely written with mobile in mind, and with a particular focus on iOS. However, the technique is pretty broadly applicable.

Reducing Power Consumption

The most pressing issue is that Unity, like all game engines, re-draws its content every frame. That’s not something that you need to do in an app, where most of the frames are going to be identical to the previous one. Most of that work is going to waste, and that means wasted power. Wasted power is particularly bad on mobile devices, since it means a needless drain on the device’s battery.

This is particularly striking when you see that an empty scene – one with nothing more than a camera, rendering the skybox – consumes significant amounts of CPU resources. On my iPhone X, for example, rendering the empty scene at 30 frames per second consumes about 20% of the CPU.

To reduce this issue, you can reduce the rate at which Unity updates, by reducing the target framerate. This can be done in a single line of code:

// Request that Unity only update every 1/10th of a second
Application.targetFrameRate = 10; 

This will reduce the amount of work that Unity does, but it has a downside: Unity will only run the Update method on your scripts once per frame, which means it will take up to 100 milliseconds for your code to notice that the user pressed a button. Additionally, setting the framerate to a fixed rate like this means that any moving content on your screen will always visibly lag. On top of this, we still haven’t really solved the original problem: the screen is still updating, many times a second, and each time it does, there’s only a small chance that anything that the user sees will have changed.

The solution, then, is to find a way to make Unity never re-draw the screen unless something happens. What that “something” is depends upon the details of your app, but generally always includes things like user input: you want to re-draw the screen when the user taps the screen, or drags their finger over it, because that’s highly likely to mean they want to press a button or drag an object around.

Hacking the Render Loop

Unity provides a way to control the player loop – the set of things that Unity does every frame. This includes re-rendering the scene, but also covers tasks like clearing the render buffers, collecting input, and – most importantly – running the Update methods on scripts. Using the PlayerLoop class, you can inspect the contents of the player loop, remove certain subsystems, and add some of your own as well.

Or, you could blow the whole thing away.

using UnityEngine.Experimental.LowLevel;
// Get the default loop
var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
// Remove _everything_ from it!! There are no rules! Unlimited power!!
playerLoop.subSystemList = null;
// Apply this new "player loop" - the game will immediately stop

If you remove all subsystems from the player loop, you effectively remove almost all of the work that Unity does each frame. There’s still some overhead that can’t be disabled, like the code that actually invokes the player loop, but by doing this, we’re getting rid of almost all of Unity’s work.

Disabling the Renderer

One of the things that emptying the player loop doesn’t directly control is the fact that Unity will attempt to run parts of the render loop as long as a camera is active in the scene.

To work around this, we can just disable the camera. However, if you do this in an Update function, the screen’s display will have already been cleared at the start of the frame. As a workaround to this, we can disable the camera, and then immediately tell the camera to render the frame. Because we won’t be clearing the display at the start of the next frame (there won’t even be a next frame), the frame will remain on screen.

As a result, the amount of CPU usage is dropped significantly. In the following image, I’ve dropped the CPU down to 3%. It’s not zero, but it’s very close; in fact, at this level of usage, the biggest power drain on the device is the screen.

Putting it All Back

So, we’ve now managed to completely stop the player loop, at a tremendous energy saving. But now we have another problem: how do we wake the app back up again when the user interacts with the screen, if all of the code that checks for input is no longer being run?

The solution is to look for input events that come from the system, and use that to wake up the application. To do this, we’ll need the following things:

  1. A way to run native code when touch events occur
  2. A way to run C# code from that native code, which restores the player loop

Everything up until this point has been entirely cross-platform, and should work on all platforms. However, because we’re now looking at native code, we need to focus on the native code implementation details for a single one. In this post, we’ll look at iOS. If you’re an Android developer and want to contribute how you’d do this in Android, let us know!

To detect any touches, there are two places we could put our code: we could override the view controller that Unity places its view in, or we could go one level lower and detect all touches that the app receives. It’s actually simpler to do that, so let’s get started.

First, we’ll need to create a new subclass of UIApplication. This is different to the similarly-named UIApplicationDelegate; the UIApplicationclass is an object that represents the entire application, while the delegate is simply an object that responds to events that happen to the application.

You typically never need to create your own subclass of UIApplication, and Apple doesn’t recommend that you do it, unless it’s for the single specific purpose that we’re about to do here: intercept and process UI events, before forwarding them to the rest of the application.

So, let’s get started. First, we’ll create a new file in our Unity project, called TouchHandler.mm, and add the following code to it:

@interface TouchDetectingApplication : UIApplication
- (void)sendEvent:(UIEvent *)event;
@implementation TouchDetectingApplication
- (void)sendEvent:(UIEvent *)event {
    // Handle touch event here!
    [super sendEvent:event];

The sendEvent method will be run on every input event. It’s very important that we call the super implementation, since without doing that, no input will ever be delivered to the app. We’ll come back to this method in a bit.

Next, we need a way to notify our C# code that a touch has occurred. To do this, we’ll send a pointer to a C# method into the native code at game start; this method will restore the game loop, and resume rendering.

We’ll do all of this in a MonoBehaviour, which you can attach to an object in the scene. The following code also contains an example of how to stop and resume the camera, too.

public class FramerateManager : MonoBehaviour
    // A singleton instance of this class. Necessary, because the 
    // callback must itself be static; there are other ways to do 
    // this, but this serves fine for this example.
    private static FramerateManager instance;
    // The type of the C# callback method that the native code will 
    // call.
    public delegate void EventDelegate();
    // This method will be called from native code when a touch 
    // input arrives. This method must be static.
    public static void TouchEventReceivedFromNativeCode()
        // Restore the original player loop.
    // This is a native function that we'll call, and pass the 
    // TouchEventReceivedFromNativeCode method to as a parameter.
    private static extern void _AttachEventHook(EventDelegate actionDelegate);
    // The number of frames remaining before we stop the loop. We 
    // leave a little buffer time after the last touch.
    private const int framesBeforeStopping = 5;
    private int framesRemaining;
    // A cached reference to the main camera. Necessary, because 
    // Camera.main only returns a valid value when there's an 
    // enabled camera in the scene.
    private Camera mainCamera;    
    void Awake()
        // On game start, call the native method, and pass it the 
        // method we want it to call when touches occur. The native
        // code will keep a reference to this method as a function
        // pointer, and call it when it needs to.
        // Set up our instance method.
        instance = this;
        framesRemaining = framesBeforeStopping;
    private void Update()
        // Count down until we're out of time.
        framesRemaining -= 1;
        // Time to stop.
        if (framesRemaining == 0)
    private void EnterLowPowerMode()
        // Remove everything from the player loop
        var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
        playerLoop.subSystemList = null;
        // Cache a reference to the camera
        mainCamera = Camera.main;
        if (mainCamera != null)
            // Disable it!
            mainCamera.enabled = false;
            // We just disabled the camera, but if we called this 
            // in an Update function, it cleared the frame buffer 
            // before this frame started. To prevent being left 
            // with a blank screen, we manually re-render the 
            // camera right now; this image will remain on screen 
            // until normal rendering resumes.
      // We're done! The game will stop after this frame, and will 
      // wake back up when TouchEventReceivedFromNativeCode is 
      // called.
    private void LeaveLowPowerMode()
        // Restore the number of remaining frames before we stop 
        // again
        framesRemaining = instance.framesBeforeStopping;
        // Re-enable the camera so we resume interactive framerates
        if (mainCamera != null)
            mainCamera.enabled = true;
        // Restore the default player loop; the game will resume.

We now need a way to receive a pointer to the C# method TouchEventReceivedFromNativeCode. This is done in the _AttachEventHook function, which is defined in native code and called from C#.

Add this to your .mm file:

// Declare the C++ type of the function pointer we'll receive from 
// C#.
typedef void (*EventDelegate)();
// Create a variable to store that function pointer.
static EventDelegate _eventDelegate = NULL;
// Declare that this function is a C function, and its name should not be mangled by the C++ compiler.
extern "C" {
  void _AttachEventHook(EventDelegate actionDelegate);    
// Finally, write the method that receives and stores the event 
// handling function pointer.
void _AttachEventHook(EventDelegate actionDelegate) {
    // Just keep it around.
    _eventDelegate = actionDelegate;
    // Log that it happened, too.
    NSLog(@"Event logging hook attached.");

We’re almost done. We now need to call the _eventDelegate function whenever a touch event lands.

Replace the sendEvent method in the TouchDetectingApplication class with this:

- (void)sendEvent:(UIEvent *)event {
    // Handle touch event here!
    [super sendEvent:event];

Finally, we need to tell the sytem to use the TouchDetectingApplication class, instead of the default UIApplication class.

Important note: While Unity will automatically copy any .mm and .h files into your project when you build the player, it will not do this step for you. Additionally, when you choose to do a build that Replaces the player (as opposed to Appending it), it will blow this change away! Fortunately, it’s a single code change, but you do need to remember to do it.

Open the main.mm file, and find the following line of code:

UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);

Replace it with this:

UIApplicationMain(argc, argv, @"TouchDetectingApplication", [NSString stringWithUTF8String: AppControllerClassName]);

The application will now use that class for its UIApplication, and it will send wake-up prompts when touch events occur!

Wrapping up

This technique is extremely useful for building apps that don’t need to re-draw the screen all the time. If you use it, let us know!

🎬 Entity Component Systems

Entity Component Systems (ECS) and You: They’re Not Just For Game Developers from the O’Reilly Software Architecture Conference 2019, in New York City. We’re scheduled to give an updated version of this talk at the Software Architecture Conference 2020, also in New York City.

⚠️ The slides from the slightly newer version of this talk (Software Architecture Conference 2020 in New York City) are now available!

Below are some of our favourite links relating to ECS. We hope you find them useful!

Follow the presentation team on Twitter at @parisba, @themartianlife, and @the_mcjones.