Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comments
  • views

About this blog

Save your forks, there's pie!

Entries in this blog


Announcing Psychologist.js, a RAD HTML5 VR framework

I've written a little bit about this project for a little while, and I've finally decided on a name.

Psychologist.js is a framework for rapidly prototyping virtual reality applications using standard HTML5 technologies. It keeps you sane while bending your mind.

You can view a demo of the framework in action here.

You can access the repository on Github here.

Google Cardboard compatible: use your smartphone as a head-mounted display,
Multiplayer: share the experience and collaborate in cyberspace,
Leap Motion support: control objects with natural movement,
Game pad support: create fast-action games,
Speech recognition: hands free interactions,
Peer-2-peer input sharing: use devices connected to your PC with your Google Cardboard,
3D Audio: create fully immersive environments,
App Cache support: save bandwidth,
Blender-based workflow: no proprietary tools to learn,
Cross-platform: works in Mozilla Firefox and Google Chrome on Windows, Linux, and Android,
Oculus Rift support (coming soon): the cutting edge of head-mounted display technology.




HTML5 audio for games made easy

Audio in the browser is deceptively tetchy. It's easy to get a basic sound to play with the tag.[code=html:1] If you can read this, your browser is not fully HTML5 compatible.
But there are several problems with this:
First of all, good luck navigating this compatibility chart. Until Mozilla finally caved and decided to support MP3, there was no single file format supporting Chrome, Firefox, Safari, and IE. Opera is still a painful holdout on file formats, and the situation on mobile is disgusting.
You can't programmatically trigger the audio playing on mobile devices without direct user action in your game loop. You basically have to put up a "start game" button that tricks the user into playing a silent audio file, then you have free reign to trigger that particular audio element.
You get almost no control over how the file plays. There is a volume setting, but it hasn't always been reliable on all platforms. There's no mixing. There are no effects.
It's super difficult to rewind and replay an audio file. Honestly, I still don't really know how to do it correctly, and I'm a goddamn salty pirate.

In short, the tag is for one thing and one thing only: for NPR to post their podcasts directly on their site.

Okay, let's get out of this malarky. What else do we have? Well, there's the Web Audio API:
Granted, formats still aren't great. Strangely, the compatibilities don't exactly match the tag. But MP3 is universally there, as is AAC. And technically, you could write a decoder if you wanted. I wouldn't suggest it, but it is possible.
You can play audio whenever you want, as many times as you want, on desktop and mobile, without buggering around with stupid hacks.
It's a fairly-well featured signal processing system. That's great if you know what you're doing, murder if you don't.

It's a little difficult to program. And the MDN tutorial gets far too into crazy effects for me to bother if all I want to do is make a few blips, bloops, and gunshot sounds.

That's why I wrote this: Audio3DOutput.js. Here's what you do:[code=js:1]// to start, create the audio contextvar audio = new Audio3DOutput();// then, check if your system supports itif(audio.isAvailable){ // if you want to play a specific sound file every time a user clicks a mouse button: audio.loadBuffer("click.mp3", null, function(buffer){ window.addEventListener("mousedown", function(evt){ audio.playBufferImmediate(buffer, 0.25); // 25% volume gain }); }); // if you want progress notifications while the audio is loading and processing: audio.loadFixedSound("song.mp3", /* looping */ true, function(op, file, numBytes){ console.log(op, file, numBytes); }, function(snd){ snd.source.start(); }); // if you want to position the sound in 3D space: var sourceX = 10, sourceY = -4, sourceZ = 3; audio.load3DSound("ambient-sound.mp3", true, sourceX, sourceY, sourceZ, null, function(snd){ snd.source.start(); setTimeout(moveListener, 5000); // 5 seconds }); function moveListener(){ audio.setPosition(x, y, z); audio.setVelocity(vx, vy, vz); audio.setOrientation( ox, oy, oz, upz, upy, upz); } // if you want to take the first file of a list that successfully loads: audio.loadFixedSoundCascadeSrcList(["song.aac", "song.ogg", "song.mp3"], null, function(snd){ snd.source.start(); }); // or if you want to synthesize the raw PCM data yourself: // in monaural var data = [], seconds = 0.25; for(var i = 0; i
There you go. If you find a need for more than these basic functions, please drop me a line and let's discuss adding it!




Why I turned down a great job offer.

I recently received a very generous job offer from a rather prestigious company. I didn't even apply, they contacted me through LinkedIn. To say that I was honored to even receive a cold-contact from such a company is an understatement. "Flabbergasted" is a much more appropriate term.

The salary was great. There was an additional cash bonus of approximately "holy crap" dollars. There was also a stock grant of even more "are you freaking serious" dollars. The projects sounded right up my alley. And the managers sounded like good people. All around, it sounded great.

But I had to say no, for two specific reasons completely unrelated to compensation packages.

I'm an east-coast guy and they wanted me to move to the left coast.

My family is here and my wife's family is here. We specifically live in a place that is convenient for seeing our families on a regular basis. We had considered the possibility of moving, if the job presented a clear opportunity for significant career advancement. But we'd also like to have kids soon, and that's going to peg us even harder to only a few hours' drive from where the grandmas and grandpas live.

Also, I've spent the last two--almost three years working as a freelancer. The term "free-lance" comes from the great Scottish author Sir Walter Scott, referring to a sort of medieval mercenary, one whose "lance" was free of any sworn allegiance to any feudal lords. I've been incredibly productive during that time. The corporate desire to have people "on site" grows more and more alien to me every day. I know what work I'm capable of, and I think being self-directed and independent has markedly improved my output. To be asked to go to a specific place to do work in our now rather aged era of telecommuting feels like being asked to intentionally hobble myself for nothing more than someone else's convenience. I think the work is more important than that.

I'm not done with my current path.

I started freelancing for a reason. I was dissatisfied with my work-life relationship and I hoped I could one day create the sort of company that I have always wanted to work for. Freelancing is not an end to itself, but it is hopefully a means. The flexibility it affords is much closer to that ideal work life that I envisioned for myself than I've ever encountered before. I'm able now to work on my own R&D projects in addition to the freelancing with a focus and effort for which I had never had the adequate time while I was working as a 9-to-5 stiff. To take the job would be to give up on those plans, just as they are starting to show promise.

I take the mercenary notion of freelancing very seriously. I operate by my own ethic, one that places doing the right thing and doing the most important things above doing what I'm told. When a client hires me, they don't just buy my time, tapping on a keyboard at whatever they want. They buy my opinions and my taste regarding how work should be organized. Sometimes that can come across as defiance, but I do it out of respect for their needs as I see them, not as they are expressed in the heat of the moment.

Freelancing is a system that explicitly maintains that--at the end of the day--I own my own labor. It is the nature of corporate non-compete and non-disclosure agreements to capture and monopolize my labor as much as possible, for as little compensation as possible--indeed, why would a contractual agreement be necessary if the compensation were enough? And to make "my" company, I need to own my labor. While the NDA and Non-Competes weren't a major deciding factor in themselves to turning down the job, the prospect of what they meant for my personal projects certainly helped the decision along. It would essentially mean cancelling most of my projects. Their offer, while generous, was not quite that compelling.

I just couldn't do it.

Through out the interviewing process, I had this voice in the back of my head, chiding me, "it's a great job, you don't turn down such a good job." I'm sure working for this company would have been very rewarding. But I don't want a "job". I think I can do more. And I think I owe it to everyone involved to do so.




VR Lessons Learned So Far

This is a loosely organized list of things I've noticed while using and developing virtual reality applications for the smartphone-in-headset form factor. It is specific to my experience and may not reflect anyone else's personal preference, such that VR is apparently quite dependent on preference. But I think that steadfast rules of design are necessary for the impending VR bubble, to convey an aesthetic and unified design such that users may expect certain, common idioms and adapt to VR software quickly. Thus, this is list a roadmap of my current aesthetic for VR. It is a living document, in the sense that future experiences may invalidate assumptions I have made and force me to recognize more universal truths. Proceed with caution.[/font][/color]
Presence is the ability to feel like you are in the scene, not just viewing a special screen. You'll hear a lot of people talk about it, and It is important, but ultimately I believe it to be a descriptor of an end result, a combination of elements done well. There is no one thing that makes "presence", just as there is no one thing that makes an application "intuitive", "user friendly", "elegant", or "beautiful". They either are or they are not, and it's up to the individual experiences of the users to determine it.
Presence is a double-edged sword. [font=inherit]I've found that, once I feel "present" in the application, I also feel alone, almost a "ghost town" feeling. Even if the app has a single-user purpose, it seems like it would be better in an "arcade" sort of setting. To be able to see other people may help with presence.[/font]
The hardware is not yet ready for the mass market. That's good, actually, because the software and design side of things are a lot worse off. Now is the time to get into VR development. I'll say nothing more about the hardware issues from a performance side. They are well known, and being worked on [font=inherit]fervently [/font]by people with far more resources than I.
Mixing 2D and 3D elements is a no-go. Others have talked about not placing fixed-screen-space 2D heads-up-display elements in the view for video game applications, but it extends much further than that. The problem is two-fold: we currently have to take off the display to do simple things involving any sort of user input, and there is no way to manage separate application windows. We're a long way off from getting this one right. For now, we'll have to settle for being consistent in a single app on its own. A good start would be to build a form API that uses three-space objects to represent its controls.
Give the user an avatar. This may be a personal preference, but when I look down, I want to see a body. It doesn't have to be my body, it just needs something there. Floating in the air gives me no sense of how tall I stand, which in turn gives me no sense of how far away everything is.
Match the avatar to the UI, and vice versa. If your application involves a character running around, then encourage the user to stand and design around gamepads. If you must have a user sit at a keyboard, then create a didactic explanation for the restriction of their movement: put them in a vehicle.
Gesture control may finally be useful. I'm still researching this issue, but the experiments I've done so far have indicated that the ability to move the view freely and see depth make gestures significantly easier to execute than they have been with 2D displays. I am anxious to finish soldering together a device for performing arm gestures and test this more thoroughly. This demo makes it clear that this is at least an extremely lucrative path of study.
Use all of the depth cues. Binocular vision is not the only one. Place familiar objects with well-known sizes in the scene. Use fog/haze and a hue shift towards blue at further distances. But most importantly, do not give the user long view distances. Restrict it with blind corners instead. Binocular vision is only good for a few feet before the other depth cues become more important, and we are not yet capable of making a convincing experience without the binocular cue.
Object believability has more to do with textures and shading than polygon count. Save on polygon count in favor of more detailed textures and smooth shading.
Frame rate is important. I remember being perfectly happy with 30FPS on games 10 years ago. That's not going to cut it anymore. You have to hit 60FPS, at least. Oculus Rift is targeting 75FPS. I'm sure that is a good goal. Make sure you're designing your content and algorithms to maintain this benchmark.
Use lots of non-repetitive textures. Flat colors give nothing for your eyes to "catch" on to make the stereo image. The design of these viewer devices is such that the eyes must actually fight their natural focus angle to see things in the display correctly. It will be easier for the user if you make it as hard as possible to not focus on object surfaces. Repetitive textures are only slightly better than flat colors, as they provide a chance to focus at the wrong angle, yet still achieve what is known as the "wallpaper effect". And do not place smaller objects in any sort of pattern with regular spacing.
Support as many different application interactions as possible. If the user has a keyboard hooked up, let them use the keyboard. If they have a gamepad, let them use the gamepad. If the user wants to use the app on their desktop with a regular 2D display, let them. Do not presume to know how the user will interact with the application. This early in development, not everyone will have all of the same hardware. Even into the future, it will be unlikely that an app will be successfully monetizable with a user base solely centered on those who have all of the requisite hardware to have a full VR experience. [font=inherit]Be maximally accessible.[/font]
[font=inherit] Make the application useful. This seems like it shouldn't be said, but ask yourself what would happen if you were to rip out the "VR" aspect of the application and have people use it with traditional IO elements. Treat the VR aspect of it as tertiary. Presence by its very definition means forgetting about the artifice of the experience. If the experience is defined by its VR nature, then it is actively destroying presence by reveling in artifice.[/font]
[font=inherit] Much research needs to be done on user input especially for large amounts of text. Typing on a keyboard is still the gold standard of text entry, but tying the user to the keyboard does not make for the best experience, and reaquiring a spatial reference to the keyboard after putting the headset on and moving away from the keyboard is nearly impossible. Too often, I find myself reaching completely behind in the wrong direction.[/font]
[font=inherit] 3D Audio is essential. We could mostly get away without audio in 2D application development, but in VR it is a significant component to sensing orientation and achieving presence. I believe it works by giving us a reference to fixed points in space that can always be sensed, even if they are not in view. Because you always hear the audio, you never lose the frame of reference.[/font]
I may add to this later.[/font][/color]




WebRTC device syncing


Big update today. When you use your PC in conjunction with your Smartphone, the two devices will communicate over your local network, rather than having to take a round trip through the game server. This reduces latency, so when you move your mouse, it updates in the display almost immediately.




Week of Awesome 2 - The Toys are Alive - #1

So Week of Awesome 2 starts on the day I have a half-day of job interviews and a demo of a product I'm working on. From 10:30am to about midnight tonight, I'm either driving somewhere or trying to present myself as awesome and totally not a slob at all. But tomorrow, I should be free for the rest of the week.

The theme is "The Toys are Alive". A title comes to mind, "Adult Toy Story". Nah, that's too obvious.

The key to a good game competition entry is to have a simple concept, executed well, completed early, to which "polish" is added with the remaining time. Yes, polish is a positive addition of things, like sprinkles on a cake. Also, to not neglect sound. Even the most basic sound instantly increases the quality of a submission 10-fold. One should stick to things one knows well. Venturing into new territory is a good way to get "stuck in the weeds" and fail to complete a submission.

With that in mind, I should probably be making a business intelligence suite, perhaps a series of reports demonstrating the effectiveness of a hospital full of toys. "Toy Hospital Administrator Simulator". I'm sure to win[1]!

Since I still don't have a real concept in mind after half an hour of typing, I'm going to continue to fill space with useless junk about strategy.

HTML5/JS game. I'm going to reuse my growing project template for doing HTML5 web apps. It's all just boilerplate stuff for loading bars, rounded corners on buttons, that sort of junk. Other people might use something like Angular or Bootstrap, but I am too old for that shit.
2D graphics. I'm still learning Three.js in my WebGL Virtual Reality[2] project, so I'm going to stick to what I know and do Canvas 2D instead of WebGL 3D.
3D audio. It's just so easy to do in modern browsers, why the hell not?
Mix of procedural and static content: Maybe a static level-select map and procedural levels.

Figure out a proper concept to meet the theme
I don't currently have a good system for easily specifying and running keyframed 2D animations. Will have to figure something out here. Might be where I spend most of my time on this project.
I have simple boilerplate code for doing multiplayer stuff, but I feel like only a really good concept should have it. To add it as a gimmick would be detrimental.

Okay, that is all for now. I'll update this post here if I think of any concepts.

[1] Only if there is a "biggest Poindexter" award.

[2] Check it out. Star it. Follow it. Fork it and make contributions. Ask nicely and get direct commit access!




Getting started with Node.JS part 2: Socket.IO

A few days ago, I talked about how easy it is to get Node.JS installed, regardless of your platform, and get code running that shows something in your browser. Whether you're on Windows or OS X or Linux, there is only one package to install that gives you access to an easy-to-configure web server running in a language you probably already know: JavaScript.

Today, we're going to jump feet first into Socket.IO: a library for Node.JS that supports WebSockets[1] between your server-side code and your client-side code, all the way back to IE5.5. Yeah[2].

To start, we'll need a basic web server that can load static files and send them to the user. I'm jumping ahead here and assuming that I'm going to eventually want to serve up some HTML, CSS, client-side JavaScript, PNG, and MP3 files, considering the goal is to make a game here. That's a lot of different types of content, so I'm going to cheat and take a library someone else wrote for handling it: Mime. This will also give me a chance to show you what happens when you install a dependency through NPM.

I'm going to make a new directory for a project, then install the Mime library through NPM. I'm making a new directory because NPM is going to download some files for me and I want it to stick them somewhere that won't junk up my harddrive. Installing the library is just simple "npm install mime" statement.

And there it goes. NPM knows where to download the code for Mime because someone registered Mime on the NPM website. The library gets copied to a directory called node_modules.

Now, let's throw down some code into a text file:

I hope this is pretty clear on what it does. There is not a lot to cover. Probably the most surprising part of it is the http.createServer call. It's registering a callback function that will be called whenever an HTTP request is made to the server. In general, Node.JS does a lot of stuff through callbacks, to make up for its lack of multi-threading primitives of any type. It's basic HTTP from there. I save this to a file called "server.js" and run it with a simple "node server" (Node adds the ".js" file extension for me), I open my browser and head over the http://localhost:81/ and this is what I get:File not found. / reason: {"errno":28,"code":"EISDIR"}
Aaaah, yes, I didn't actually tell it what file I want. That's pretty easy to fix though. Let's kill the server with CTRL+C (webServer.listen will keep Node running until we explicitly kill it) and make the code default to loading an "index.html" file if the URL specified indicates it was a directory name.

I've also created a file named "index.html" that just contains the text "Hello, world!". Now, when I restart the server and load the page, I see this:

"But capn_midnight", you say, "Why don't we just use Express and weeooeeooeeeoooooo". Because we're making a Single-Page Application (SPA) that will have mostly static files for making an extremely basic front end, with most of the logic residing on the server side. If we need more out of our static content delivery than this, then we can figure that out later. Also, this article series isn't really about Node.JS or Socket.IO or Express or any thing in particular, it's about getting to make a multiplayer game very quickly.

Alright, let's move on to the Socket.IO stuff. Do yourself an "npm install socket.io" in your project directory. You'll notice that there is a lot more spewed out than when we did it for Mime. This is because Socket.IO has its own dependencies and NPM went ahead and got them for us. If you've done any reading about NPM installs, you might ask if we would want to install Socket.IO with the -g switch, for "global". Typically, global installs are for installing Node software that we are going to use, not libraries that our project is going to use. If we wanted to use the TypeScript translator, that would be done with "npm install -g typescript" (and you would have to have admin rights, so you probably need to sudo that if you're on a Unix-like OS). Then, we would have the TypeScript compiler, tsc, installed into our PATH, and we could use it directly from the command line. But that's not necessary here.

For code, I'm going to first push most of the Web server stuff into it's own file, just to try to keep everything tidy. The only thing left in my original source file is the call to create the server and start listening. It's important at this point to point out a point of interest in Node's import system. When you call the require() function, the parameter to it is actually specifying a search string, not exactly a library. It iteratively searches from the current directory all the way up to the root directory of your system, looking for a "node_modules" folder that has a file that matches the name you're looking for. And if you didn't add a file extension to the file, require() automatically assumes ".js" for you.

But, if you don't want to put your files into a folder named "node_modules" (or pollute your NPM installation directory), then you need to tell require to look in a specific directory for the file. It's a lot simpler than it sounds, just use the "." single-dot name for the "current directory" and apply your filename to that.

So in this particular case, I've moved my code to a file named "httpRequestHandler.js". I've put it in the same directory as my "server.js" file. So to import it, I must "require('./httpRequestHandler.js')" or "require('./httpRequestHandler')" for a little-bit shorter version.

Anyway, now that we've had that little bit of a side-quest, back to the task at hand. I add code to my server.js file for creating a WebSockets listener. It's very simple. If you've done any sort of network programming before, I'm sure you'll be as flabbergasted as I was.

Look at that! It's all of four additional lines of code to listen, respond to new connections, and do some basic communication. In other words, it's one more freaking line of code than things we're freaking doing.

So what is going on here? Well, lines 5 and 6 get our web server going again, to be able to serve up the index.html file that will represent the client side of our client-server modeled program. And lines 8 through 14 setup the server side of our client-server modeled program.
Line 8: Socket.IO needs to know what socket it's going to listen on. You can give it a specific port number, or you can give it a reference to your webServer object and it will listen on the same port as the Web server is running on. That's pretty neat.
Line 9: Registers a callback function that will execute whenever a new connection is made. At this point, we're officially ready-and-waiting for connections. The callback receives a parameter that is the socket object with which we'll communicate with the connected client. No polling for new connections, no needing to worry that work done to accept a connection is blocking IO with all of the other clients. It's the very picture of "just works".
Line 10: To send data to the client, we use the emit() method on the socket object. It takes two parameters, an event name and a data package to include with the event. The names can be anything of your choosing. Any event issued with emit() can be consumed with on(). The data package can be anything as well. Typically, we'll send a plain Javascript object, but for now I'm just sending a string.
Line 11: To receive data from the client, we use the on() method on the socket object. It takes two parameters, an event name and a callback function to execute when the event occurs. The callback function receives a parameter of its own, which will be the data package that was emit()ed at the server from the client.
Line 12: And then, for this example, just to prove to the client that we heard it, we echo back a message.

Finally, we need a little bit of UI code to provide a user a physical interface with which to interact with server:

By now, there shouldn't be anything surprising here. We using an HTML SCRIPT tag to import the Socket.IO library for the client side[3]. It specifies an object called "io" that has a method connect(). Connect takes an address and does all the handshaking necessary to establish a connection[4]. From there, it's exactly the same as wiring up the events and handlers as we did on the server side. Exactly the same. Networking code really can't get any simpler than this.

Start it up, click the button a few times, and you should see this:

By this point, if you know HTML, CSS, and JavaScript already, you can be off to the races on making a multiplayer game with Node.JS and Socket.IO. But I'm not going to leave you out in the rain just yet. Next time[5], I'll show you a very simple chat program using what we've learned so far. And this very simple chat program will grow legs and eventually become a Multi-User Dungeon, or MUD for short.

[1] strictly speaking, it's only WebSockets if you're on a browser that supports WebSockets, but they smooth over the details for you with some fallback options. By default, you probably won't have to worry about it.
[2] I know. Sploosh. Okay, the IE5.5 support isn't that mind blowing considering that it's done through a Flash plugin. But it points to a larger issue of dedication to cross-platform compatability in the Socket.IO dev team. This works whether you're on a 3 year old iPhone or a 10 year old laptop. In other words, if your code has platform compatability issues, it's probably not Socket.IO.
[3] The location of which is a closely guarded secret. Actually, it's just coming out of your node_modules directory. But Socket.IO is hijacking the HTTP requests a little bit to look for requests to the client JS file. Anyway, this is mostly out of scope here.
[4] There is a seriously heavy amount of code in this connect() method. It has to figure out what the client browser is capable of doing, be it true WebSockets, AJAX long-polling, or eventually just giving up and using a Flash-based fallback. And then it has to make the connection to the server and communicate those details so that the server knows how to respond. Again, not really that important.
[5] Which unfortunately might be a couple of weeks. I'm going on a two-week-long trip to the Galapagos Islands with my wife, my camera, and distinctly not my computer.




Getting started with Node.JS part 1: Setup

I had been hearing about Node.JS for a while. "It's JavaScript on the server!" I mostly ignored it, as ASP.NET was forced on me at the time and I hadn't yet given employed life the finger and a flaming bag of poo on its doorstep[1]. What does "JavaScript on the server" even mean?

Well, it's a little more than just the bare meaning of a JS execution environment outside of a browser. Think of it like JS finally making something out of itself. All those years in college. Getting stuck in low paying design jobs. Now it commands respect! It can connect to databases!

Basically, start with V8--Google's JavaScript engine, not the salty-disgusting-juice that tricks you into eating vegetables when you were expecting a fruit smoothy instead. Just like the JavaScript that runs in their Chrome web browser. Then, throw away DOM--or rather--never add it because you didn't add WebKit into the sauce. Finally--and here comes the important part--throw on top a reliable package manager and a core set of libraries that make building a stand-alone Web server nothing more than a few lines of configuration code.

I should probably just shut up now and get to the point, because I'm the one late to the party and you, dear reader, probably know all this junk already.

What kept me away for so long was Django. And Ruby On Rails. And Leinenkugel, or Lemonysnickets, or whatever the hell those people in [s]ScalaClosure[/s]Clojure land are calling it. See, I have been trying for many years to get out of ASP.NET, and having heard the call of all of these programming-language-plus-web-environment-plus-package-manager combos[2], I had tried them out, to much dismay. These things were a pain in the ass! This was what everyone on HackerNews was raving about and telling me I was the idiot for sticking to ASP.NET? Half this junk wouldn't run on Windows without at least a day and a half of tracking down obscure patches and packages and talismans, of which you're on your own finding because the communities are hostile towards Windows users. Yes, I know, you don't like "Micro$oft". But not helping me and not spending the extra effort to make your software compatible with Windows, you're also not helping me get one step closer to using Linux full-time.

But Node.JS isn't like that.

First of all, you install one thing. You go to http://nodejs.org/download/ and you pick the version that is right for your system. Or, you open your terminal and type "apt-get install nodejs" or "emerge nodejs" or "yum install npm" or "brew install node" or whatever, you can probably figure it out, it's out there in your package manager of choice. And it's done. You have it. It's even installed on your PATH now.

Next, you don't "django-admin.py startproject mysite" or "rails new mysite" and then watch as it does a ton of stuff that nobody has explained yet and aren't anywhere close to explaining, because apparently you should be happy that it just dumped half a megabyte of text on your hard drive when all you want to do is give the thing a spin. If you want someone to make a project template for you later, you can do that, but up front, when you're just trying it out, there is no necessity.

And finally, when you install new libraries through the package manager, NPM, you also don't go hunting for obscure C libraries that maybe didn't get included in your particular Linux distro because the package maintainer is a masochist who compiled his own Gentoo from scratch and you're on a base config of Linux Mint, or because you're on Windows still and would really rather not have to install that bastard child Cygwin.

So let's try it out now. Open your command line. Type "node". Hit enter. I'll wait. If you installed it like I said, it should work. They realized people don't like to take more than one step to use new software, so they setup reasonable defaults for everything. You'll be presented with a REPL[3]. Then, just type sometimg. Sometimes I type "hello", a methaphorical call out into the dark, searching for a response. It comes in the form of evaluation.

Try a few more things, quit out of it by hitting CTRL+C twice[4].

If you've ever done anything with the HTML, this is probably no big surprise. And that's the brilliance of Node.JS! It's a programming language you already know.

Okay, one more example, to show off how easy it is to get a Web server going, because REPLs are great and all but they don't a project make. Particularly clever students with well refined bullshitting skills will find everything they need in the next screenshot to make a successful consultancy. If you've never done web development before, you have no clue how much I didn't have to do here. This is not a specially contrived example with 10MB of configuration files in a Turing-complete config format. I did this from a bare install as I described in the article and you see everything in this image necessary to replicate it.

That's it for now. Stay tuned for my next article, which will cover WebSockets with AJAX fall-back through Socket.IO. What does that even mean!? LOLGIBBERISH! It means lower overhead for requests back to the server, which means faster updates from the server, which means we can start writing networked games in JavaScript and deploy them through the browser in a way that Java never seemed to be able to pull off.

[1] for the record, I still haven't, but I have stopped returning its calls.
[2] the good, ol' PLPWEPPMC, as my pappy used to call it
[3] Read-Eval-Print-Loop, a new brand of cereal to compete with Fruit-Loops
[4] or CMD+C on OS X, but I suspect you probably know to make the mental translation on your own by now




I used to be a member here

This was me back then, in the year 2002:

And this is me now, 12 years later:

So what happened in between?

Well, after getting my degree in Computer Science, I ended up bouncing around between jobs. I've had--depending on how you count--6 to 8 jobs in the last twelve years. Most of them sucked. I got depressed from this, thinking it was my fault, that my work problems were because I didn't have the discipline to get out of bed in the morning. Turns out that there was a global conspiracy to give the middle class the shaft and I couldn't get out of bed in the morning because my bosses were universally assholes.

I flitted around the Mid-Atlantic region for a while. Living at home with my parents, renting a place with coworkers, living at home with my parents again, forcing myself out by moving to a completely different city, losing everything I owned in a flood, breaking up with almost all of my friends from childhood, getting fired for the first time from a job (for not looking like I was busy enough, despite the fact that my work provided most of the revenue to the company), living on friends couches and basements and spare rooms for a while, tusling with the decision of whether or not to become a fulltime alcaholic, experimenting with online dating--an experience that got too close to receiving violence on too many occasions for my liking--and just generally kissing the nose of complete destruction.

So I resolved I would always do things my own way and not have a boss ever again. I took about a 4 month sabbatical (and by that, I mean that is all the longer my unemployment benefits lasted, thus forcing me to find gainful employment) where I taught myself how to motivate myself for work. I sold t-shirts for a while. I made props for museums. I got some consulting gigs. I now have one major client who pays all my bills. I'm completely out of debt--no cars, no student loans, no credit cards.

And I got married to a woman who fills me with so much love and provides me with such an amazing base of rationality and sanity that it almost seems like the 10 years prior to her never even happened.

I now live with her just outside of our nation's capitol. I could be healthier, but overall, my life is really great now. I'm writing a lot lately, and I do a lot of photography and artwork when I'm not programming and actually finishing projects on a regular basis. I work from home, frequently not putting pants on all day. Most people in Northern Virginia either works for the government or works for a company that works for the government, people who I get to make extremely jealous with my beard, long hair, and carefree spirit. And that feels like winning.

So am I back? Sure, I guess you can call it something like that. Why am I here? I can't predict the future and know that I will post here regularly again. I only post this now because I see there are still some people here who would presumably remember my name and might have wondered what happened to me. I don't want to come in acting like "I'm an old, wisened master, bow before my wisening". I guess I'm here to learn again.

Here, this place, where I first learned.




Enterprise Game Design - week 1 update

Got some work done. I've deleted the empty sections without renumbering the sections, so don't get confused when it jumps from section 4 to section 8.

1 Introduction
1.1 Purpose
This is a general software design for character-oriented, story-driven games, as distinctive from sports games, puzzle games, etc. The resulting game framework will be suitable for developing open-ended worlds with story-centric interactions. The primary emphasis is on interactive story telling, with a secondary emphasis on multiplayer interaction as an enhancement to the story telling system.
1.2 Document Conventions
As deterministic computers are incapable of true randomness, the distinction between pseudo-random and random is ignored. For this reason, the terms pseudo-random and random are used interchangeably throughout the document to refer to predictably repeatable pseudo-random sequence generation.
1.4 Suggested Reading and Game Playing

Plots Unlimited, Tom Sawyer, Arthur David Weingarten, 2004
The Writer's Journey: Mythic Structures for Writers, 2nd Edition, Christopher Vogler, 2007
Noctis v4.0, by Alessandro Ghignola.
The Elder Scrolls IV: Oblivion, from Bethesda Softworks.

2 Scope
2.1 Identifications
2.1.1 Need
Content creation is an expensive, time consuming process. Scripted content is also not as satisfying as "real content" to the consumer. The current state of the art in pseudo-random content generation has solved these problems for physical objects and environments. The problems of random story generation and robust interactive story telling have yet to be conquered.

By utilizing mathematical formulae to generate and reliably re-generate data that appears convincingly natural and organic, random content generation saves on content creation time in trade for research and development time. However, the trade is more than economical, as the random content generator is limited only by the restraints of computer memory systems. A good random content generator is able to generate quantities of data so vast that the user may reasonably assume it to be infinite.

Scripted content has the capacity to feel realistic during the user's initial experience, but quickly grows stale. Scripted content turns the game into a sort of "Game World Amusement Park", where the game attempts to provide each individual player with the same, repeatable experience. This is comparable to the way a roller coaster provides every amusement park customer with an identical, repeatable experience.

Conflict is the basis for plot and story progression. Conflict in reality is not scripted; it comes about through the clashing of opposing motivations. By creating a system in which story is dynamically generated through the simulation of the interaction between player characters and artificial intelligence actors, the system eliminates the "Amusement Park" aspect of game world interaction. It is the difference between riding through a constructed park of robotic animals and embarking on a real safari through untamed land.
2.1.5 Assumptions
The distinction between "client" and "server" are relative terms. Sinking the server into the client and removing the network stack should be sufficient to make a single-player game.
2.1.6 Constraints
The specific details of game play mechanics unrelated to story progression are left unanswered, to permit the story telling mechanic to be adaptable to any style of game play. Graphics, audio, and other user interface considerations will also not be covered in great detail, again for the sake of modularity. UI features will be a bare-minimum system necessary to demonstrate the capabilities of the framework.

For the sake of security and portability, and because of the lack of emphasis on UI, the Game Client portion of the design will be relative thin compared to the Game Server portion.
2.3 Known Risks
The creation of a gaming framework for any purpose, let alone a general purpose framework, is a monumental undertaking. Having no distinct game play or user interface characteristics requirements to limit the scope of the project greatly enhances the scale of the project. As this is being developed as a side project, time resources for it are very limited. Project failure due to stagnation, even after very significant resources have been spent on the project, is a distinct risk.

Currently, no dynamic story generation system of the scale proposed in this document exists on the market. While basic, automated story generation systems exist, they are far too simplistic for the purpose of this project. While more complex story generation processes also exist, they require far too much human interaction to be readily adaptable to an automated system. There is no evidence that such a large-scale dynamic story generation system is even possible. Striking out into new territory is always risky.
3 Requirements
3.9 Server
Server tasks are game-play-agnostic. The server has a semantic understanding of the game content, but does not care how that content is rendered.

. Maintain position in server cluster
. Manipulate data in a single dataset for the entire cluster
. Enforce game play rules
. Provide data to user on request
. Allow users to interact with each other
. Simulate other users as NPCs
. Take hot-updates - fixes while the server is still running
4.2 Server Environment
4.2.2 Microsoft Solution
Operating System: Microsoft Windows Vista 64 bit Ultimate Edition
Runtime Environment: Microsoft .NET v3.5
Database: [Microsoft SQL Server 2008| PostgreSQL 8.3.3]
4.2.3 Open Source Solution
Operating System: FreeBSD 7.0
Runtime Environment: [Java SE 6.0|Mono 1.9]
Database: PostgreSQL 8.3.3
8 Appendix B: Areas for Further Research

. Pen-and-paper RPGs
o DND 3.0, 3.5
o other
. Game Maker applications
o MMO (does one exist)
. Network Development
o As relates to MMOs
o How FPS shooters differ
o Encryption
. Games
o RPGs
? Neverwinter Nights
? The Elder Scrolls: Morrowind + Oblivion
? Mass Effect
? Etc.
o Sandbox Games
? CrackDown
? Etc.
o Mod-able FPSes
? Half-Life 1+2
? Battlefield
. Scripting Systems
. AI Techniques for games
o Strategic vs. Active
. Pseudo-random content generation
o Terrain
o Cities
o Characters
o Stories
. Story-writing
. Spatial servers for game world data




Story-Driven Game Framework: an Enterprise Approach

I've been talking with a couple of guys here at work about game development. We're all avid gamers across all different types of games (i.e. electronic, board, pen-and-paper), and we are all fairly successful enterprise software developers. So, I'm trying to take the results of our discussions and formulate them into a general software design for character driven games, as distinctive from sports games or puzzle games, etc.

The basic idea is that the resulting game framework should be suitable for developing open-ended worlds with story-centric interactions. The emphasis is really on story telling, then game play (which may include multiplayer). Only after these aspects have been fulfilled will graphical quality be considered.

As what we really care about is the gaming system itself, not the means in which the user interacts with it, the Game Client portion of the design will be relative thin compared to the Game Server portion. In this case, "client" and "server" are relative terms. If possible, sinking the server into the client and removing the network stack should be sufficient to make a single-player game. So, such considerations as graphics and sound will be of little interest. Arguments over "DirectX vs OpenGL" are unnecessary, because in all reality, the first client will probably be text-based. UI considerations will only be "that which is enough to demonstrate the capabilities of the framework."

I have a ton of notes on paper, and still a ton of research to do, but I have been able to build a basic outline thus-far. Much of the project will be filling in the blanks from here.

1) Introduction
a. Purpose
b. Document Conventions
c. Intended Audience
d. Suggested Reading
2) Scope
a. Define
i. Need
ii. Goal
iii. Objectives
iv. Business Case
v. Assumptions
vi. Constraints
b. Operational Concept
c. Known Risks
3) Requirements
a. Overview
b. Game Network
i. Topography
ii. Encryption
iii. Data
iv. Performance
c. Story Telling
d. Physical Representation
e. Game-Play
f. Server
g. Client
4) Game Server System Design
a. Overview
b. Server Environment
c. Game-Play
d. Story
e. Mapping
f. Physics
g. Scripting
h. Artificial Intelligence
i. Networking
j. Database
5) Game Client System Design
a. Overview
b. Expected User System Requirements
c. Networking
d. User Input
e. Graphics
f. Sound
6) References
7) Appendix A: Glossary
8) Appendix B: Areas for Further Research

I don't really need to complete these sections in a linear fashion. In fact, a linear progression would probably be stifling to the process. Continuous refinement and parallel implementation will be necessary to fully account for all features and pitfalls.

I realize that what I'm undertaking is pretty much the software development equivalent of putting a man on the moon... with tools from my garage. However, I think the goals of the project and the milestone goals (unpublished as of now) will set me up for having some sort of useful results even if they don't make it into one system.

Incidentally, my journal writeup here serves as a pretty good start for the intro bullet.




Dirty Laundry

Okay folks, this is called "Exposing my dirty laundry, with the hopes that I will be shamed into making progress".

Exposing My Dirty Laundry

I have about a metric ton open software projects right now. These are in no particular order, other than "As I see them while browsing through my project folder".

Fishtank: a simulation of a fishtank, meant to be a game in the vein of all those Sim-X games. However, it was also a learning experience in strict MVC architecture, as the code base has three different front-ends: a command line interface meant to eventually be a telnet interface, a GDI+ GUI interface, and an XNA GUI interface. I had also planned on making a Silverlight interface, but then something shiny distracted me.
Genetic Paint: this one isn't really important, but I never got it to work, so it bugs at me. It's a Genetic Programming implementation that is meant to reproduce simple bitmap images by evolving lists of drawing operations. It doesn't work, because I don't have a Neural Network image recognition system to guide the selection process. Like I said, it's not breaking me up to much that this one isn't done.
JScript Runtime Environment: I think javascript would be a good learning language for new programmers, but there aren't very many good tools for working in it. So, I wrote a basic editor with in-place interpreting (actually, it's compiled on the fly, through the .NET compiler). I'd still like to finish it, but in the process I got distracted by...
Syntax Hilighting Textbox Control: yeah, Yet Another Textbox Control. However, there currently does not exist a good, free, syntax-hilighting textbox control for .NET, so I thought I would make one. I've made decent progress, I have all of the individual questions answered, I just need to put them all together, make a solid, bug free implementation, include some documentation, and then release it. Yeah, that's all, honest.
P2P Instant Messenger: This was meant to be the starts for creating a game lobby system that did not require a game lobby server. The idea was to use the fail-safe features of P2P networks to ensure the game lobbies were always available, and use regular client-server connections to run the games. Not too torn up about this one either, as network code really isn't my thing, not what I get up out of bed in the morning looking forward to doing.
Simple Finance Application: I have always felt that the main reason I don't keep up with tracking my finances is that Quicken and MS Money are too freaking bloated and complex. They have tons of features that I don't need, or similar functioning features that could be consolidated down to a single feature if they were treated more abstractly. I ran into a snag with my graph drawing not covering subsets of my data properly, so this project kind of fizzled.
2D Rigid Physics Engine: I might as well just throw this away and use something Off The Shelf. I am dissapointed with myself that I couldn't figure the math out on my own. I have everything except conservation of energy. That's kind of the most important part.
Toxic Gas Cloud Simulation: this I started more to cheese off one of my bosses. I claimed I could write a better simulation of gas clouds than the several thousand dollar tool we were licensing. In about 2 hours I had a reasonable mock-up. She got really pissed at me, but I got more interested in the project itself.
PocketPC Development: I have a bunch of little, one-off projects that run on Windows Mobile. They little things like a Notepad clone (because the Windows Mobile text editor doesn't make raw text files), a Dice Roller, a database for tracking progress over time while training for cross-country running, other stuff.
PriorityQueue: just what it sounds like, a priority queue container for .NET, because .NET does not have one. It's actually complete, I just need to document and release it somewhere.
Puzzle Games: I wanted to write a durth of simple puzzle games that I could just skin and sell for $5 a pop. I even wrote an entire framework for manipulating puzzles, with a Tetris clone as an example of using the framework. I just never got around to finishing an original puzzle, with a proper UI. That's where a lot of my projects end up dieing on the vine, whenever I get around to writing the UI.
My Website: I have a bunch of things that I still want to do to my website to get it to the point where everything else is just content. Actually, most of it can be consolidated into a single CMS, but once again, I'd rather write my own CMS than use something off-the-shelf.
Sheep Song: the game of song writing with colorful sheep. I really can't go into much about this one, other than once again getting bored with UI work.
Spatial Server: a database for geographically oriented data. Traditionally, spatial databases are implemented on top of regular relational databases. This provides for the ability to reuse the SQL engine as a simple spatial querying system, i.e. "SELECT * FROM POLYGONS WHERE POINTS.LEFT > @BouningBoxLeft AND POINTS.RIGHT
Issue Tracker Program: this I actually released! Internally, that is. Some of my coworkers are using a desktop-based issue tracking program I wrote. It runs off of a central database and uses a tagging-based system to track issues. The issues can be anything since its all based around the tagging system, but it's flexible enough to be used for defects, requirements, administrative notes, etc. I need to work out some bugs, improve the deployment model, and maybe add a few more features, and then it will be ready for prime-time.
Optical Illusion V2: a follow-up to my now 3 year old optical illusion project.
Word Search Game: auto generating word search boards based off of dictionary files. This is pretty close to being done.
XML Editor Tools: a library of tools for editing XML files. The System.Xml namespace in .NET is pretty much inadequate for any heavy work. It's okay if you're just consuming XML files, but generating them is a completely different deal.
Asteroids-like Online Game: I have a large portion of this done, but it's in Java, and I want to do it in XNA now. Once again, something shiny distracted me.

The sad thing is that I have ideas for other projects, I just haven't created project files for them yet.





Grad School Bid, 2.0

Okay folks, I've got the bug again for wanting to go to grad school. I was kind of disheartened by the lack of response from my last go-around with grad school applications, so I'm going to need a lot of moral support this time around.

I'm looking to do Computer Science with studying graphics in some way. I have a lot of ideas involving optical illusions that would be great for handheld devices. Perhaps some of you remember that project from some years ago. I thought it was a really original project, with very compelling results. I got a lot of good responses on it from anyone I could get to look at it. I thought I would be a shoe-in to most grad schools based on that project alone; I got no responses at all. I'm pretty sure it was because of my GRE scores, I just completely bombed the CS subject test.

I'm not certain of where I want to go. Superpig mentioned trying to apply to Oxford, which *would* be freaking phenominal, but I'm just not sure I could swing it, financially. Carnegie Mellon seems to be the #1 center for mixing Computer Science and Cognitive Science, which is the essential basis for study of optical illusions, but again, I got passed over by them the first time. UMBC seemed like a safe bet last time, but alas it was not true. Georgia Tech is one of the premier schools for doing graphics study, and they overlooked me too.

So help me out, guys. I want to pick my school more based on location. I'd like to live in the Philadelphia area, the Baltimore area, or the UK.

Also, I need to figure out my angle for my applications. I don't want to take the GRE again, it's expensive and studies I've read suggest that it has almost no correlation to academic success anyone, which makes me want to refuse on principle alone. I have 3 years of work experience under my belt now, and my resume is pretty good. I *do* have an original research project to my name, and I've spoken at conferences before.

Maybe we can work on a plan of action for things I can do before I apply to help bolster my application.





So, I'm driving in my Fiji Blue 2008 Honda Civic Si to work at the Conservatory for Bad-Assery one morning along this really sick-ass section of road that runs along a cliff face plummeting down into this deep ravine full of rocks and trees and shit like out of a movie like Lord of the Rings or something, when this giant, fire-breathing dragon comes screaming in from deep, dark corner of the chasm, like it's some kind of chasm of despair, and starts hovering right in front of me on the road. I'm like, "ohshitohshitohfuckohshit" and really starting to freak out when I remember, "hey, I've got a fucking rocket launcher, I mean seriously, who doesn't amiright?" So, I hoist this rocket launcher up on my shoulder as I'm standing up out of my sunroof and blast a billboard on the side of the road, the billboard falls down, I punch the gas on my car and totally use the billboard to ramp up and over this gigantic dragon, like whoa, and the dragon is looking up at me as I'm flipping through the air and I can see the look in its eye, and the dragon is totally saying, "hoooolyyyyy shiiiiiit," and I'm all, "oooooh shiiiiit," and as I'm just over the dragon I say "yooooou shall not paaass" and I shoot my biggest heat seeking rocket right at the dragon's tonsils. The rocket flies right down his throat and EXPLODES in his stomache, raining down this mass of blood and guts and bubbles and jet fuel and shit everywhere.

It was fucking metal.




IEEE Float Suck

IEEE standard floating point numbers, at any bit depth, should not be used to define color spaces. Specifically, one should not use floats or doubles (henceforth collectively "floats") as color components when rendering High Dynamic Range Imagery (HDRI). Due to the nature of the representation of floats, they cannot be used to define uniform color spaces.

The IEEE standard for floating point numbers defines a 32 bit float as a 1 bit sign value, an 8 bit biased exponent value, and a 23 bit fraction value. The exponent is "biased" in that it represents an integer value from which the value 127 is subtracted, to give a real range of exponent values from -127 to +127. The fraction is the fraction portion of a number expressed in "floating point binary notation".

There are 6 reserved values

0 00000000 00000000000000000000000 = 0
1 00000000 00000000000000000000000 = -0

0 11111111 00000000000000000000000 = Infinity
1 11111111 00000000000000000000000 = -Infinity

0 11111111 00000100000000000000000 = NaN
1 11111111 00100010001001010101010 = NaN

Any value that uses a full bit field for the exponent value is a non-number with the IEEE representation. With this exponent, and a 0 fractional value, it is interpreted as signed infinity. With a non zero fractional value, it is interpreted as Not A Number. Because of this interpretation, there are a full 2**24 unusable values when using floats as color components.

For example, the number -32.5625 would be converted as

S = 1, as the number is negative
temp = 100000.1001, "floating point binary representation"
= 1.000001001 x 2**5
E = 5 + 127 = 132
= 10000100
F = 000001001, drop the "1." from representation
= 00000100100000000000000, padded with zeros

Full number:
1 10000100 00000100100000000000000

The problem with color spaces lies in calculating the difference between two "consecutive" floats, i.e. floats that differ only in their least significant bit. Color is equally dependant on the relationship between two very similar colors as it is on the absolute value of a single color. Without thinking about the problem, one might think that this difference is very small, as floats are capable of representing very small numbers. However, once we start calculating the exact decimal value of the float representation boundary cases, we see that the difference between "consecutive" floats is dependant on the actual value of the numbers.

As an example, I've constructed a "4bit IEEE-like floating point number." It has no sign bit; a positive, 2 bit, unbiased exponent (so translating the exponent is not necessary, as with 32 or 64 bit floats); and a 2 bit fraction. Otherwise, calculating the value follows the same rules as regular IEEE floats. The purpose of using such a limited example is to allow us to see the full range of values that can occur for a specific representation.

bin | sci not |fp bin| dec | delta
0000 | 1.00 x 1 | 1.00 | 1 | -
0001 | 1.01 x 1 | 1.01 | 1.25 | 0.25
0010 | 1.10 x 1 | 1.10 | 1.5 | 0.25
0011 | 1.11 x 1 | 1.11 | 1.75 | 0.25
0100 | 1.00 x 2 | 10.0 | 2 | 0.25
0101 | 1.01 x 2 | 10.1 | 2.5 | 0.5
0110 | 1.10 x 2 | 11.0 | 3 | 0.5
0111 | 1.11 x 2 | 11.1 | 3.5 | 0.5
1000 | 1.00 x 4 | 100 | 4 | 0.5
1001 | 1.01 x 4 | 101 | 5 | 1
1010 | 1.10 x 4 | 110 | 6 | 1
1011 | 1.11 x 4 | 111 | 7 | 1
1100 | 1.00 x 8 | 1000 | 8 | 1
1101 | 1.01 x 8 | 1010 | 10 | 2
1110 | 1.10 x 8 | 1100 | 12 | 2
1111 | 1.11 x 8 | 1110 | 14 | 2

What this shows us is that the difference in values in the range of floating point numbers is not fixed.

Next, we will calculate the exact decimal value that two "consecutive" floats represent. These numbers are the 2nd-largest and largest possible, positive floats.

2nd largest 32 bit float
Binary: 01111111011111111111111111111110
Sign: 0
Exponent: binary 11111110 - 01111111 = 254 - 127 = 127
Fraction: 11111111111111111111110 = 2**24 - 2
Binary scientific notation: 1.11111111111111111111110 x 2**127
Decimal: 3.4028232635611925616003375953727e+38
Equivalent: 2**128 - 2**105

largest 32 bit float
Binary: 01111111011111111111111111111111
Sign: 0
Exponent: binary 11111110 - 01111111 = 254 - 127 = 127
Fraction: 11111111111111111111110 = 2**24 - 1
Binary scientific notation: 1.11111111111111111111111 x 2**127
Decimal: 3.4028234663852885981170418348452e+38
Equivalent: 2**128 - 2**104

Difference: (2**128 - 2**104) - (2**128 - 2**105) = 2**105 - 2**104 = 2**104 = 20282409603651670423947251286016
or roughly
2.0282 x 10**31

We can do the same calculations for the difference between the two smallest numbers and come up with a difference of 2**-150, or an extremely small number.

Using floats to define a color space will result in a non-uniform color space. There will be a lot of subtlety in the middle of the range, and giant leaps between values at the ends of the range. In the end, there are really only 2**32 - 2**24 unique and usable 32 bit floats (as was previously demonstrated) unique and usable 32 bit floats, because of the 5 "special values" that the IEEE float specification defines for values such as plus or minus infinity. Just these special values alone limit the expressive power of floats in defining a color space.

Unsigned integers work much better for defining color spaces, as there are a full 2**32 unique and usable values, and the difference between the largest two integers is the same as the difference between the smallest two integers: only 1.




LittleBugs, update 2

Here is the XML Schema for the bug list:

"1.0" encoding="utf-8" ?>


"UserList" minOccurs="1" maxOccurs="1"/>
"ProjectList" minOccurs="1" maxOccurs="1"/>

"userID" type="xsd:integer" default="1337"/>


"name" type="xsd:string" use="required"/>
"userID" use="required"/>
"contact" type="xsd:string"/>


"User" minOccurs="1" maxOccurs="unbounded"/>

"userID" use="required"/>

"UserAssignment" type="UserAssignmentType"/>


"UserAssignment" minOccurs="1" maxOccurs="unbounded"/>


"Name" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="false"/>
"Summary" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="false"/>
"Creator" minOccurs="1" maxOccurs="1" nillable="false" type="UserAssignmentType"/>

"creationDate" type="xsd:string" use="required"/>


"Description" type="DescriptionType" minOccurs="1" maxOccurs="1" nillable="false"/>
"UserAssignmentList" minOccurs="0" maxOccurs="1"/>

"id" type="xsd:integer" use="required"/>
"resolvedDate" type="xsd:string" use="optional"/>


"Bug" minOccurs="1" maxOccurs="unbounded"/>


"Description" type="DescriptionType" minOccurs="1" maxOccurs="1" nillable="false"/>
"UserAssignmentList" minOccurs="1" maxOccurs="1"/>
"BugList" minOccurs="1" maxOccurs="1"/>


"Project" minOccurs="1" maxOccurs="unbounded"/>

That should work for now.




LittleBugz update

In starting this journal entry, I'm considering the scope of the LittleBugz project. This journal entry is then a brain storming session on my behalf. Over the course of the entry, I had changed my mind on the scope of the proejct, but I left the process of coming to that decision in the entry.

I'm thinking LittleBugz will support multiple modes of operation. It could have a wizard interface to ask the user questions about how they are going to use LittleBugz, and then it will select a mode of operation based on that.

Modes will cover different combinations of features:

Single user versus multi user
user authentication versus no auth
user roles versus no user roles
XML file versus database store

Here's how I expect them to be used:

Single User, no auth, no roles, XML file store:
An organized todo list for an hobbyist working on personal projects

Multi user, authenticated, no roles, XML file store:
A small team (3-5) of hobbyists, probably close friends, working on a project together. They already have source control, probably something like SVN, and the XML store file will be in that source control. Everyone has full control over the bug list. Authentication is merely for accounting, not security.

Multi user, authenticated, roles, database store:
A medium sized team (10 - 20) of hobbyist developers (probably OSS), with a designated project lead.

At this point, I really don't have much interest in being useful for anything larger than a small team of hobbyists who are also friends and thusly trust each other. There are plenty of bug tracking solutions for medium sized OSS teams (in particular, Bugzilla comes to mind). The scope of this project is specifically to be a simple bug tracking system. A medium sized team will need more bug tracking features than I intend to include in this project. For that reason, I doubt few medium sized teams will use LittleBugz, even if I provide the User authentication, roles, and database support that they would need.

Up to this point, I had been building LittleBugz on top of SQL Server 2005. I think that's too much of an obfuscation now. I don't expect beginners to be able to handle setting up SQL Server 2005 Express Edition with the proper security settings. As far as databases go, it's not that difficult to do, but as far as beginners go, it's really a chore. For a single-man team, it offers nothing, and for a small team it doesn't offer anything that could not be achieved in other ways. By elliminating support for a database store, I will simplify the project significantly.

Project and Bug definitions will be stored in an XML file. The developers will be free to figure out their own strategy for sharing that XML file. The suggested method will be to add the XML file to source control and to use file merging to stay up to date on bugs created by individual developers. Bugs and projects will be ID'd with GUIDs to ensure there are no collisions between new bugs during file merges.

Roles have no use to a single-man team. I don't think a small team of friends are going to worry about project roles. Of all the small teams I've been involved in, control over work items hasn't been an issue. The only time a concept of "project role" came in to play was during decisions involving project features and project scope. That's merely a political distinction at that point, and up to being handled by the team itself.

Authentication has no use to a single-man team. Because of the trust level between a small team, authorization has no use in a smal team. Authentication, however, is desirable, to keep a record of changes. The project can then assume that authorization is handled de facto by the source control system. If a user has access to the source code, why not give them access to the bug list, too? At this point in time, LittleBugz has full authentication with hashed passwords. Passwords are going to be removed, they just aren't necessary.

Okay, there we go. This will greatly simplify the use of the project. I can elliminate any need for a "use mode" wizard now. When the application starts for the first time, the user will enter their name. This name will then be automatically added to every bug that that user creates. Since the multi-user aspect is essentially handled by external tools, their really is no need to even track users at all -- it just becomes an extra field on the Bug itself.

Should have done this from the start.





I've started a small defect tracking project that I call "LittleBugz - defect tracking for small projects". The idea is to provide a basic level of defect tracking in a simple-to-use interface leveraging .NET and SQL Server.

Right now I'm developing in C# on VS 2005 Pro with SQL Server Pro. I'm thinking of popping over to VC# EE "Orcas" Beta to get a head start on learning C# 3.0 and Linq.

This project is so simple, I could probably finish the first draft in a day. The only reason I haven't is because I was trying to do everything with Data Bound controls, and I really don't have the time to be figuring that out right now. Over time, I expect to add features to it to create some basic report generation. I won't get too much use out of the project personally, as I have access to Team Foundation Server, but I expect a number of people might like something like this. I know at least one guy in #gamedev who was looking for something like this.

It's WinForms right now, with no plans to do a web-based interface.




Power Outage Fried My Computer

Yup, my main desktop was dead for about two weeks thanks to a power outage. I originally thought that it was just the hard drive, because I could boot it up, but it would die whenever I got to a certain point in loading Windows. After closer inspection, I have determined that the outage actually fried my graphics card (Radeon 9800 something something). The fan on the card's heat sink is siezed and the chip under the heat sink is charred around the edges. I've got an old 9200 SE in it's place right now, but it's giving me weird scanline issues and I can't change my display settings. Eh, whatever. I got my documents backed up to an external USB hard drive now, and I got the important documents burnt off to CD, so everything is safe.

Right now the desktop is operational, but I'm concerned that the reason the GPU was fried was because the mobo is faulty. This computer has always had problems of some type, from frying parts to never being able to properly handle a warm OS restart. If I perform a restart instead of a full shutdown cycle, it loses its secondary IDE channel and halts processing for about half a second about every 5 seconds. This isn't an OS issue, it did it to Linux and BSD, too. That, coupled with the fact that it has become prohibitively expensive to upgrade the memory (Rambus RDRAM, wooo), and it's clear that this computer just has to go.

I had been considering rebuilding it to a usable configuration and gifting it to a family member, but given the restart issue I don't think that is a workable solution as none of them will understand what is going on or how to fix it (just shut it down). It took me a year to figure out exactly what was going on, I don't want to leave that kind of bug for my grandmother or someone.

Incidentally, my laptop has hit a brick wall, too. It's running fine, but it's just not powerful enough to do the things I want to do. It's an old P3 1.2Ghz machine, but it uses an integrated Intel graphics chip, so it doesn't support the minimum specs for doing XNA development. When I got the laptop, even though it was literally half the specs of my desktop in every way (512mb of ram instead of 1gb, and a 1.2ghz processor instead of 2.4ghz, a 20gb hard drive instead of a 40gb hard drive, etc, etc), it had almost completely replaced my desktop because I could use it in the livingroom instead of having to retreat to the basement where I keep the desktops. Since XNA has replaced Hardware Accelerated Java2D for me, in everything from ease of development to support to performance, if my lappy can't do XNA, then it's pretty much worthless to me.

So right now, the only computer I have at my disposal is my work laptop. At least it seems to be working ok. Knock on wood.




New development journal

In my quest for pulling everything under my own control, I have started my development journal on my site specific. You can find it here. It is NOT a Blog. Blogs are written by illiterate carpetbrains who voted for John Kerry. It is a journal.

Unfortunately, it got auto-installed to a directory named "blog" anyway. Grrrr.




create content++

So, I've got room creation working in No Room For Monkeys. You navigate to a room and from there you can create one. This creates a world graph that is a nice N-ary tree. However, it currently does not allow for cycles in that graph, which basically means there is only one path to any particular room. I think I might specify two types of room connections, a natural connection that arose from graph navigation, and a portal to connect unrelated nodes. This way, users can navigate the world in a compelling fashion, without creating unmanageable graph cycles.

Take a quick look:

To simplify the stored procedure for making the Connections list (will be renamed Exits), I redefined room connections as being one way (hmm, I should rename the columns to reflect that). Now, if you want to be able to walk back and forth between two rooms, it needs two connections, one for A-to-B and one for B-to-A. This actually makes sense, as it will allow for a compelling feature regarding room connections, i.e. something akin to "Shoots and Ladders".

Shouldn't be hard to make the People Here list for each of the rooms. Something like

create procedure proc_GetUsersHere
@RoomID int
select a.UserName
from aspnet_Users as a, UserStats as b
where a.UserID = b.UserID
and b.RoomID = @RoomID;

Items Here would be similar.

I'm going to introduce a few user roles. There are the obvious User and Admin, but I think I'm going to define Limited and Unlimited content creators as well. This will be done through the ASP.NET Membership Roles system, if I can figure out how to administer it properly.

Hmm, just reallized that I could still create a telnet interface for this MUD, and have it running on the same database with no compromises. Schweet, like candy. I might make a thin-client, too. That's what this project is all about, using standard .NET controls to build a fully featured game.




No Room For Monkeys

Asteroids project hit a major snag. One of my developers is gone, and it looks like he left quite a few unfinished changes. I'll have to manually undo them, as the SVN reversion isn't going very well.

Also, I was unemployed for a while, and I really didn't touch a computer during that time. I've been working again for about a month (with some very nice people at a company that seems small enough to stay mostly un-evil), and I'm almost back on my feet. Luckily I don't have any credit cards, and I had a pretty good chunk of change saved up, so I didn't get into too much trouble with not having any income for about two months.

At last count, I had the vector editor completed, along with the starts for a proper quadtree system. It's time I finally got some network code in there. I need to do a mini-project in networking first, because my attempts at networking in the past have been rather hackish.


At work I've been doing a lot of stuff with .NET, SQL Server, Windows Server, etc. I've been building a Smart Client application (desktop app tied to a central database server and supporting offline editting) that interacts with a number of different Web Services. It's aware of one Web Service for certain data needs, and it queries a UDDI (Universal Description, Discovery, and Integration) Server to get at the others. I had to write an WSDL handler to manually extract information about arbitrary web service, though. As far as I can tell, you can only consume a Web Service if you are aware of its interface ahead of time. This seems kind of silly to me, but whatever, using a few simple XPath queries gets me the info I need lickity split. All rather interesting stuff from an Enterprise Development standpoint.

I'm trying to apply what I've been learning to a personal web server that I have set up in my basement. I'm fiddling around with ASP.NET 2.0 and building a very simple web-based game to learn the ropes of system administration. In the process, I'm trying to use as many OTS products as possible. I'm running Windows Server 2003 (on 180 day trial right now), Sequel Server 2005, and IIS 6.0. The ASP.NET Membership Profile system is pretty cool. If you know how to set it up, you can have a Website running supporting user accounts in a matter of a few minutes. Even supporting creating/managing user accounts, password management, and roles management. It's really freaking neat.

Anyway, the game is called "No Room For Monkeys" and will feature user generated content. I'm thinking existing users will create rooms with a requirement of having a 1:1::User:Room ratio. If a new user tries to join and the ratio is too low, then they'll see a message "Dammit! I *told* you there was no room for monkeys!"

erh, whatever. Look at the page layout.




ack 2.0

I'm derunk, in a hotel room, surfing gdnet and eating a turkey and cheese sandwich. this is the most exciting time I have had all week. bloomington, il is awesome.




intarblag tube.0


"Decal" Editor: Decals are instance objects that are used for rendering. Instead of having a million polygons for a million stars, now there is one polygon (Decal), and a million star objects that reference it by an ID. I thought Decal was more of a descriptive name than "Sticker" or "Stamp" in this regard. Decals support seperate stroke and fill colors, as well as sub decals, i.e. different sections of the decal for different blocks of color.
New Developer: One of my coworkers has signed on and started working on the physics system. The physics system wasn't as complete as I previously though. It conserved momentum, which is great, but it didn't conserve energy, which is really bad. Andrew is going to also help with pulling the game simulation out of the client and into a server. Engage Wootbot.
New Project Notes Page: Don't forget to check it out on my retardedly simple wiki.


More Unit Testing: Getting a little bit better about this...
Physics Server: Closer to this goal than previously, but still a ways off. First step to making the game multiplayer will be to get the solar system simulation running on a server instead of in the game clinet itself. It will require me to undo some optimization work that I've done.
Content System: About 50% completely right now, now that I have the Decal Editor and the Decals are serializable. I have no content system right now. All objects are hardcoded right now. Dirty, dirty, dirty.



Sign in to follow this  
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!