My interactive presentation on digital signal processing (previous post with video) is now available on the web, at visual-dsp.switchb.org! More details, source code, etc. at the site.

(P.S. I'll also be at the next meetup, which is tomorrow, January 21, but I don’t have another talk planned. (Why yes, I did procrastinate getting this site set up until a convenient semi-deadline.))

I have really failed to get around to blogging what I've been doing lately, which is all software-defined radio. Let's start fixing that, in reverse order.

Yesterday, I went to a Bay Area SDR meetup, “Cyberspectrum” organized by Balint Seeber and gave a presentation of visual representations of digital signals and DSP operations. It was very well received. This video is a recording of the entire event, with my talk starting at 12:30.

(I could say some meta-commentary about how I haven't been blogging much and I've made a resolution to get back to it and it'll be good for me and so on, but I think I've done that too many times already, so let's get right to the actual thing...)

When I wrote Cubes (a browser-based “Minecraft-like”), one of the components I built was a facility for key-bindings — that is, allowing the user to choose which keys (or mouse buttons, or gamepad buttons) to assign to which functions (move left, fly up, place block, etc.) and then generically handling calling the right functions when the event occurs.

Now, I want to use that in some other programs. But in order for it to exist as a separate library, it needs a name. I have failed to think of any good ones for months. Suggestions wanted.

Preferably, the name should hint at that it supports the gamepad API as well as keyboard and mouse. It should not end in “.js” because cliche. Also for reference, the other library that arose out of Cubes development I named Measviz (which I chose as a portmanteau and for having almost zero existing usage according to web searches).

(The working draft name is web-input-mapper, which is fairly descriptive but also thoroughly clunky.)

My GLToyJS project now has a live instance so you can play with it without setting up your own server. Caveats: • I don't promise it will remain at this URL or that the parameter format won't change. • There is an automatic 5-minute-interval change to a new random effect which cannot be disabled (but you can undo it by going back). • It doesn't tell you if your browser doesn't have WebGL, it just stops (gray screen).

Started a new project, GLToyJS; I’m porting my GLToy to WebGL. The advantage, besides using a higher-level language and modern OpenGL (shaders!), is that it is more cross-platform, rather than being a Mac-only screensaver. The disadvantage is that it’s not a screensaver at all, but a web page; I plan to add a wrapper to fix that, and I have a working proof of concept.

So far I’ve put together the core framework and ported 6 of the original 13 effects (most of the in-my-current-opinion good ones, of course). An additional feature is that an effect’s parameters are described in JSON, which will be used to allow you to save a particularly good random result for future viewing. (I could just put them in the URL, in fact — I think I’ll try that next.)

I haven't yet created any new effects, so nothing takes obvious advantage of the additional capabilities provided by shaders (other than refinements such as Phong-rather-than-Gouraud lighting and GPU-side particle systems). I also wrote a sketchy compatibility layer for the GLSL Sandbox’s interface so that you can drop in a fragment shader from there to make an effect; a possible thing to do would be automatically downloading from their gallery (if politeness and copyright law permits).

It's not published as a web page anywhere yet, but it should be and I’ll let you know as soon as it is.

An early stage in the development of lighting in Cubes (long since past).

Cubes update

Friday, March 9th, 2012 21:46

Some new features in Cubes:

  • An automated test suite. It’s hardly complete coverage, but at least it exists and so can grow. (I ended up going with Jasmine for in-browser testing. I’m not a big fan of the Englishy syntax, but it does the job reasonably well and has niceties like rerunning individual tests and adequate support for asynchronous tests.)
  • Precise collision against rotated blocks: you can now walk up the slope of those funky pyramid blocks, and so on. Stairs, anyone?
  • Performance monitoring widget with fancy graphs. (If you click the “[-]” to hide it, then it won’t waste CPU time updating itself, either.)

[I was asked about Cubes “Where do you think you might take the game play next?” and it turned into this.]

My original motivation for creating Cubes was a combination of the “blocks out of blocks” idea — which itself came from immersion in the graphics of Minecraft — and also dissatisfaction with certain bugs, limitations, and design choices in Minecraft. As a result, I’m not just building a voxel game; I’m building a game that shares what I like about Minecraft.

(What I like about Minecraft, broadly, is survival and engineering — I like building structures and machines to make my virtual life easier.)

Now, creating a Minecraft clone would be lame, rude, closer to using someone else’s intellectual property, and just plain unoriginal. But I don’t have experience with what little exists of a genre of voxel building games to synthesize my own thing, and I myself am looking for something like Minecraft. What can I do? Here’s what I’ve been trying:

  • Be different.

    Whenever I see an opportunity to do something specifically unlike Minecraft, that doesn’t compromise what I’m trying to do, I take it and see what happens. However, most of these experiments have failed; for example, Cubes originally had a larger-scaled player character, but this turned out bad because it means tunneling and building is 8× more tedious, and it reduces the apparent size of the world. Also, it leads to thinking “OK, add this feature Minecraft has — but (superficially) differently!”

  • Be generic.

    This is my long-term goal, and it is one that ties neatly into the “blocks made of blocks” theme. The characteristics of blocks can be defined by building circuits (programs) inside them. What I’m aiming for is that by creating a blockset (collection of block designs which the player can build with), one is defining the game that can be played, by giving those blocks specific behaviors.

    In this way, I am working towards having a game which can be programmed to emulate Minecraft.

    (I have a working prototype of an importer for Minecraft worlds as well as for Minecraft blocks — that is, turning the terrain.png from a Minecraft texture pack into Cubes' 3D blocks — but I am not going to release that code until and unless I determine that Mojang doesn’t mind my doing so. I still love Minecraft and they deserve my not stepping on their toes that far.)

    However, this means both that Cubes itself needs to be very generic, and that the built-in example uses of such features should feel different from Minecraft.


So, returning to the original topic of “where am I going next”, I need to add the following functionality to the game world:

  • Extend the circuits feature so that there can be blocks that are active and interactive (e.g. opening and closing doors, “physics” like Minecraft falling sand and growing plants).

  • Add moving objects (for vehicles and mobs). I intend to generalize these so that they are worlds in themselves — this will allow large or unique vehicles, and mean that they can be designed using the same game tools.

  • Add some form of resource constraints/conservation laws (as in Minecraft survival mode) — that is, you have to gather stuff to make it into other stuff. I haven’t figured out specifically how I want to do this yet, and this seems particularly tricky to make programmable. One idea that keeps coming to mind is that when you break a block, specific subcubes are “resource cubes” (according to their type in the block world) which you collect, and in order to place a block you need to have the corresponding resources for its type. However, I’m not sure I like the “raw material counter” feel of this.

  • Add player attributes that can be modified (e.g. health) so that e.g. death, or other effects-by-the-world can be supported.

Less grandly, I plan to work on one of these specific technical features soon:

  • Allowing circuit blocks to be rotated to change their connectivity. (Right now, circuit blocks have specific faces — e.g. on a certain one the +X direction is always the output.)
  • Figure out what more circuit primitives I want to add. (Right now, the circuits are definitely not Turing-complete, and not capable of all the effects on the world they should be, but there are also already a lot of different primitives; I may have to invent new block-picking UI just to make them practical.)
  • Add moving objects (bodies) — things which can collide with the terrain as the player does. The current code is entangled with player behavior, and the player does not persist in a world.
  • Add subworld/multiple-world handling — the ability for more than one world (grid of blocks) to be present in the same space. Right now, there are hardwired assumptions that the player is in the single world’s coordinate system.

Another core feature which is currently missing is the ability to design a blockset and then reuse it for multiple worlds. The problem right now is that we're using a simple object-graph serializer, so each world has its own blockset which is modified independently. To fix this, it needs to be possible to save a blockset under a user-visible name, and have individual worlds which reference that blockset; also, the world generator needs to decouple blockset generation from terrain generation. The “persistence” framework which added support for multiple worlds is a step towards this; the main thing I am pondering is what the semantics of these separate-named-persistent objects are and what the user interface for editing them is.

Based on the feedback I’ve received, I conclude that the white-screen/crash problem with Cubes is hardware/driver-specific and not very widespread. Since

  • this is a hobby project and an experiment, not a Game to be Published,
  • the problem looks hard to debug,
  • I don't have a variety of machines to test on, and
  • I replaced the MacBook Pro in question with a newer model which does not exhibit the same problem,

I have decided not to debug it further at this time. I've added a note about the problem to the documentation, and I’ll instead work on the problems Cubes exhibits on the new machine :-) (such as a speckling of not-the-right-texture-tile at the edges of blocks, and a strange input lag) or adding new features, like more useful saving/persistence, sub-block collision detection, or subworlds.

I upgraded to Mac OS X 10.7 Lion this month, and ever since then Cubes has crashed or otherwise misbehaved on my machine. However, I have only the one to test on, so I would like your help in figuring out what the extent of the incompatibility is — whether this is a GPU driver bug or something Cubes is doing wrong.

If you have a WebGL-capable browser (such as Chrome or Firefox) and GPU, and especially if you're running Lion or are otherwise similar to my configuration, please run Cubes (no installation is required) and tell me whether it works and what your system configuration is, including these properties:

PropertyI have
Hardware modelMacBookPro5,1
GPU modelNVIDIA GeForce 9600M GT
OS versionMac OS X 10.7.2
GPU driver version?
Browser versionChrome 17.0.963.12, Firefox 8.0

(For some MacBook Pro models such as mine, the GPU used (9600M or 9600M GT) depends on the “Graphics” setting in Energy Saver preferences.)

The problems I observe are:

  • All blocks (terrain) being flat white except for lighting; the sky and particle effects still have color. (For the interested, this appears to be a mis-execution of the over-unity-to-white code introduced in commit 48674f….)
  • After some amount of usage, a crash (in Firefox, the browser exits; in Chrome, the display goes gray and the Web Inspector console says “WARNING: WebGL content on the page might have caused the graphics card to reset” while the in-page text says “Previous GL errors: INVALID_OPERATION”).

I will appreciate any help as this is making it quite impractical to work on Cubes.

I need to stash this info somewhere; might as well be well-indexed.

Stereo photos such as those taken by the Nintendo 3DS, with a .MPO file extension, are actually JPEG right-eye images with the left-eye image embedded as extra data. They can be interpreted as JPEG files (perhaps after changing the extension to convince your software to read them), and the left-eye image can be extracted with exiftool, as follows:

exiftool input.mpo -mpimage2 -b > L.jpg

A standalone right-eye image without the extra data can be produced with

exiftool -trailer:all= input.mpo -o R.jpg

Source, via.

These may be three different things:

  • The answer to the question you asked
  • The solution to the problem implied by the question you asked
  • The solution to the problem you actually have

I was reminded of this yesterday when, noticing that my code for Cubes was using an arbitrary constant for the near clip plane, I asked how to calculate it in a principled way.

On September 6, I had an idea which I couldn't not work on. (Unfortunately, it wasn't an idea for either of my course projects this semester.)

As you may know, in Minecraft, the individual cubical blocks are textured with unsmoothed 16×16 pixel textures. All blocks’ shapes (that aren't just cubes) have lengths in multiples of 1⁄16 block (example, so that the objects have (to some degree) the appearance of being made out of voxels, or smaller cubes. And, people have built giant versions of specific blocks out of colored blocks.

So, what if building blocks out of blocks was actually how the block types were defined?

And that's what I've implemented, in JavaScript/WebGL. The working project name is “Cubes”, because I don't know where it's going enough to give it a better name right now.

The block types you see above were all procedurally generated as placeholders, since I don't have any save/load facility to save manually edited blocks (and I'm not sure about the color scheme of the current set of blocks-you-make-blocks-out-of).

Play (requires WebGL-capable browser; I recommend Chrome).

Source code.

Controls: Standard WASD keys, or arrow keys, and mouselook. The left button adds or removes blocks at the location of the white rectangle cursor; the right button brings up a menu for choosing blocks (the empty square at the top left is the removal tool). The R key enters the world of the selected block; the F key exits.

Update 2011-09-13: I've improved startup; it now tells you more explicitly what went wrong if it fails to load, rather than a blank white screen. I've also added an in-game Help button with controls and browser compatibility info.

The Witness

Sunday, August 14th, 2011 07:54

So, this is potentially interesting. The developer of the game Braid has started a new project, The Witness. It’s apparently going to be 3D, set on an island, and involve solving puzzles scattered around the island (while being able to move freely around it). Their blog is talking a lot about their graphics engine design as opposed to the gameplay — naturally, as graphics tech is more usefully shareable and isn't inherently spoilerish.

What particularly caught my eye as “I agree with this” was their post Experiments in Texturing. Good textures are hard; it's often easier to make a good, clean model than it is to make a texture that is not jarringly unrealistic. The Witness is putting a lot of emphasis on lighting: “We’re on a low budget here, being an indie game; so not only was it an open question how to solve the Ugly Texturing problem, but we also needed to solve it with relatively little manpower. I knew that, ultimately, we could just fall back on untextured geometry with lighting, if we had good precomputed lighting.” They go on to describe using textures as accents, to add texture rather than defining significant features of the object.

As a Minecraft player (structures are built of pre-textured blocks) and former Avara map designer (graphics engine does not support textures), I entirely approve of this approach.

I have updated the Minecraft topic at my web site, bringing it up to date with changes, adding many new links, and information about my new world. Also, I didn't previously announce this:

I am running a Minecraft server. I've been running one for a while, but it had a rocky start trying to run on a shared Linode. It now has a dedicated machine (though one which is rather old and running on a home cable connection) and is running 24/7.

The address is: mc.switchb.org

This server runs a copy of my single-player world, updated each day, so changes you make are not persistent (except for your inventory). This is a place to tour, or use for building experiments, not to live in. However, I have attempted to make it suitable for multiplayer use, with direction and instruction signs and multiplayer-capable rail stations (though most of the rail tunnels are single-track).

Feel free to suggest improvements to the facilities, or additional builds.

(Home sweet home.) (Cactus and flower farming.) (Mob tower and access routes.) (Rail hub station.)

(Note for those who have tried the server before: I recently fixed a problem causing new players to spawn nowhere in particular rather than at the spawn station.)

GraphLife

Tuesday, August 28th, 2007 17:50

This is a somewhat odd cellular automaton implementation in Haskell. It encodes the shape of the world, and the stepping rule, in the data structure. Briefly:

data Cell v n = Cell {
  value     :: v,
  neighbors :: n (Cell v n),
  future    :: Cell v n }

-- Build a cell and its chain of futures, given its rule, similar neighbors,
-- and initial value.
mkCell :: Functor n => (v -> n v -> v) -> v -> n (Cell v n) -> Cell v n
mkCell rule val nei = initial
  where initial = Cell val nei (calcFuture initial)
        calcFuture c = c'
          where c' = Cell (rule (value c) (fmap value (neighbors c)))
                          (fmap future (neighbors c))
                          (calcFuture c')

data Moore c = Moore c c c c c c c c

-- Conway's Life
evalLife :: Bool -> Moore Bool -> Bool
evalLife v n = f v (sumN fromEnum n)
  where f _    3 = True
        f True 2 = True
        f _    _ = False

The remainder of the code is routines for setting up worlds and displaying them.