A half-arsed idea for a computer game
September 30, 2012
For a while now I’ve been thinking about computer game worlds. Although my schedule is overflowing with things I ought to be doing, I’m unfortunately the kind of person who cannot properly work until a competing train-of-thought has been dealt with. Hopefully writing this post will put my mind at ease long enough for me to focus on writing an article for AD magazine, recording and editing my acceptance speech for the Acadia 2012 award for innovative research, finishing the new RhinoScript compiler for Rhino5 and trying to go hiking a few more times before winter truly arrives.
Aaanyway… computer games. I used to play a lot on my father’s Acorn computer. Think early 1990’s. Mad Professor Mariarti, Starfighter 3000, Spheres of Chaos, Lander, Tower of Babel, Lemmings, Super Foul Egg, Nebulus, Cataclysm …. the list goes on. Good times. Then nothing much until I got an XBox console about 2 years ago, but even there I log maybe 4~5 hours a week. Maybe.
The Lander game on Acorn Risc Os.
It is quite shocking how much the graphics and physics of games have advanced in this time-period, but equally shocking how little progress has been made with regards to fun. But that’s a story for another blog-post. Increases in storage, memory and processing over the past 20 years have allowed game developers to create humongous worlds for games to be acted out in but as far as I know most —if not all— commercial games have hand-crafted worlds which puts a limitation other than hardware on the size of a game; namely the amount of work needed to design and draw the geometry involved.
I’m reasonably familiar with the worlds of Red Dead Redemption and Just Cause 2. Although both are very big by my old-fashioned standards, they aren’t nearly big enough to truly give a feeling of boundlessness. If you spur on your horse you can ride across the entire RDR world in 5~10 minutes. And although the world in JC2 is much bigger, it’s extremely repetitive and therefore travelling loses its meaning. Although I am sure that the world-builders use/write algorithms to automate tasks (such as placing plants or rocks), it seems that these algorithms are not used to generate data during game play.
For a long time now there have been landscape generators available and some of them appear rather impressive, however it seems most of them are mere proof-of-concepts that fall well short of actually generating enough data to challenge the quality of hand-crafted worlds. I acknowledge it is very difficult to generate terrain, vegetation, plant-life, roads, settlements and all the other things needed for a full blown open-world game. But let us assume this nut has been cracked and that we can generate an endless amount of unique landscape based on a finite collection of settings. Let us call these settings the Terrain-tensor (τ). It may contain properties to do with soil, vegetation, roughness or a myriad of other characteristics. How would we apply such a terrain generator? It will most likely be quite computationally expensive to generate large terrains to the level of detail we’ve come to expect. Although far-away parts of the world need only be generated in low-poly approximations, it still seems like an uncomfortable sacrifice to spend cycles on generating a large world if that results in a marked decline in visual quality.
Another problem with generating a large ‘flat’ world is that you can often see a long way. The world is there, you can see it, you can ride around in it as far as you want. In such a case, the only benefit to having a world-generator would be to remove the boundaries of the map and although the game may now well be infinite, you can only travel so far so fast, and you can therefore only encounter new environments at a fairly limited rate.
But what if you cannot see very far? In that case the world generator would not be constrained much by what it is already showing you. It could adapt the τ and generate an environment that is actually controlled (in part or in whole) by the actions of the player. Fog or darkness would be one way of limiting the information given to the player, but I was thinking of something a bit more interesting:
We’re all very familiar with what it feels like to be on a spherical world. It’s just that our real world is so big that for all intents and purposes it might as well be flat. The radius of the Earth is roughly 6000 kilometers meaning that for every kilometer we travel in a straight line the surface of the Earth drops about 5 centimeters due to Earth’s curvature. Typical landscape on Earth has a larger curvature. What if we shrink the size of the world? What would it feel like to be on a globe with a radius of 10km, 1km, 100m, 10m? There are two interesting visual distances associated with a spherical world; the distance to the horizon (dH) and the distance to the furthest visible object behind the horizon (dF). The former distance represents the area completely visible to the player; the local world. The latter distance represents the area that is fixed at any given time; the global world. Anything beyond dF though must be generated when the player moves in that direction and of course the τ for this newly generated piece of landscape is up for grabs.
There are three numbers that define dH and dF; the radius of the world (r), the height of the largest object (h) in the world and the elevation of the camera (e). Let us write down some equations that describe the relationships between these numbers, all the while assuming a perfect spherical planet.
dH = squareroot((r+e)2 – r2)
α = arccosine(r/(r+e))
dHw = 4π2r/α
AH = 4πr2 sine2(α/2)
dF = dH + squareroot((r+h)2 – r2)
β = α + arccosine(r/(r+h))
dFw = 4π2r/β
where:
dH = the distance from the camera to the horizon.
α = the angle between the camera and the horizon as measured from the planet centre point.
dHw = the distance along the planet surface from the camera to the horizon.
AH = the surface area of the visible ground (everything inside of the horizon).
dF = the distance from the camera to the tip of the furthest visible objects.
β = the angle between the camera and the furthest visible objects as measured from the planet centre point.
dFw = the distance along the planet surface from the camera to the furthest visible objects.
The whole point of using a spherical world is that it limits how much of it you can see at any given time. However this characteristic dissipates as the world radius grows larger. However a very small world is problematic too as the objects on it will be relatively large and thus there will be very little ‘undefined’ area left over. Also, a small world does not allow for big terrain. You cannot grow a 30 meter cliff face on a planet with a radius of 20 meters without it looking very silly indeed.
So let’s say we have a world with a radius of 50 meters and the camera is 4 meters above the ground, which is a fairly typical elevation for a third person game. We’ll populate our world with trees and buildings, but no massive landscape features, so we’ll limit the highest objects to 15 meters.
These values put the horizon roughly 20m away and the furthest visible objects roughly over 60m. The total world area is a little over 30,000m2, of which a bit less than 1200m2 is visible, which is roughly one thirtieth. The length of the horizon is about 120m and the length of the defined world boundary is nearly 300m. So let’s say we walk 60 steps in a random direction. This will put us at the old world boundary. Half of what we see now we’ve seen before, the other half has been generated while we walked. There was no constraint to the τ (the terrain-tensor) for this newly generated landscape, though we do want it to conform somewhat to the landscapes it borders on.
Since we’re moving along the surface of a sphere, our landscape is two-dimensional. This means we can draw a two-dimensional tensor field where certain coordinates for a fixed τ. Between these coordinates terrain tensors can be interpolated:
Now if we move along our surface world, we can use this tensor-field to determine what new landscapes to generate at the boundary. But even more interestingly, we can generate a new tensor field based on the game play history. For example, imagine we’re standing in the middle of a field and we walk in a straight line due North. After 60 steps we’ve reached the old boundary of the world (i.e. where the boundary was before we started walking) and before us we see a giant swamp. Now we walk 60 meters due South until we’re back where we started. The swamp has disappeared beyond the visible boundary and we’re back in the field. Now we walk 60 steps in the NNE direction, very similar but not identical to the earlier path taken. Now, instead of a swamp, we’re greeted by a thick forest, even though we’re only ~15m away from the point where we turned around not so long ago. This should not be possible, but because we can generate brand new landscapes along the visual boundary, our spherical world in fact behaves as though it has a large negative curvature, rather than the positive curvature we’d expect from a sphere. After all, what we’d expect from a sphere is that if you walk in a straight line, no matter what direction you walk in, eventually you’ll always end up in the same spot, i.e. directly opposite the point from where you started.
In practice this principle could be implemented in a number of ways. It could be that the walking direction always affects the τ along the boundary. Or it could be that only certain gateway paths result in a change in τ. Think of it as being stuck on a small constant world, and eventually walking into a completely different, but also constant world once you’ve figured out how to get there. It is even possible to change the size and topology of the world itself, growing it or shrinking it as one navigates its surface.
Like I said, a half-arsed idea. It needs a lot of work but I’m not a game developer and I hope I can stop thinking about this now. If anyone ever implements this idea —or an idea vaguely like it— I’d love to try it out.
Round 3: A rebuttal by ayg011
September 12, 2012
On April 1st this year I wrote a blog post called Programming, conflicting perspectives which was partially a response to several comments left by a user called ayg011 on the Grasshopper forum. Ayg’s original comments had an unmistakeable veneer of bitterness, even vitriol to them, but I was glad to find a thoughtful response a week ago.
Rather than taking this discussion into the comment section, I prefer to continue it as another top-level blog post, because it is an interesting and important discussion. I hope the inherent imbalance between our respective manifestations* —blog owner vs. commenter— doesn’t lead to an unfair advantage in favour of the points I am arguing.
Anyway; round 3. Ding!
“The example you have used to argue that there is no difference between GH ‘programming’ and any other language is poor as it conveniently ignores all of the key concepts programming offers which GH is unable to handle […]”
Guilty as charged. I did pick a very simple example, something devoid of both conditional statements and iteration or recursion. Grasshopper —like most node-based editors I know— is notoriously bad at control flow design. An amended example that does include a conditional statement could look like this:
public Vector3d VectorFunc(Vector3d A, Vector3d B) { A.Unitize(); B.Unitize(); if (A.Z < 0.0) A.Reverse(); return A + B; }
with the Grasshopper equivalent being this:
A number of observations can hopefully be agreed upon by all parties:
- The increase in relevant characters in the C# code is roughly 50%. I’m discounting characters which could have been omitted.
- The increase in relevant objects in the Grasshopper code is roughly 100%. Where before we used 5 components with 4 wires, now we need 10 components with 11 wires.
- The legibility of the C# code remains high.
- The legibility of the Grasshopper code suffers quite badly.
It certainly seems to support the notion that Grasshopper is a worse programming language than C#, at least in terms of efficacy, which is a very important characteristic. But is it sufficient reason to jettison Grasshopper from the realm of the ‘real’ programming languages? I’d argue that this is not a fundamental asymmetry, but rather a matter of degrees.
Take for example a language such as VBScript. It can deal with conditionals and loops and recursion quite well. Does that mean it’s on a par with C# or VB.NET? Well… no. VBScript cannot do threading, which is possible in VB.NET. If you never use threading you’ll be unmoved, but if you do it may well be a deal-breaker. So you switch to VB.NET and you find that you cannot access memory directly using pointer addresses, which makes bitmap-processing significantly slower. So you switch to C# since it has the unsafe keyword, or even to C++ which provides fine-grained control over the memory. And the regression doesn’t end here, if you need even more performance than C++ can give you you may need to switch to Assembly and so on and so forth.
To say that VB.NET is not a programming language because it can be outperformed by C++ is ridiculous. To say that VBScript is not a programming language because it can be outperformed by VB.NET is ridiculous. So would it be ridiculous to say that Grasshopper isn’t a programming language because it can be outperformed by VBScript?
Here’s a different way to make the same point. What if next week I add a mechanism which makes adding conditional statements to Grasshopper networks straightforward? Would that propel Grasshopper into a different category? I doubt it. Adding such a feature would be an incremental update, not a paradigm shift. In the meantime —and perhaps forever— Grasshopper is indeed rather lame concerning conditionals and loops.
“There is a limit, particilarly [sic] when it comes to conditional statements, loops, and efficient data structure (the list structure in GH know [sic] as ‘trees’ I find to be highly esoteric, stifling and worst of all a non-transferable skill […]”
I find this an interesting point, because it is both true and yet mostly irrelevant in my opinion. Ignoring the bit about conditionals and loops since we just talked about that, I wonder what it means to the status of a programming language that its primary data storage is inefficient, esoteric, stifling and non-transferable.
I assume the word ‘efficient’ is used to refer to memory overhead concerned with storing data in a tree, as opposed to some other mechanism**. I wonder how ayg011 knows that data trees are inefficient. What have they been compared against? And under what conditions?
Esoteric and stifling are things I do worry about myself. Languages such as VB.NET and C# have a lot of different options when it comes to data storage. Individual variables, arrays, lists, arraylists, sorted lists, linked lists, collections, synchronized collections, readonly collections, dictionaries, sorted dictionaries, hash tables, queues, stacks… the list goes on. Datatrees are an attempt to provide as flexible a mechanism as possible for the problem of storing any nesting depth of jagged array (sparsely populated if need be). I concede they are complicated and can be daunting to use and I’d love to hear some ideas about making them a bit more cuddly, but I don’t see a workable alternative that would both significantly reduce complexity while maintaining —let alone increasing— efficiency and flexibility.
Finally, I find the objection that a skill is less worthy because it is non-transferable very sketchy. I would hope that people learn Grasshopper because they want to work with Grasshopper, if anyone out there is using Grasshopper as a springboard to learning C#, why not just learn C# and be done with it?
“Once this limit is reached, conventional programming methods have to be used (c++ or python component etc), which proves there is a difference and you can’t truly call GH ‘programming’.”
Once penicillin no longer helps you may have to switch to stronger substances (Augmentin or Azithromycin etc), which proves there is a difference and you can’t truly call penicillin ‘medicine’. See? It does not follow.
“At this point, for the reasons above, I stipulate that due to the convoluted methods of creating a definition, along with the plethora of different components that will undoubtedly require a lengthly [sic] and protracted training programme for new users, that GH will forever remain a niche; the betamax of the parametric software world.”
I think all programming requires a lengthy training programme. And I suspect that there’s a disturbingly large percentage of people —not correlated with intelligence— who cannot be taught programming at all. Whose reasoning and thinking patterns do not lend themselves to translation into algorithmic operations.
Grasshopper is not for everybody. It was never intended to be for everybody. Robert McNeel & Associates feel the computational architecture/parametric software world is big enough to warrant continued development, even for a niche product. I do not know how long this state of affairs will last. Perhaps computational design is really a fad after all and people will lose interest in 2 years. Perhaps the Grasshopper user base will dwindle due to a blossoming of competing products, within or without Rhino. Perhaps students will start learning C# en masse and be frustrated with the lack of flow control that Grasshopper provides.
* Christ I miss the time when one could use the word “avatar” without sounding like a 14 year old boy. Now I’m stuck with “manifestation” or “reincarnation”.
** If I’m wrong about this, please correct me.
*** I hope anyway, it would be a sad world where Grasshopper is forced on people.
Physical Interface Design
September 1, 2012
I don’t cook every day. But when I do, I enjoy it and I especially like to make oven-dishes (they give me time to clean up and wind down while the stuff is simmering away in the oven). Today I made two small one-person chicken-leek pies and several things struck me about my oven that one would categorize under GUI flaws were my oven to be software. I’ve noticed these things about most ovens/stoves I’ve ever owned so it seems to be pretty systemic.
- Why is the light inside the oven exactly the kind of colour that makes everything look done? Why doesn’t it have a —say— daylight spectrum so my food actually looks like its supposed to look?
- Why is there only one light inside the oven? It’s very easy to cast shadows onto food if you use more than one level now.
- Why is the glass front covered in a fine grid of black dots? If I want to see inside my oven I have to move my head like a chicken on crack just to stop my eyes from auto-focusing on the pattern.
- The metal grid that covers the gas-burners is made up of two pieces. They too big to fit into the sink so I have to wash them in the shower. Why couldn’t they have made it four pieces?
- Why are there so many narrow creases near the bit where grease tends to spatter?
- Why do the gas-burners whistle at certain settings?
- Why is the smallest burner on the lowest setting still too strong to let creamy sauces simmer?
While living in Toulouse and Turku I’ve had electric stoves which are typically not plagued by 4, 6 & 7. I could never get used to electric stoves though, just not responsive enough.