Home

Welcome! This is the public, open development site for The Nut, a game about building things (every things) being developed by one person, me. I'm doing this because there doesn't seem to be a lot of information around about this process and its many issues.

Nocturne

posted 1 Dec 2013, 13:48 by Burton Radons   [ updated 1 Dec 2013, 14:23 ]

Woops! I never meant to take such a significant break. The Nut got foundered in some difficult problems, and I went off and did a bunch of other stuff for a few years.

I decided to go with a simpler, more readily achievable game, and it came to me in kind of a flash. I can't remember why, but I was thinking of an extraordinary scene in My Neighbour Totoro, a Japanese film by Hayao Miyazaki. The focus of the film is on these two tiny little girls, I think around five and three, that have just moved into the country with their father. It follows them naturalistically, allowing us to learn more about them simply by what they encounter and how they behave, which is remarkably true to children of their age. The twist is that they're neighbours to a forest spirit, a great big bear monster called Totoro, that they befriend. Well, they plant a bunch of nuts and seeds Totoro gives them in their garden, and one night he brings them out to make them grow. What follows is startling, awe-inspiring, and almost religiously intense. Unfortunately I could only find it with the English dub, which plays down some of the sounds and voices.

My Neighbour Totoro - Growing Seeds


So why not make a game out of that? A game where you sing and roar and clap and the world changes around you? That's the basic idea of Nocturne. I don't plan to make a story out of it, just give you a sandbox where you're a disconnected voice who can manipulate your environment by making noises into a microphone, sometimes guided by other voices who teach you new songs to create plants and change the world around you.

This presents a pretty linear set of pieces that need to be developed to make it into a game. They are:

  1. Engine. I've decided to make an OpenGL 4.3 engine based off of OpenTK, absolutely top of the line. While my rendering needs are somewhat lower than some games, I still need to render an enormous number of leaves and grasses, and for that I need far more than what XNA can give me. XBLIG is dead anyway (an important data point is that Solar 2 sold more on Steam in a week than it sold in a year on XBLIG, and I think a huge part of that was that Microsoft doesn't promote their indie lineup at all, and I expect that to only get worse). This will continuously get developed as the project goes on.
  2. Wind. Since your voice is the way you affect the environment, it's vital that anything you say has a response within it. To be effective, this requires liquid simulation for complex wind behaviour. There also need to be carriers on the wind like pollen and seeds that colour the sounds you make, telling you how the game is interpreting you so that you can be trained to performing the right noises to achieve the desired action.
  3. Terrain. In most cases, I don't think you should be able to see the ground. I think that ground cover should almost always be so thick (but not necessarily tall) that it's impossible to see it, and the camera angle might be constrained so that you don't see the grass blades poking out of plain green textures. But I do think it's necessary to see the ground in cases like sand, and I do want terraforming. So while the terrain might not be visible, it should still be there. I can port over a nice dynamic terrain library I'd written in XNA for this, so it's not a big problem.
  4. Grass. Grass is vital to telling you about the wind, and therefore your voice (perhaps I'll follow From Dust and capitalise that as the Voice rather than the Breath to give you a bit of an avatar). I believe that geometry shaders should be good at producing random and thick blades of grass over the surface of the terrain.
  5. Plants. Plant generation is easy and well-known. The difficulty here is in putting it completely under your control, letting you grow the plant as you desire by singing to it.
  6. Plant dynamics. Plants should interact with each other and the soil they're in. This creates a bit of a game element and forces some more variability in a player's garden.
  7. Vocalisation. This is by far the hardest and trickiest part. The fact is, I'm going to need to fake a lot of it, using pitch and volume and combos to interpret meaning rather than understanding words. In a way, that's good, since it allows the player to improvise their singing. But it can be frustrating if you think you're plainly singing one thing and the game interprets it as something else entirely. I'll try to make the experience as consequence-free and smooth as I can to reduce frustration as much as I can.
  8. Guidance. The player needs to be able to learn new songs and have some idea of what they could be doing to have some sort of effect. I do want to make this as minimalistic and natural as I can, but the priority absolutely is in the player being able to know how things work as straightforwardly as possible. So if subtlety doesn't work, go straight to clear and plain text that tells you what to do.
  9. Testing. It's impossible to test your own game; you just won't think of all the stupid things that testers will try. Testers also introduce hardware variety that gives a small taste of the chaos that release brings.
  10. Art. I need a visual artist and a musician. This is not something I'm much worried about now; getting the mechanics right is most important.
  11. Effects. The game should look pretty, so shadows and ambient occlusion and water reflections and water caustics and caustic reflections and a bunch of other junk needs to be put in place, eventually.
  12. Presentation. I intend to go on Steam, so the final game needs to have their stuff integrated in, and they might have various requirements that I'll need to meet.
  13. Release. Release is always followed by bug patching, because on the PC you have so few guarantees about hardware and software. This will result in at least a few weeks of 20-hour days of coding.
  14. Workshop. I'd like players to be able to add to the game. If possible, I'd like that to be organically integrated into the game itself, Spore-style. I'll keep this in mind as I develop, but I won't touch it until after release.
I'm currently at 2, looking through fluid simulation papers and adapting them to shaders.

24-bit Dithering

posted 8 Sep 2011, 12:45 by Burton Radons   [ updated 8 Sep 2011, 13:34 ]

A widely-held misconception is that 24-bit colour (16.7 million colors) is enough to make gradients imperceptible to the human eye. This may be correct if your gradients are red, green, and blue. But any more complex gradient, or any compositing of gradients, will very quickly become visible and annoy the hell out of anyone who can see it.

Correcting for this in computer graphics is kind of stupid easy. Take a texture, fill it with random values. When you are about to return the color from the shader, do this:

float4 output;
...
output.xyz += (tex2D(RandomSampler, ScreenPosition.xy * Scale).xyz * 0.5) / 256;
return output;

Where "Scale" is some factor that splats the texture evenly over the entire screen. This randomly pushes components up or down half a 24-bit RGB boundary, so that when it's subsequently rounded, it acts as a dither. Here's an example of the result:


The banding on the green is harder to see (as it's one of the primary RGB colors, and so is closer to the ideal) but it's certainly there; these are both very close to ideal conditions for gradients that minimise the error, and to me they're plainly visible. Normally you'd need to do all sorts of fancy tricks to hide patterns in the dither or to avoid a weird feeling when the camera moves that the screen is covered in dust. But because this is so subtle, you don't need to do anything else. One step does it all. Five minutes to implement.

(Yes I'm working on The Nut, I just saw a post on The Witness blog I wanted to comment on.)

Voxels on my brain

posted 7 Sep 2011, 09:53 by Burton Radons   [ updated 7 Sep 2011, 10:01 ]

Whoops! Got involved in a weekend project that became a weekday project; a voxel engine.


There's some pretty sweet tech behind this, but my favourite point is when I got it to this stage:


Yes, making it look worse is a huge improvement. Because the earlier one took the voxels and transformed them into triangles. The latter renders the voxels directly using raytracing. It took no time at all to do, and is actually so fast (on both the PC and the XBox) that it looks completely viable as the rendering method of choice. But it IS a weekend project, and it doesn't have a purpose, so I'm setting it aside now and getting back to The Nut. I'll still plug away at it on weekends, but that's it.

Generic Constraints

posted 26 Aug 2011, 22:48 by Burton Radons

No screenshot today since my circuit simulating code is doing little more than pumping out some matrices, but as I was working on the matrix library I thought I'd talk a bit about .NET generics.

Before this year, from late 2001 my language of preference was D. D's templating system is close to C++'s, in that it's little more than a macro system. Most importantly, it's not type safe; it's never possible to prove that it's correct, and instantiating it in the wrong way can easily break the code (this is the primary source of C++'s dreaded spagghetti template errors). One interesting power, though, is static if blocks, where you can optionally insert code based upon certain specific conditions:

struct Vector(T, int D) {
    static if(D == 3) T CrossProduct(Vector other) { ... }
};

It's a powerful mechanism, but it makes maintaining the code confusing because it's harder to read and it makes documenting the code very difficult. A more structured mechanism could handle the most effective and important uses of this while making it clearer to the reader what's happening.

One way to partially do that is how .NET does it, by using constraints:

struct Foo<T> where T : IEquatable<T> ...

The only way you can use a type parameter is by the constraints you've defined; so I can't just use "T a = ..., b; a += b;" and hope that the user supplies a type that can handle arithmetic. This means that the generic constructs are proven, and you know they'll work with any valid input. Good stuff.

When you do something like this, it behooves oneself to have a rich and consistently applied interface set so that the constraint system can be used effectively. You also want to use methods to implement operations on your objects rather than something silly like Java's Math static function library class, which would be useless to generics. Guess what? .NET has only IComparable and IEquatable as effective constraint supplements, and it has a dumb Math static function library class. The constraint system remains useful, but its uses are very specific, and not nearly as important as the uses it has locked out.

The upshot is that I would like to have something like:

class Matrix<T> where T : INumeric, IArithmetic, IFractional...

Which would then allow me to cast from numbers, perform addition, and be assured that division won't be unduly rounded. I have none of that, and implementing something like this requires tricks.

For the matrix library, what I'm doing is deriving from an Implementation class I've defined that has some common functionality - it has a static dictionary of implementations by type, a function to return one or a dummy implementation, and some other folderal. The implementations have a set of methods that take and return objects, and in their bodies will perform the desired operation in a type-specific form. In the types themselves, I perform common checks, then grab an implementation and execute it like so:

static MatrixImplementation Implementation { get { return MatrixImplementation.Find(typeof(T)); } }

public Matrix<T> Multiply(Matrix<T> other) {
    if(other == null)
        throw new ArgumentNullException("other");
    if(other.Rows != Columns)
        throw new ArgumentException("other.Rows must equal this.Columns for matrix multiplication.");
    return (Matrix<T>)Implementation.Multiply(this, other);
}


This is a bad hack - it necessitates code duplication with all its sundry problems and it makes understanding the code more difficult - but it's what's necessary. It's a shame that .NET is still so crippled by its earlier version limitations and underconceptualization.

One workaround I would like to see is declarative interfaces - that is to say, I claim that this type implements this interface, and if this actually is true, then I can cast an object of this type to this interface even though it wasn't declared to be a member of it. But OO languages are not very good about understanding that library implementors often forget important things that have enormous consequences to their users, who are the ones the language should be serving first as 95% of the code will be written by library users, not implementors. Alas, language design is still treated as an art rather than an engineering problem where you can absolutely declare that one way to do things is better than another.

Octopus Taming

posted 25 Aug 2011, 14:24 by Burton Radons

Here we go (and here I realise Google reencodes pictures after uploading them). Better curves, better tangents, little exposed wire ends. I'll revisit this code much later to optimise the interpolation and give more variety to the attachment points, but it's mostly done for now. Now to make those wires actually mean something by starting in on Electronic Circuit & System Simulation Methods. The book, that is, not the movie adaptation.

Benefits of anti-swimming with shadowmaps

posted 24 Aug 2011, 17:52 by Burton Radons

I wanted to get a YouTube! account working along with the movie-posting workflow, so I made a quick video showing the importance of anti-swimming your shadow maps:

The core problem is that you need to move your shadow projector with the viewpoint in any complex or large environment, but if you don't anti-swim you're going to cause aliasing artefacts aplenty. The solution is simply to round the target offset in shadow space, as with this pseudo-code:

Texture ShadowTexture;
Matrix BaseShadowMatrix = LookAtMatrix(from: -LightDirection * 100, at: Origin, up: UnitY) * OrthographicMatrix(...);
Vector3 ViewTarget = ...; // A point in front of the viewpoint camera.
Vector3 ShadowTarget = BaseShadowMatrix * ViewTarget;

ShadowTarget.XY = Round(ShadowTarget.XY / ShadowTexture.Size) * ShadowTexture.Size;
Matrix ShadowMatrix = BaseShadowMatrix * TranslationMatrix(ShadowTarget);

Simple!

Electric Octopus

posted 24 Aug 2011, 17:52 by Burton Radons   [ updated 25 Aug 2011, 00:37 ]

The tangents are the worst, but getting that right is a fiddly process. A Flash prototype I made several years ago used anchor points that I could direct to face away from the component as appropriate; it then chose tangents by extrapolating those to a distance appropriate to the length. I should use something like that. The good news is that this code is oddly very fast and can update the wires smoothly.

Welcome!

posted 23 Aug 2011, 20:33 by Burton Radons

Hello there, and welcome to the website. I just thought I'd put up a screenshot to show that there actually is a program being discussed here:


I've mostly been working on the rendering engine and menu system. It's very simple, with elements that are easy to peel off as needed. So I could make the background a pre-blurred cube map, not blur the reflection, and remove shadows. On the components side they're all built in 3DS using shapes that can be triangulated at lower detail or replaced with simpler approximations, like switching out a cone with a texture map for the coils. The LED digit thingy uses a baked ambient occlusion map process I'm working out that allows the entire thing (aside from coils) to be drawn with a single rendering call, so simplifying that further would be difficult.

The simplistic background is also intended to bring attention to what you build rather than getting the eyes or attention lost in pretty sparkly lights and spinning things going WHEEEEEEEER and a clown bouncing in front of the screen. That was my first idea, but this is much easier to build.

1-8 of 8