4D Snake

This is a little project that spawned out of an offhand comment. As all the best ones tend to do.

 4D Snake 

At the end of the second-last week of my course, we had a surprise game jam sprung on us, completely open to throw together whatever we like by the next Friday. I was completely blank for ideas, but a friend came up in the break room and started telling me about an idea he had kicking around. To cut a needlessly lengthy story short, events led to me joking that we should do 4D Tetris (because the 3D version’s already been done), which then led to discussion/arguments over whether 4D was even possible.

After going home that night, the thought of doing a 4D game was still bubbling away in my mind, I was still wondering about how you’d go about doing it. After tossing around a few classic games like Pong and Pac Man, I landed on Snake. It’s a pretty simple game, one I’m very familiar with, and one that was quite easy to take into multiple dimensions. From the get-go though, I deliberately avoided googling for 4D Snake, since I figured that plenty of other people have already thought of and done it. I wasn’t interested in knowing the answer, I wanted to figure it out for myself. That’s half the fun.

The main point that came up in the discussions that day was that people have a very difficult time wrapping their head around the idea of a fourth dimension. Even if they’re not one of the ones asking if that means it involves time travel. Mercifully, nobody suggested that it meant there would be things shaking your seat or spraying water in your face as you played. Whenever I try explaining the concept of a fourth spatial dimension, I end up starting out with an example of a 2D world, and how two objects in that world would collide if they moved towards each other. Then show how they can either move around each other by moving up on the Y axis, or show how through movement in the third dimension they can also appear to pass through each other from that 2D perspective. Then I try and explain how it can be extended to a 3D perspective and… generally people’s eyes start to glaze over or their face screws up or they just smile and nod. Or similar. In hindsight I realised how time as a fourth dimension does make it a lot easier to explain the concept, and how two objects can be in the same position yet not be colliding. I still don’t really like it though, time seems like it should be its own separate thing to space and feels like it would just confuse things when you’re only dealing in spatial movement like with Snake here.

My first question was how to represent this mystical magical fourth dimension. The simplest answer to me was to just use a spectrum of colours to represent each position along the axis. It’d be easy enough for Snake, since the field you move around in is of a fairly limited size (I chose a 10x10x10x10 cu- uh, hypercube?) so you wouldn’t need to pick all that many colours, and therefore they’d also be distinct from each other. Or at least they would be after screwing around with the colour values a bit. I started out with just a linear progression of ten points from (0,0,1) to (1,0,0) (via (0,1,1), (0,1,0) and(1,1,0)) but as it turns out, that leaves you with a whole chunk of greens and yellows that all look just about the same as each other. Later on I tweaked them to have things more distinct and visually spread out more evenly.

So to begin with, I just had a little cube on screen that had four spatial coordinates, three being used as its on-screen X, Y and Z position and the fourth being displayed as a colour. Then I had eight buttons to move the cube, two to move it up and down each axis, and I threw in another pair of buttons to rotate which of the coordinate axes were being displayed on which on-screen axis. I added in a big empty cube to give some sense of boundaries, even though it didn’t actually do anything if you went outside of them.

A weekend full of social events meant I had to put it all aside for a couple of days, but there was some good travel time in there which gave me a chance to ponder better control setups than what I had going at the moment. I got to thinking about classic Nokia Snake. It seems that not a lot of people knew this, but there was actually an alternative to just using 2/8/4/6 as a makeshift d-pad for moving your snake up, down, left and right. I remember as a kid thinking how cool those little clip-on control sticks would have been to have and how much easier it would make things to control, but someone already came up with a much better solution. It’s entirely possible to control the game with just two buttons – either 1 and 9 or 3 and 7, whichever you preferred. When your snake is travelling in a given direction, you have three choices. Either keep going the way you’re going, turn to your snake’s left, or turn to your snake’s right. Due to the rules of the game, your snake will continue to travel along whatever axis it’s moving, so the “forward” direction is ineffective and you can’t travel back on yourself so “backwards” does nothing too. So that leaves you with just two controls necessary – one for each direction along the axis you aren’t using. And that’s what this alternative control scheme gives you. When travelling horizontally, 1 or 3 will make you go up while 7 or 9 will make you go down. When travelling vertically, 1 or 7 will make you go left while 3 or 9 will make you go right.

 Nokia Snake on the 8250. Charged the old fella up just to check it out again. 

Likewise in a 3D Snake setup, when travelling along any given axis you only have two directions along two axes to choose from, therefore only four buttons needed. And in 4D Snake? Two directions along three remaining axes. Six buttons required – Up, Down, Left, Right, “In” and “Out”. The tricky part to deal with here is deciding what direction buttons refer to what direction in space. For the sake of simplicity, I decided to assume the game would be played from an isometric perspective, so you could see all three (plus one) axes at once. I also decided against having the movements relative to the snake – firstly, because he was only being represented as a series of cubes so there was no way of telling which way his (say) left would be when travelling vertically. And then once you do start going that way, if you turn left while travelling up, your left would now be pointing down, and I’m not sure how many people would expect Left to make them start moving downwards even if it were visibly clear that he was rolled on his side. So directions relative to the playfield made much more sense. Although while it’s easy to stick with Up and Down mapping to the Y axis when moving along either X or Z, I wasn’t quite sure what to do when moving along Y. In the end I just decided it felt most normal to have Left and Right relate to the X axis and Up and Down would refer to Z. It’s just one of those things players would have to learn.

So with an also rather busy Monday, I made it to Tuesday now with a snake that was actually a snake rather than a single cube, and he would travel in a given direction which could then be set to any other direction and he’d keep heading that way until told otherwise. But again, that was just with the absolute controls I’d already done. I needed to implement the scheme I’d thought up over the weekend. I spent most of that day trying to wrap my head around mapping the controls so that they would remain relative to the playfield regardless of how the snake was actually being “rotated” (eg if the on-screen XYZW were actually showing the coordinates of YWZX respectively), tying it in many, MANY knots in the process but I eventually got there. Didn’t help that I’d mislabelled two of my axes in some of my sketches by accident, so was assigning the wrong numbers to the wrong directions. Oops. But I was pretty happy with myself once I’d fixed that up and the whole thing was working properly. In my excitement I kiiind of ended up staying up til 2:30am adding in an “apple” – an extra cube that would randomly spawn, then respawn somewhere else when you collected it while adding a new segment to the snake. This little thing I’d thrown together was starting to actually resemble a game, and I was getting pretty excited.

At this point it was still fairly incomplete though. The snake couldn’t collide with himself, nor could he go out of bounds. There was no way to die, the game couldn’t end. But the others at school seemed pretty impressed with it, I think I blew a few minds with the whole fourth dimensional rotation thing. I spent Wednesday afternoon/night and Thursday morning fixing a few things up – making it so that the snake could actually collide with itself and die when it did that or move out of bounds, giving it a little death “animation” where it falls to pieces, letting you actually start again when that happens rather than having to relaunch the game, and finally adding in a score counter too. The apples being cubes wasn’t so great, if you ran “through” them (thanks to not being on the same fourth plane as them) you couldn’t see them any more, so I changed them to be spheres that were slightly larger than the cubes, keeping them visible when that happens. I also now had some extra indicators showing where your snake’s head is on each of the three spatial planes, and a friend who dropped by to visit during our graduate showcase suggested I make them highlight when you’re level with the apple, so I added that in. At some point during all this I realised that my perspective shift wasn’t that great, and whipped up a new algorithm that worked much better.

After all the family and friends were done coming through, it was time for some industry guys to have their turn checking out all our stuff. A few of them seemed to like what I’d put together, one in particular had a good long chat with me about it, what did and didn’t work etc. One big thing that came up was that it’s really hard to explain it to players. I have no problem understanding it myself, but trying to then convey that to someone else… I really struggle with it. I do have a few ideas on how to teach the player, which I’d like to explore more if I were to flesh things out a bit more. The game concept is fairly easy to understand if you just boil it down to “you can’t touch things unless you’re the same colour”, if you don’t even mention that it’s 4D then nobody has to get confused by it. And you could use that concept to build up from 2D to 3D by adding in the colour element, then stripping out the colours and having it just play from a 3D perspective. Then once you reintroduce colours from that perspective, it should be pretty easy to come to terms with. Maybe.

 An attempt to show the "perspective shift" function. 

There were a few other things I played around with afterwards, beyond the scope of the game jam and industry night. I kind of thought that having the colours in there makes things kind of easy, since essentially you’re seeing in 4D. You can tell if something’s not aligned on that fourth axis by the difference in colour. Whereas if I strip out the colours, it takes the emphasis away from the In and Out keys and shifts the power to the perspective shift keys. I mean you can still move In and Out if you want, but you can’t really see if it’s safe to do or not. What you’re left with is the equivalent of playing a 3D game of Snake from a 2D perspective. Imagine you can only see the playfield from Top, Front or Side views, and the only way to see if it’s safe to move along that third axis is to shift your perspective so that extra axis is one you can see on-screen. Essentially it’s kind of like Fez, which I’ll admit I did play through a weekend or two before this whole thing happened, and may have ended up a bit of an influence on this whole thing. Amazing game by the way, go and play it. But yes, I thought this colourless way of playing kind of made it more of a “true” 4D mode, or at least true 4D for a creature that can only perceive three dimensions.

But then I realised that hey, if I can get rid of this displayed fourth dimension but still play in four dimensions… why not put it back in, and add another? So I did a quick and dirty mod of the game and created a bonus 5D mode. I think it works quiet well, I was stuck playing it for a good hour and a half before thinking that I should probably go to bed. That was kind of a common theme of this whole project actually, so much of the time I’d just get caught up playing it instead of working on it. But that’s ok though, because it’s just, uh… testing. Right? Yeah. It’s important. Actually come to think of it, I could probably even bump it up to have even more than five dimensions, just so long as I fixed the bug of there being no pause during perspective shifts where nothing on the screen physically moves. You’d just have to move through more perspective shifts to make sure you’re in line with the target. It’d make things harder and a little more tedious (and mightn’t be as fun), but I think it should be doable. Guess I’ll have to test it out.

So what next? Well I’d really like to flesh it out into more of a complete game. Give it some actual menus and options instead of hard-coded settings, throw in some different control schemes and see what people prefer to use. Actually one thing that did come to mind in development was depth perception. I think this was before I had the axis indicators for the snake’s head, or maybe just when I had the apples appearing and I was trying to line up with these floating targets. I mean I’ve gotten pretty good at judging where they are with how much I’ve played now, but I did get wondering whether rendering in stereo would help you to tell where they are. Then I thought to myself that I could try and add in the Oculus Rift stuff I’d been working on for my research project, both for the stereoscopy but also thinking that by adding in head tracking, you’d be able to look around the cube and get a better sense of where everything was in 3D space. That’s definitely something else I’d like to test out, and would have if I hadn’t completely forgotten how I modified the framework’s camera to work with the Rift in that project. I was more concerned with just getting the Snake stuff working than wasting time on trying to get the Rift stuff to work too.

Download:
This is a zip of the game as it stands right now. It includes an image that attempts to explain the control scheme, three exe files (regular, hard mode and 5D mode) and the freeimage dll which was tied up into our framework and I didn’t get around to removing. It was coded in C++ using glfw, maybe somewhere around 500 lines long.
4D Snake

Leave a comment