I woke up last night with a great feature idea which on further examination was totally inapplicable to All is Cubes in its current state. (I was for some dream-ish reason imagining top-down tile- and turn-based movement, and had the idea to change the cursor depending on whether a click was a normal move or an only-allowed-because-we're-debugging teleport. This is totally unlike anything I've done yet and makes no sense for a first-person free movement game. But I might think about cursor/crosshair changes to signal what clicking on a block would do.)

That seems like a good excuse to write a status update. Since my last post I've made significant progress, but there are still large missing pieces compared to the original JavaScript version.

(The hazard in any rewrite, of course, is second-system effect — “we know what mistakes we made last time, so let's make zero of them this time”, with the result that you add both constraints and features, and overengineer the second version until you have a complex system that doesn't work. I'm trying to pay close attention to signs of overconstraint.)

[screenshot]

Now done:

  • There's a web server you can run (aic-server) that will serve the web app version; right now it's just static files with no client-server features.

  • Recursive blocks exist, and they can be rendered both in the WebGL and raytracing modes.

  • There's an actual camera/character component, so we can have perspective projection, WASD movement (but not yet mouselook), and collision.

    For collision, right now the body is considered a point, but I'm in the middle of adding axis-aligned box collisions. I've improved on the original implementation in that I'm using the raycasting algorithm rather than making three separate axis-aligned moves, so we have true “continuous collision detection” and fast objects will never pass through walls or collide with things that aren't actually in their path.

  • You can click on blocks to remove them (but not place new ones).

  • Most of the lighting algorithm from the original, with the addition of RGB color.

    Also new in this implementation, Space has an explicit field for the “sky color” which is used both for rendering and for illuminating blocks from outside the bounds. This actually reduces the number of constants used in the code, but also gets us closer to “physically based rendering”, and allows having “night” scenes without needing to put a roof over everything. (I expect to eventually generalize from a single color to a skybox of some sort, for outdoor directional lighting and having a visible horizon, sun, or other decorative elements.)

  • Rendering space in chunks instead of a single list of vertices that has to be recomputed for every change.

  • Added a data structure (EvaluatedBlock) for caching computed details of blocks like whether their faces are opaque, and used it to correctly implement interior surface removal and lighting. This will also be critical for efficiently supporting things like rotated variants of blocks. (In the JS version, the Block type was a JS object which memoized this information, but here, Block is designed to be lightweight and copiable (because I've replaced having a Blockset defining numeric IDs with passing around the actual Block and letting the Space handle allocating IDs), so it's less desirable to be storing computed values in Block.)

  • Made nearly all of the GL/luminance rendering code not wasm-specific. That way, we can support "desktop application" as an option if we want to (I might do this solely for purposes of being able to graphically debug physics tests) and there is less code that can only be compiled with the wasm cross-compilation target.

  • Integrated embedded_graphics to allow us to draw text (and other 2D graphics) into voxels. (That library was convenient because it came with fonts and because it allows implementing new drawing targets as the minimal interface "write this color (whatever you mean by color) to the pixel at these coordinates".) I plan to use this for building possibly the entire user interface out of voxels — but for now it's also an additional tool for test content generation.

Still to do that original Cubes had:

  • Mouselook/pointer lock.
  • Block selection UI and placement.
  • Any UI at all other than movement and targeting blocks. I've got ambitious plans to build the UI itself out of blocks, which both fits the "recursive self-defining blocks" theme and means I can do less platform-specific UI code (while running headlong down the path of problematically from-scratch inaccessible video game UI).
  • Collision with recursive subcubes rather than whole cubes (so slopes/stairs and other smaller-than-an-entire-cube blocks work as expected).
  • Persistence (saving to disk).
  • Lots and lots of currently unhandled edge cases and "reallocate this buffer bigger" cases.

Stuff I want to do that's entirely new:

  • Networking; if not multiplayer, at least the web client saves its world data to a server. I've probably already gone a bit too far down the path of writing a data model without consideration for networking.

I've been getting back into playing Minecraft recently, and getting back into that frame of mind caused me to take another look at my block-game-engine project titled "Cubes" (previous posts).

I've fixed some API-change bitrot in Cubes so that it's runnable on current browsers; unfortunately the GitHub Pages build is broken so the running version that I'd otherwise link to isn't updated. (I intend to fix that.)

The bigger news is that I've decided to rewrite it. Why?

  • There's some inconsistency in the design of how block rotation works, and the way I've thought of to fix it is to start with a completely different strategy: instead of rotation being a feature of a block's behavior, there will be the general notion of blocks derived from other block definitions, so “this block but rotated” is such a derivation.

  • I'd like to start with a client-server architecture from the beginning, to support the options of both multiplayer and ✨ saving to the cloud!✨ — I mean, having a server which stores the world data instead of fitting it all into browser local storage.

  • I've been looking for an excuse to learn Rust. And, if it works as I hope, I'll be able to program with a much better tradeoff between performance and high-level code.

The new version is already on GitHub. I've given it the name “All is Cubes”, because “Cubes” really was a placeholder from the beginning and it's too generic.

I'm currently working on porting (with improvements) various core data structures and algorithms from the original version — the first one being the voxel raycasting algorithm, which I then used to implement a raytracer that outputs to the terminal. (Conveniently, "ASCII art" is low-resolution and thus doesn't require too many rays.) And after getting that solid, I set up compiling the Rust code into WebAssembly to run in web browsers and render with WebGL.

[console screenshot] [WebGL screenshot]

(In the unlikely event that anyone cares, I haven't quite decided what to do with the post tags; I think that I will switch to tagging them all with all is cubes, but I might or might not go back and apply that to the old posts on the grounds that having a tag that gets everything is good and I'm not really giving the rewrite a different name so much as taking the opportunity to replace the placeholder at a convenient time.)

HTTPS, finally

Thursday, June 28th, 2018 10:34

In further news of updating my personal web presence, I have finally set up HTTPS for switchb.org. As I write this I'm working on updating all the links to it that I control.

The thing I found underdocumented in Let's Encrypt/Certbot is: if you want to (or must) manually edit the HTTP configuration, what should the edits be? What I concluded was:

<VirtualHost *:443>
  ServerName YOUR DOMAIN NAME
  Include /etc/letsencrypt/options-ssl-apache.conf
  SSLCertificateFile /etc/letsencrypt/live/YOUR DOMAIN OR CERT NAME/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/YOUR DOMAIN OR CERT NAME/privkey.pem
  SSLCertificateChainFile /etc/letsencrypt/live/YOUR DOMAIN OR CERT NAME/chain.pem

  ...rest of configuration for this virtual host...
</VirtualHost>

Notes:

  • /etc/letsencrypt/options-ssl-apache.conf (which of course may be in a different location depending on your OS and package manager) contains the basic configuration to enable SSL (SSLEngine on) and certbot-recommended cipher options.
  • You have to have a separate VirtualHost entry for *:443 and *:80; there's no way to copy the common configuration as far as I heard.
  • By "CERT NAME" I mean the name assigned to a multi-domain-name certificate if you have requested one. You can find out the certificate names with the command certbot certificates. For a single domain it will be identical to the domain name.

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.)

Yesterday I completely rewrote my resource embedding test to cover more cases (especially ones new in HTML5) and be more usable. In the likely event you're not familiar with it, it's a HTML document which embeds many types of resources (images, audio, other HTML, etc.) using all of the possible containers (<img>, <iframe>, etc.) to see how browsers react.

The results can be quite interesting; for example, with the current expansion I discovered that JavaScript embedded in a SVG document will not execute if embedded using <img>, but will with <object>. (In hindsight, this makes perfect sense given the fundamental design principle of Web security, namely “don't add anything which would obviously make existing sites' security assumptions false”, the assumption here being that it's safe to allow <img>s as user-generated content.)

Specific new features:

  • Audio, HTML, and plain text content. (Unfortunately, some combinations cause the audio to autoplay; I tried to make it quiet and plain to make up for that.)
  • <audio> and <video> containers.
  • Scripts inside HTML and SVG content, which also attempt to modify window.top.
  • Fixed-scrolling headers so you don't need a large window to make sense of the large table.

Let me know if you've thought of any additional useful cases.

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).

The draft-standard Gamepad API allows JavaScript in the browser to obtain input from connected gamepad/joystick devices. This is of course useful for games, so I have worked on adding support for it to Cubes.

This (about) is the only Gamepad API demo that I found that worked with arbitrary gamepads (or rather, the junk one I had around) rather than ignoring or crashing on anything that wasn't a known-to-it devices such as a PS3 or Xbox controller. (It's part of a game framework called Construct 2, but I haven't investigated that further.) It was critical to my early setup in making sure that I had a compatible gamepad and browser configuration.

(There's a reason for libraries having information about specific devices — the Gamepad API just gives you a list of inputs and doesn't tell you what the buttons should be called in the user interface — and these days you're almost expected to have pictures of the buttons, too. But there's no reason not to have a fallback, too. Incidentally, the USB HID protocol which most gamepads use is capable of including some information about the layout/function of buttons, but this information is often incorrect and the Gamepad API does not expose it.)

In order to integrate gamepad support into Chrome, I used Toji's Game Shim library, a very nice lightweight library which only adapts browser-provided interfaces to the current draft standards so that you can use the Gamepad API, as well as requestAnimationFrame, fullscreen, and pointer lock, without making your code full of conditionals or browser-specific prefixes.

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.)

Today I learned that there is a standard-DOM alternative to the convenient IEism element.innerText (a close relative of element.innerHTML): element.textContent.

It is slightly different, according to MDN: .innerText returns the visible text (omitting scripts and CSS-hidden text), whereas .textContent returns everything, more like walking the document tree.

(This information crossed my awareness while working on Caja, but I didn't recognize it as something I could actually make use of until now.)

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.

Cubes is a work-in-progress open-source block game (that is, like Minecraft) where the blocks are made out of blocks; in principle, you should be able to build a complete custom block game from scratch simply by building the appropriate block-set, out of blocks. As I mentioned earlier, I'm doing a project on the HCI for this game. I need data.

If you think you might be interested in playing my game, or if you're a current player of a block game (Minecraft, Terraria, FortressCraft, what-ever), please take this survey. I assure you there are no “On a scale from 1 to 5” questions in it.

In September, I wrote of my new project Cubes that “unfortunately, it wasn't an idea for either of my course projects this semester.” Since I have completely failed to find motivation for the course-related project I had planned to do, þreader (a thread-emphasizing feed reader; you can read the project introduction), I have decided to make the best of it and somehow make Cubes into the needed project.

I will therefore be using Cubes as my project for the course CS459 Human-Computer Interaction; the main consequence of this is that I need to actually study the potential users of my system.

So. To recap, Cubes is a block game (like Minecraft) where the blocks are made out of blocks; in principle, you should be able to build a complete custom block game from scratch simply by building the appropriate block-set, out of blocks. If you're a potential user of a game like this, and interested in giving me data (surveys, interviews, etc.), let me know. I will have something for you within the next few days.

Also, the live version of Cubes now supports load/save (either to Local Storage or by cut-and-paste of text (!)), so you can save your work! (I don't promise not to change the world format incompatibly, though.)

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.

LinkedIn?

Wednesday, March 2nd, 2011 07:37

Should I get on LinkedIn? One hears far less about what they're up to than Facebook, and I recently received an invitation from a friend of mine.

Less subjectively: What does LinkedIn offer (given that it's a social network site), and do you find it worth your time?

Update: I signed up. No especially noticeable effects so far other than one newsletter sort of mailing and a lot of people I know wanting to add me as a contact^Wconnection; presumably LinkedIn notifies you when people in your address book create an account?

“Tile Game” was a game I wrote in the spring of 2010 as my final project for CI272 Visual Basic at MVCC. It was written in, of course, Visual Basic. I have just finished porting it to JavaScript and you can play it online.

HTML or PDF?

Thursday, October 21st, 2010 12:00

I'm planning to write a short introduction/quick reference to LaTeX (with a particular emphasis on “what corresponds to this HTML element?”, and actually explaining the core syntax rather than just examples of particular cases), as another page on my web site. Should I write it as HTML or LaTeX (rendered to PDF)? Using LaTeX means I can embed rendered examples without each one being an image (which I don't really want to deal with), but the result being a PDF rather than HTML means that the document would have a fixed line width, and possibly require download/be unviewable depending on the particular browser/platform/installed plugins. (It could still have hyperlinks.)

(In case you're wondering, there are several LaTeX-to-HTML conversion tools, and the last time I looked they all either didn't run, accepted a far-too-small subset of LaTeX, or produced too-low-quality or obviously broken output. I used one of them for this post and had to hand-edit black bars out of every image and trim the margins, and the antialiasing is poor.)

What would you prefer?

Got a nice fluid layout on your web site? Annoyed at how mobile browsers like to assume pages need nine hundred virtual horizontal pixels to display properly? Add this to your <head>, as I've just done across my site:

<meta name="viewport" content="width=device-width">

This tells iPhone and Android browsers, at least, to present the page with a virtual window width equal to the device's actual screen width. It was invented and specified by Apple.

(I am not taking up the question of whether these browsers are making the right default choice. I will say, however, that in my technical opinion this is the wrong choice of location for this parameter: whether a layout will work at narrow widths depends largely on the stylesheet, not on the HTML; this parameter therefore ought to be stored in the stylesheet (that is, be a CSS extension); insofar as it does depend on the HTML, you can then put it in a <style> element.)

If you're looking to use media types to provide different styles: These browsers also don't respect the “handheld” media type; but they do support draft CSS3 Media Queries, which allow you to condition on the actual screen width — if you want, even in ems! I've used this on the main switchb.org page to make the Big Text less likely to spill off the screen (could use some further testing; all I've used so far is my desktop and a Nexus One), and also in the Caja Corkboard demo (which I wrote this summer (among other things) and ought to blog about).