World transitions: Manipulating viewports in Spirit Shift

This post is originally from here.

Spirit Shift was made in 3 days for the Ludum Dare 30 game jam, based on the theme of ‘connected worlds’. After a couple of hours of discussion we worked out what we were going to make: an infinite runner where the player can (and has to) phase-shift between worlds rapidly. Since this was the core mechanic of the game we wanted it to look fluid and not confuse the player. I had done some GameMaker tutorials a few years prior and remembered a little about having multiple viewports, so I knew it would be possible and a lot easier than coding it by hand. It took a day and a half.

Tunnel Vision

Once I’d done a couple of GML tutorials and read through some of the documentation (something I’d be doing a lot of over the jam), I got some basic platforms generating and moving across the screen. Turns out GameMaker doesn’t support having multiple rooms active, so I ended up having 3 separate ‘lanes’ spaced vertically across a single room. When the player shifted worlds it would just be a case of moving them up or down to the appropriate lane.
After mucking about with views for a while I knocked up the following prototype:

Centre portals

 

This is how we originally pictured the world portals. The idea was that you’d almost be going through a tunnel, as each world shift caused the next one to expand out and fill the screen. At this point the shifting only worked the first time, so in the following demo video I have to restart the program each time:

The main (yellow) world expands out of view, the next (cyan) world expands to take its place, the last (green) world follows suit, and a temporary fourth view expands from nothing in the centre to take last place. At least, that’s what seems to be happening. In truth GameMaker doesn’t allow a viewport to be larger than the window, so to get the main view to expand I actually keep it the same size and shrink the game area it represents, essentially zooming in. Having now worked it out, this trick became very useful later on.

A world of problems

With the prototype in place we started working through the design issues apparent in the way I was doing things so far.

  1. Having the portals in the middle of the screen drastically limited the play-space. Although GameMaker supports sprite depth, views themselves override this. Even if the sprite depth for all of the cyan platforms is set so that they appear in front of the yellow ones, the viewport itself takes precedence and completely covers everything behind it.
  2. It’s ugly. Having the viewports overlap each other minimizes the total area they take up, while giving us the ‘tunneling’ effect of going into the screen as they expand. Unfortunately it just doesn’t look good with those hard edges. We could have had clever bordering artwork to smooth the transition, but a hole in the world is a hole in the world.

Addressing the first issue was pretty easy. All I’m doing is linearly interpolating between the position and size of each viewport to its target position and size, meaning I can actually place them any way I want and the transition will still smooth out over the same (arbitrary) time period. Here’s the expansion demo again, this time coming from the top-centre of the screen:

The sticking point is that second problem: it’s still ugly. The artists on the team were (rightly) concerned about what the backgrounds were going to look like overlapping in that way, or if we would even want backgrounds with a system like this.

A fresh perspective

After some more discussion we agreed on a kind of roulette system, mocked-up here by one of the artists:

view mockup

Not only is this much better aesthetically, it actually improves the gameplay too. Since each viewport has the same width but different heights, I had to widen the area of the game world shown in each port in order to preserve aspect ratio. This had the knock-on effect of allowing the player to see further ahead in the world they’re about to shift to, helping them plan ahead.
The final breakdown for the portal heights had the main port taking 5/8ths of the window height, the next port with 2/8ths (1/4) and the last one with 1/8th. These are roughly the same proportions as the mock-up.
The only downside to this approach was that it made transitions more complicated: I now had to morph not only the viewports but the areas they represented too. Here’s what happens when the player shifts:

  • The main viewport slides down off the screen.*
  • The next viewport slides down, expands vertically and zooms in to replace it.
  • The last viewport slides down, expands vertically and zooms in to replace that.
  • A temporary fourth view slides in from the top.* Once the transition is complete, the temporary view is disabled and what was the main view now takes last place.

*Sort of.
In much the same way that GameMaker doesn’t allow viewports to be larger than the window, it also doesn’t allow them to occupy space outside the window. A ‘sliding’ viewport is actually vertically shrinking or expanding while zooming in or out. This is functionally similar to the expansion zoom trick from earlier. As one of my lecturers likes to say: in videogames programming, everything is a hack.

39966-shot1

Above is a screenshot from the final game. Below is some footage of the transitions, with the time per transition increased fourfold for clarity. Below that is gameplay of the final game, so you can see how it ended up.
The last thing I’ll say about the viewports is that whenever you shift you’re actually discarding that world and generating a new one at the top. Having a temporary fourth lane was too much hassle for a jam game, so once the transition is complete you can actually see the new world pop in over the old one at the top. Since the backgrounds are detailed and the player isn’t focusing on the top of the window at that time, I think we get away with it. Look out for it in the videos below.