Some time ago, I came up with an idea of a story about a guy, not unlike myself, who got transported to a foreign land and learned that magic is real. That idea never really left me, and I slowly started to develop the setting, some characters, and the story itself.

Every time I hit a roadblock, I feel like writing some thoughts down might help me; but I'm never around the computer when this happens. Today, I finally decided to jot down at least something, hoping that I'll be able to persuade myself one way or another.

So today's roadblock: What would prompt the main character to leave the 3rd city and go north? It could be: someone stole the crystals--but that would introduce a mystery toward the end of the story. The main villain could have stolen them. But how would the main villain also know where they are? It could be an unrelated reason: to catch his ride home? But he doesn't care about going back now as much. I guess I need to start thinking about what he wants to do, and then figure out whether going north would seem natural to the plot or not.

Bioshock Infinite

After beating Bioshock Infinite, I have just 1 relatively spoiler-free complaint about it. Collapse ) While the game is a step in the right direction for the industry, it's rather insignificant by itself.  I was bored by it, and couldn't wait to finish it so that I could move to playing better games.  Even travelling by Sky-Line--initially the coolest part of the game--got tedious toward the end.


I finally had a chance to try Sous-vide. Sous-vide is a method of cooking food (mostly meats) in a vacuum-sealed container, which is submerged in a bath of hot water. The idea is simple: Pasteurisation temperature is 131 degrees F; so as long as you raise the temperature a few degrees higher, any food you eat will be safe. The fastest way, of course, is boiling; but boiling will disperse all the juices and make the food taste bland. This is where plastic bags come in: they seal in the flavour while still allowing food to be cooked thoroughly.

Since there are no nearby restaurants that offer Sous-vide steaks, I decided to cook the steaks by myself. Here's how to do it: first, get some expensive meat. Nothing outrageous, of course; I tried Top Sirloin and Tri-Tip. They were around $10/pound; but half a pound is more than enough for most people (if served properly, with two sides). Season the steak using SOFA (Salt, Oil, Flavor, Acid): pepper, salt, lemon juice, and a dash, and put it into a zipper storage bag. (I used a sandwich Ziploc.) Fill a pot with hot tap water, set it on low heat, and get a thermometer, a chopstick, and a clip (any clip). As soon as the temperature reaches 130 degrees F, dip the bag in the water and suction the air. Then close the bag, put the clip on top of the bag, put the chopstick through the clip, and rest it on both sides of the pot. The meat should be fully underwater, while the top of the bag should be above water.

Then, carefully control the temperature so that it's between 131 and 140 Fahrenheit. 131 will yield a Medium-rare steak, while 140 will yield a Medium steak. Cook the steaks for at least 90 minutes (but do consult a Sous-vide cooking chart if your steak is extra-thick or cold). Right before serving, pre-heat a frying pan on high temperature, and fry the steaks on both sides for about 100 seconds to get a brown crust. (I tried grilling and frying; frying, surprisingly, tastes better.) Voila!

You will have a tender, delicious, 8-ounce steak that costs $5 and tastes as good as a $30 steak in an expensive steakhouse. (Thanks, Microsoft, for treating our team to lunch! :-)) The meat will be reddish-pink when you cut it. Don't worry: it's not blood, it's simply Pasteurised Myoglobin. But be careful: you might not want to go out to a steakhouse afterwards.
  • Current Music

WinSock 2.2

I've been working with Windows Sockets recently, and I want to summarise a few things that I've learned, just in case I'll need to remember them in the future.

(1) Berkeley Sockets are supported, and work fine for console applications. They aren't ideal if you need to mix in threads or message pumps. Also, select() behaves slightly differently on Windows than it does on Unix. If you are waiting for 2 sockets and only the second is signalled, then in Unix FD_ISSET(0, read_set) is false and FD_ISSET(1, read_set) is true. In Windows, read_set.fd_count is 1, and read_set.fd_array[0] is the handle of the second socket (since sockets aren't created in a nice arithmetic progression).

(2) There's a way to have select() work directly with window messages: WSAAsyncSelect(). But you need to create a window in that thread, which obviously limits the current number of running threads. There's also WSAEventSelect(), which requires a call to WaitForMultipleObjects() instead of a window. It's slightly simpler to use.

(3) The most straightforward way to write multi-socket servers is to use IoCompletionPorts. Every operation is asynchronous; once the operation finishes you can find out the result by calling a blocking function GetQueriedCompletionStatus (from any thread--which is a big advantage).

(4) In order to use techniques 2 or 3, you need to create "overlapped" sockets (using socket() or WSASocket(WSA_FLAG_OVERLAPPED). If you're calling accept()/WSAAccept(), then the new socket will be "overlapped" if the listening socket is overlapped (which is important!). I still can find no reason to create a non-overlapped socket intentionally, since passing a NULL lpOverlapped converts any function into a blocking function (this is true only for sockets).

(5) Neither accept() nor WSAAccept() (same applies for variants of connect()) are overlapped calls, so they cannot be serviced by the threads that are looping over GetQueriedCompletionStatus(). You can either have a thread dedicated to accept() (or connect()) calls, or use a bizarre WinSock2 extension called SIO_GET_EXTENSION_FUNCTION_POINTER, which associates your listening socket (or connecting socket) with a Completion Port, so that you can have homogeneous loops. Here's what it looks like:

#include <mswsock.h>

unsigned long dummy = 0;
SOCKET listeningSocket = CreateListeningSocket(80);
CreateIoCompletionPort((HANDLE) listeningSocket, currentCompletionPort, 42, 0);

// Load the AcceptEx extension function from the provider for this socket
&guidAcceptEx, sizeof(guidAcceptEx),
&fnAcceptEx, sizeof(fnAcceptEx),
&dummy, NULL, NULL);
fnAcceptEx(/*Crazy parameters*/);

It's not as bad as it looks--but depending on the design of your application, WSAAsyncSelect may be all that you need. :-)
  • Current Music


Damn you, Cy & H, for making me listen to dubstep! Before, I was happy not even knowing what it was... *sniff*

(But I prefer the Wub Wub to polyrhythms... ^_^)
  • Current Music
    Dubstep - D I G I T A L L Y - I M P O R T E D - Dubstep hits and mixes!!!! - Salomon - Stepping On D


This post contains spoilers about: KotOR 1 and 2, Ringworld and Ringworld Engineers, Integral Trees, Dreamfall, Ender’s Game, and Xenocide
Collapse )
  • Current Music
    Tripswitch - Strange Parallels


Yesterday, I tried Durian for the first time. Also, probably for the last time: It tastes like a combination of mango, avocado, and raw onion. It also smells like a combination of mango, avocado, and raw onion. But, see, while I like mangoes, and I enjoy avocados, I try to avoid raw onions by either skipping or frying them; so mangos clearly have all the advantages and none of the disadvantages of cracking open a large, spiky fruit.
  • Current Mood
    amused amused