Wednesday, May 20, 2015 Eric Richards

For the past few weeks, I've been once again noodling on the idea of starting a .NET port of a classic Id FPS. As a kid on my first computer, an off-brand 486 with DOS, I just hit the tail end of the good old days of shareware. And amongst all the floppy disks of kiddy and educational software and sliming Gruzzles couldn't really hold a candle to exploring Indiana Jones and the Last Crusade-esque Gothic castles and knifing Nazis.

While the original source-code for Wolfenstein 3D has been available for some time, it is a bit of a slog trying to wade through C code that was written 20 years ago, with near and far pointers, blitting directly to VGA memory, and hand-rolled assembly routines, let alone build the project successfully. Consequently, converting over to C# is a bit of a struggle, particularly for some of the low-level pointer manipulation and when loading in binary assets - it is very helpful to be able to step through both codebases side by side in the debugger to figure out any discrepancies.

Because of these difficulties, I have started looking at the Chocolate Wolfenstein 3D project, by Fabien Sanglard. Mr. Sanglard is a great student of the Id Software engine source code, and has done several very nice writeups of the different engines open-sourced by Id. He was even planning on writing a book-length analysis of Wolfenstein 3D, which hopefully is still underway. Chocolate Wolfenstein 3D is a more modernized C++ conversion of the original Id code, with some of the more gnarly bits smoothed out, and using SDL for cross-platform window-management, graphics, input, and sound. Even better, it can be built and run using current versions of Visual Studio.

The only problem I had with the Chocolate Wolfenstein 3D GitHub repository is that it is missing some dependencies and requires a small amount of tweaking in order to get it to build and run on Visual Studio 2013. These steps are not particularly difficult, but if you simply clone the repo and hit F5, it doesn't work right out of the box. If you are working on a Mac, there is a very nice guide on setting up the project in XCode, but I have not found a similar guide for Windows, so I decided to document the steps that I went through and share those here.

Chocolate Wolfenstein 3D title screen


Wednesday, May 13, 2015 Eric Richards

If you have not used it yet, Signalr is a real-time web communication library which is now under the ASP.NET banner. It is a very cool technology, which allows you to actively push data from a server application to your clients, without having to worry too much about the particular transport mechanism by which the content is delivered - SignalR ideally uses WebSockets, but degrades gracefully to older transport protocols (like AJAX long polling), if WebSocket connections are not supported by either the client or server. This is very powerful, since it allows you to write a single implementation, focused on your high-level needs, and SignalR handles most of the nitty gritty work for you. In addition, while SignalR can be used as something of a dumb pipe (although not that dumb, since you do get object->JSON serialization out of the box) via PersistentConnection, the real power of SignalR lies in its Hubs concept. By connecting to a SignalR Hub, a client can call methods on the server, both to execute commands, or to query for data. Similarly, the server can issue commands to the client by calling client-side callback methods.

This allows you to do some pretty cool things. Probably the canonical example is web-based instant-messaging/chat rooms, which is dead simple to implement using SignalR. But really any kind web page that polls for new data on an interval is a good candidate for SignalR, like, say, real-time dashboards, or a sports score ticker, maybe some classes of multiplayer games.

One scenario that SignalR does not support very nicely is when the server needs to query its clients for information and have that data returned to the Hub. As currently implemented, a SignalR client can only define handlers for methods called by the Hub which are Action<T,...> delegates, which have a void return signature. So, while the code below will compile if it is included in a Hub method, data is actually a Task object, which is an asynchronous wrapper for the client-side Action. In short, there is no way to directly return a value from a client-side method back to the Hub.

var data = Clients.Client(SOME_ID).GetData()

Why would you want to do this kind of action using SignalR? In my case, I recently encountered a situation where a third-party library implemented a wrapper around a COM application. This COM wrapper was implemented as a singleton, but in my particular case, I needed to execute multiple instances of the underlying COM application, in order to connect to an external service with different user accounts, but, because the wrapper was a singleton, I could only make one connection from my main application process. However, I could get around this limitation by spawning an additional process for each instance of the COM wrapper that was required (fortunately, it was simply a C# singleton, and not limited by any kind of global mutex). While each child process could for the most part operate independently performing its responsibilities, the main application needed to be able to issue commands to control the child processes, as well as retrieve information from them for various reporting features and to ensure consistency in various aspects globally across the application.

I considered using a more traditional IPC method, like bidirectional sockets, or named pipes, but the simplicity and cleanness of using SignalR was more attractive to me than rolling my own message-passing protocol and coding a message loop on both sides. At least for issuing commands to the child processes, implementing a SignalR Hub on my main application to which the clients would connect was pretty quick and easy. Then I ran into the difficulty of how to get data back out of the child processes using SignalR.

In retrospect, I could have modified the code executing on the child processes into a more event-driven form, so that I could use the normal SignalR paradigm to push information to the Hub in the main application, instead of querying the child processes for it. However, this would have involved a complete revision of the architecture of the application (there were very similar components that ran within the main process, using the same interfaces and the bulk of the implementation), as well as necessitating an extensive amount of caching in the main process.

Instead, I settled on the slightly crazy pattern illustrated here. In broad strokes, what I am doing is:

  1. A specially-tagged SignalR client owned by the main application calls a method on the Hub requesting a piece of data from a specific child process.
  2. The Hub resolves the requested child process to its SignalR connection Id, and calls a method to order the child process to assemble the requested data.
  3. The child process calculates the requested data, and pushes it to a different method on the Hub.
  4. The second Hub method stuffs the pushed data from the child process into a dictionary, keyed by the child process' identity.
  5. While this has been happening, the first Hub method has been blocking, waiting for the requested data to appear in the dictionary.
  6. When the data appears in the dictionary, it is popped off, removing the key from the dictionary, preparing the dictionary for the next invocation. There is also a timeout value, so that if there is some sort of interuption, a default value will be returned, rather than indefinitely blocking.
  7. Finally, the first Hub method returns the piece of data to the main application.

bidirectional signalR

The code for this example is available on GitHub at https://github.com/ericrrichards/crazy-signalr-ipc


Wednesday, February 11, 2015 Eric Richards

Just a quick update today. I've updated the 3D model loading code to use the latest version of AssimpNet that is on Nuget now. The latest code is updated on GitHub.

The biggest changes appear to be that the AssimpImporter/Exporter classes have been merged into a single AssimpContext class that can do both. Some of the GetXXX methods to retrieve vertex elements and textures also appear to be replaced with properties. The way that one hooks into the internal Assimp logging has also changed. I haven't discovered many other changes, besides some additional file format support yet, but I haven't gotten around to really explore it that closely. Mildly irritating that the interface has changed here, but hey, at least it is being actively worked on (which is more than I can say for some of my stuff at times...).

I've been quite busy with work lately, so I haven't had a huge amount of time to work on anything here. I'm also a little burned out on doing straight DX11 graphics stuff, so I think I'm going to try to transition into doing some more applied work for a while. I've got some stuff in the pipeline on making simple games with Direct2D, and ideally I'd like to get involved with One Game a Month, to give me a little additional motivation.

skinnedModels


Saturday, January 17, 2015 Eric Richards

Recently, I have been using OWIN a good deal for developing internal web applications. One of the chief benefits of this is that OWIN offers the ability to host its own HTTP server, which allows me to get out of the business of installing and configuring IIS on windows, which is one of the main points of pain when deploying the products I work on to our customers. Unfortunately, when I first started using OWIN, there was not a version of ASP.NET MVC available that was compatible with OWIN. Most of my previous experience with programming web servers has been based on MVC (except for briefly experiencing WebForms hell), so finding a similar framework that was compatible with OWIN was one of my first priorities.

In my search, I discovered Nancy, a fairly similar MVC-style framework which offered OWIN support. It also was capable of using the same Razor view engine as ASP.NET MVC, with some minor differences, so I was able to convert existing IIS ASP.NET MVC applications to OWIN/Nancy using most of the existing views and front-end code. At some point I plan to write an article illustrating how one would do this type of conversion, but for now, I'm going to examine one particular gotcha I discovered when converting my personal Netflix-type video application to OWIN/Nancy: serving HTML5 video files.


Sunday, December 21, 2014 Eric Richards

A couple of weeks ago as I was browsing HackerNews, I stumbled onto an article about creating spherical procedural maps by Andy Gainey. Procedural terrain/map generation is always something I find interesting, having grown up slightly obsessed with Civilization and its successors. Various methods of tiling a sphere in order to make a game grid have been bouncing around the back of my mind for a while now - unfortunately finding time to explore some of those ideas has been problematic. But, after reading through Mr. Gainey's piece and looking over the source for his demo, I got inspired to take a stab at something similar. My first attempt was to try to directly port his Javascript implementation, which got bogged down in the impedance mismatch between going from JS to C# and WebGL to DirectX at the same time, so I stepped back, and decided to come at the idea again, working in smaller steps.

The first step was to generate a spherical triangle mesh. For this purpose, the spherical mesh that we have previously worked with is not very well suited, as its topology is very inconsistent, particularly around the poles, as you can see in the screenshot below. Instead of this kind of lattitude/longitude subdivision, we will instead use an alternate method, which starts from an icosahedron, then subdivides each face of the icosahedron into four triangles, and finally projects the resulting vertices onto the sphere. This produces a much more regular tessellation, known as a geodesic grid, as you can see in the right screenshot below. This tessellation is not without artifacts - at the vertices of the original icosahedron, the resulting geodesic will have five edges, while all other vertices have six edges, similar to a real-life soccer ball.

lat/long tessellation
Lattitude/Longitude tessellation, with artifacts at the poles
geodesic tessellation
Geodesic tessellation

Frank Luna's Introduction to 3D Game Programming with Direct3D 11.0, Chapter 6, presented a method of generating of generating a geodesic sphere, which I previously skipped over. The code for this example is based upon his example, with some improvements to eliminate redundant vertices.

The code for this example can be obtained from my GitHub repository.


Bookshelf

I have way too many programming and programming-related books. Here are some of my favorites.