Time Dilation

The naively ambitious starting point for this project was the idea for a space farming game, wherein the player must manage an interplanetary farming supply chain at relativistic distances and speeds. The core mechanic would involve deciding when to send off your ships at how fast such that they return from their voyages, time dilation and all, with a full harvest of crops.

Pretty early on I encountered two glaring problems with this idea. To start, a game centered around logistics management combined with astrophysics must have such a small niche that it might not even exist, but more importantly I realised that I hadn’t wrapped my head around time dilation enough to do anything productive with it. I needed to approach the concept in a much smaller way first.

I scoped back and tried to start visualising time dilation in a more approachable (and manageable) way. An Intro To Special Relativity helped me begin to grasp at the concept, and at the very least provided the mathematic foundation to start putting something together in Unity.

The google image result for “Time Dilation”. Not particularly intuitive.

The Universe

public class Universe : MonoBehaviour
    public static float c = 2;
    public static float InverseGamma(float v)
        float y = 0;
        y = Mathf.Sqrt(1 - Mathf.Pow(v, 2) / Mathf.Pow(c, 2));
        return y;

The class above controls the laws of physics for my simulation. c is the absolute maximum velocity in the world (speed of light), which is very low for the sake of demonstration. InverseGamma() is the equation that describes time dilation, or the Lorentz transformation. In this case, because all of our scripts run on the observed objects and not the observer (more on that below), we use the inverse transformation.

Controlling Time

public class TimeController : MonoBehaviour
    float velocity;
    Vector3 pPosition;
    public float localTimeSinceStart = 0;
    void Start()
        pPosition = transform.position;

    private void FixedUpdate()
        //Calculate velocity in units per (realtime) second:
        Vector3 vel = this.transform.position - pPosition;
        vel /= Time.fixedDeltaTime;
        velocity = vel.magnitude;  // Units per RT second;

        pPosition = transform.position;

        //Acculmulate local time elapsed
        localTimeSinceStart += GetDilatedInterval(Time.fixedDeltaTime);

    public float GetDilatedInterval(float observerTimeElapsed)
        //In the reference frame of /THIS/ object, the 
        //transformation is the INVERSE of the observer's reference frame.

        //i.e. we have to inverse the dilation equation 
        //to get what the time is from this object's 
        //perspective, relative to the observer.
        return observerTimeElapsed * Universe.InverseGamma(velocity);

The TimeController class controls the timing functions of the simulation. Each object that can move has this script attached. The script will calculate and store what the time since the start of the simulation is for that object, from the observer’s perspective (i.e. relative to the object at rest).

To calculate the ‘local’ time, we use Unity’s physic simulation tool, fixedDeltaTime. Unlike the standard “Update()” loop which is subject to variable framerates, “FixedUpdate()” runs on a separate thread and guarantees a fixed interval between its cycles. This is good for simulating physics in general, and in this case I’ve used this fixed time as my ‘quanta’ from which all other time is based. A single interval of the fixed loop is stretched out (via the Lorentz transform) for the objects which are moving quickly.

This script replaces the standard Time class for the Unity game engine. For instance, if an object is supposed to change colour after 5 seconds have elapsed, instead of retrieving Time.realTimeSinceStart, we can query this.TimeController.localTimeSinceStart.

Managing Events

There is a definite liberty that we are taking with this whole situation. If the speed of light is low in this universe, we as observers would only be seeing the light from these events much later, and the idea of simultaneity would immediately break down (as it does in our universe at interplanetary distances).

To work around this, I have situated us, the observers, as extra-dimensional beings not subject to the slow speed of light or any of the other laws of physics. There is a sort of aether we see (the ‘scene view’) in which things do, absolutely, at a specific time, happen.

To try to visualise the actual laws a bit more appropriately, I have set up “events” that happen according to each object’s own internal (local) clock. Each object has a ticking hand that revolves around it once each of its own seconds. Every revolution of the hand (so every local second) the object emits a ‘light pulse’ in the direction of the observer at rest within the world.

To try to further highlight the time stretching, each object cycles through a range of colours and the light it emits reflects it colour at the time of emission.

public class EventPulse : MonoBehaviour
    [SerializeField] float eventInterval = 5f;    // In local time
    [SerializeField] GameObject lightBeam;
    [SerializeField] Transform pulseTarget;

    TimeController timeController;
    ColourOverLife colourOverLife;

    float lastEvent = 0;
    void Start()
        colourOverLife = GetComponent<ColourOverLife>();
        timeController = GetComponent<TimeController>();


    private void FixedUpdate()
        if(timeController.localTimeSinceStart - lastEvent > eventInterval)
            lastEvent = timeController.localTimeSinceStart;

    private void EmitPulse()

        Vector3 toObject = pulseTarget.position - transform.position;
        GameObject pulse = Instantiate(lightBeam, transform.position, Quaternion.LookRotation(toObject));

       //Set pulse colour to object colour:


So only once the bean of light emitted from an object reaches the observer will the observer have any information about that object (at the “time” that the object’s light left it).

The colours of each object cycle through this spectrum:

The Future

There are two next steps I’d like to take before considering how to gamify this manageably:

  1. Implementing length contraction. Similar to time dilation, in that it involves the Lorentz transformation, length contraction is a bit trickier to implement in Unity. Unity’s time system is easy to access but the space system (the “Transform” class) is a bit more beholden to our nonrelativistic view of the world. I’d like to put more thought into how to visualise length contraction.
  2. Visualising what the “Observer” sees. I wonder if there’s a way to render out the view from the observer, given the ‘lightbeams’ that it is receiving. Perhaps there is a ‘relativistic renderer’ somewhere in there!

A Generalisable Astrolabe for a Procedural Universe


This is a project for a class on Time. It is also an extension of an ongoing personal project to create a procedural universe. The overarching idea here is to be able to recreate an ancient astronomical timekeeping device (an Astrolabe) for any latitude on any procedurally generated planet.

The Fundamentals

Before tackling the ambitious end goal of a generalisable astrolabe, I first needed to wrap my head around how a standard, earth-based one works.

The above gif helped a lot in my understanding. The trick of an astrolabe, or rather the bulk of the mechanism, is a stereographic projection of the hemisphere you’re interested in onto the equator from the point of view or the opposite pole.

A stereographic projection of the Tropic of Capricorn onto the equatorial plane

‘Stereographic’ is a fancy term with lots of maths behind it. In short, though, the idea is ‘how do you get a representation of a 3D world onto a 2D plane?’ In the years since the Astrolabe’s conception we’ve developed a much more abstracted solution to that problem – a camera!

A camera is just a stereographic projection tool that works out the maths for you! With the above image I was able to set a field of view (FOV) for the south pole projection camera at (90+epsilon)/2 * 2 , or 90 + epsilon where epsilon is the obliquity of ecliptic (i.e. how tilted the planet is)

The Design

One way that I could have constructed the Astrolabe in Unity would be to ‘simulate’ the workings of the solar system as we currently know it. In this case I would program the planet to rotate about its axis, offset that axis from the Sun a little, then rotate that around the Sun. This would achieve the desired relative celestial positions as it would most closely resemble the way things actually work.

In the spirit of the original astrolabes, however, I did not do that. In my program the ‘planet’, or the reference for all the projection and maths, is fixed. It’s the center of the universe and all other bodies rotate around it in strange and exciting ways.

At the core of my scene are two cameras rendering separately.

The first is the ‘observer’ camera, which shows in the main viewport. This camera sees an infinitely far away dome with the starmap texture on it. This camera is what you would see if you were standing on the surface of the planet.

The second camera is at the south pole and points directly North along the axis of rotation. Because the stereographic projection requires the sphere representing the celestial dome to be the same size as the planet, there was some trickery involved in getting both cameras to see -and ignore – the right things.

The Parameters

As the Obliquity parameter changes, the celestial sphere (star map) rotates around an axis perpendicular to the north-south axis. This creates the effect that the planet is ’tilting’ where in actuality it is everything around that is tilting. This will determine which section of the celestial dome is visible to the observer, by shifting the dome itself

As Latitude changes, the observer camera moves around the surface of the planet. Latitude will determine many things such as how high the ‘north star’ is, the day/night ratio, and the curviness of the astrolabe’s interface. This will determine which section of the dome is visible to the observer, by shifting the equator line.

As the Rotation changes, the celestial dome and all its innards rotate around the north-south axis of the planet. This simulates one day/night cycle of the planet.

The Seasons setting tilts the sun up and down in the sky, simulating an orbit of the planet around its sun. the ‘summer’ season means that the sun is furthest “up” along the north/south axis (if “up” is North), and the winter season means that the sun is furthest “down”.

Telling Time

The astrolabes that I read about had incredibly complex mechanisms for telling the time. In my sketch I have tried to pare down the time system to be as simple as possible. Precision not guaranteed.

There are three elements requires to tell the general time on this astrolabe:

  • The “Hand” – the single white line that points up in standard mode (as opposed to “track” mode.
  • The numbered dial around the outside that looks like a clock face.
  • Some recognisable star in the sky near that line.

The Hand” represents an imaginary line that shoots up out of the horizon and crosses through the north star (or equivalent). When a star crosses that line, move the astrolabe so that the star map shows that star crossing The Hand. The Hand will now point at (around) the correct time.

The References:

Mafia Mod – Bandits?

This is a 4-6 player game.


  • Each player gets [players] number of coins.
  • During the night, the mafia takes one coin from any player and puts in anywhere in play (i.e. another player, or the center pool).
  • During the day, the villagers have one minute to discuss and choose someone to accuse. At the end of the minute, on the count of three all villagers point at their accuse.

Night Time:

  • During the night, the mafia steals one coin and puts it in the mafia pool
  • During the day, the villagers have one minute to discuss and choose someone to accuse. At the end of the minute, on the count of three all villagers point at their accuse.

Day Time:

  • During the day, the villagers have one minute to discuss and choose someone to accuse. At the end of the minute, on the count of three all villagers point at their accuse.
  • Being accused means the IRS investigates you. An investigation is expensive which means you lose coins. The number of coins you lose is [Number of Accusations Received] – 1
  • If a player loses all their coins, they are shunned from the village.
    • In the case the player is the mafia, the villagers win.
    • In the case that the player is a villager, they are no longer in play. Also, the mafia gets one coin in the mafia pool.

To Win:

  • As Mafia, get 6 coins into your mafia pool (or survive until there are 2 players)
  • As Villagers, shun the Mafia

Space Juice

Project Files

  • Punch it
  • Engage
  • Jump
  • Make it so
  • FTL
  • fwoosh

Whatever you call it, travelling large distances in sci fi requires some sort of faster than light travel, and since the beginnings of cinema folks have been trying to find interesting ways of portraying the mechanics of those voyages.

Here I attempt to juice a hyperspace entry. I take inspiration from Star Wars, Star Trek (2009), and Battlestar Galactica (2003).

There are three beats I hope to hit:

  • A gradual crescendo increase in speed and warpness until some sort of threshold, where the ship seems almost ready to break through some barrier but can’t quite just.
  • The “Punch It” moment where you enter hyperspace and feel like OMFG
  • Dropping out of hyperspace. This should feel like reality folds back into existence around you and evoke a sense of vertigo.

Blue Marble – Mad Dash Home

As all good stories are, this one is set in space.

Link to project files

This (vaguely) Marble Madness inspired sketch explores physics and motion in 3 dimensions. The objective of the game is to roll around and hop between small, close planets in search of missing parts for your broken spaceship.

At the core of the sketch is a gravity system that works based on the well known F=G(M1.M2/r^2) equation. The force applied to the player’s rigidbody is the sum of G(Mn)/rn^2 where:

  • G = some constant that has been tweaked for the size of the world
  • n = each planet (this function is an iterator)
  • M = an adjustable ‘mass’ for each planet
  • r = the Vector3 distance between the player and each planet

Since gravity works on an inverse square law (the result of dividing by r^2), being closer to a planet means that its influence is quadratically higher. When you’re near a planet you are ‘captured’ by that planet’s gravity, but when you’re in space the forces are weaker and relatively more competitive.

Rube Goldberg Forever

In the land of cubes the sphere is king

Find the project on GitHub

The sketch runs smooth, but my screen recorder likes to be slow…

The story here isn’t as fully developed as it could be, rather this is an exploration of vaguely related themes and references. There’s blue things and red things and (hopefully) surprises and throwbacks. The non-deterministic physics of Unity threw off my plans of a predictably machine, so rather I tried to create the opportunity for little moments of delight, such as if you happen to see the red ball again, or you notice that your blue light is “winning”.

I started out hoping to make a zero-G Rube Goldberg, but as I was playing around with the rocket mechanics I discovered that it could be a lot more fun/interesting to have the rocket fly around haplessly in a gravitied environment, then crash and become part of the scene itself.

The zero-G plan turned into an anti-G plan, in which the ball activates a giant red button because of course there’s a giant red button. The giant red button flips the gravity of the world and all the falling pieces begin falling up.

I played around with how to handle the anti-G section for a while, and settled on a smooth camera flip a brief pause after the gravity flips. It seems to nicely accentuate the vertigo of switching the direction of ‘up’, and it’s a neat little mindf— that what were the bottoms of things are now the tops.

Finally, once one has in place a button for switching gravity on a whim, it is almost impossible for one to not put another button ‘above’ it. With no official end, this machine will keep on going until the physics breaks or the iewer gives up. It is a slow march from the joyfulness of bouncing balls and blinking lights into the endless despair of hoping something will change but knowing that it won’t.

The Joy of Making Things

I enjoy stories. Many years ago I stumbled upon the realisation that, since I enjoy stories, perhaps I would enjoy making them too. I did.

I enjoy games. I am now at a point where I am considering that, since I enjoy games, perhaps I will enjoy making them too.

Stories are for many things. For me they are sometimes about discovery or escape or explosive emotional payoffs. The best stories are for people mostly.

Games are for many things. For me they are sometimes about discovery or escape or challenge. The best games are for people mostly.

Continue reading “The Joy of Making Things”