Become a Patron!

I’ve come to a crossroads recently.

I write a blog post every week. It takes time. The last one was close to 2,000 words and required reading a book. For the past three years I’ve been writing full time, and so blogging can be a burden that cuts into this with no monetary rewards.

This blog is now over nine years old, and I’ve done nothing to monetize it. I think this is mostly a good thing. I do not and will not run any sort of advertisements. Even upon the release of my first book, I only did a brief mention and then no promotion afterward (and as far as I can tell, this converted to literally 0 sales).

I want this to be about the blog content. I do not want it to turn into some secret ad campaign to sell my work. I can think of many authors who have done this, and I ended up unsubscribing from them.

This brings me to the point. Putting this much work into something is not really sustainable anymore without some sort of support, so I’ve started a Patreon page. As you’ll see, my initial goal is quite modest and will barely cover the expenses to run my blog and website. But without anything, I will slowly phase out writing here regularly.

If this concept is new to you, Patreon is a site dedicated to supporting creative work. Patrons can pledge money to support people creating content they like. It can be as little as $1 a month (or as many podcasters say: “less than a coffee a month”), and in return, you not only help the site to keep running, you’ll receive bonus content as well.

Because of the scattered nature of my posts, I know a lot of you are probably scared to support, because you might not get content of interest for the month. Some of you like the math and tune out for the writing advice. Some of you like the critical analysis of philosophy and wish the articles on game mechanics didn’t exist.

For consistency, I’ll only put out something that would be tagged “literature” for the vast majority of posts from now on. This means once a month or less and probably never two months in a row (i.e. six per year spread out equally). This “literature” tag includes, but is not limited to, most posts on philosophy that touch on narrative or language somehow, editing rules, writing advice, book reviews, story structure analysis, examining pro’s prose, movie reviews, and so on.

Again, the core original vision for the blog included game and music and math posts, but these will be intentionally fewer now. If you check the past few years, I basically already did this anyway, but this way you know what you’re signing up for.

I think people are drawn to my literature analysis because I’m in a unique position. This month I’m about to submit my fifth romance novel under a pseudonym. This is the “commercial” work I do for money, and it’s going reasonably well. I’ve come to understand the ins and outs of genre fiction through this experience, and it has been a valuable part of learning the craft of writing for me.

My main work under my real name is much more literary. I’ve put out one novel of literary fiction. Next month I’ll put out my second “real” novel, which is firmly in the fantasy genre but hopefully doesn’t give up high-quality prose.

These two opposite experiences have given me an eye for what makes story work and what makes prose work. All over this blog I’ve shown that I love experimental writing, but I’ve also been one of the few people to unapologetically call out BS where I see it.

As you can imagine, writing several genre novels and a “real” novel every year makes it tough to justify this weekly blog for the fun of it.

If I haven’t convinced you that the quality here is worth supporting, I’ll give you one last tidbit. I get to see incoming links thanks to WordPress, so I know that more than one graduate seminar and MFA program has linked to various posts I’ve made on critical theory and difficult literature. Since I’m not in those classes, I can’t be sure of the purpose, but graduate programs tend to only suggest reading things that are worth reading. There just isn’t enough time for anything else.

I know, I know. Print is dead. You’d rather support people making podcasts or videos, but writing is the easiest way to get my ideas across. I listen to plenty of podcasts on writing, but none of them get to dig into things like prose style. The format isn’t conducive to it. One needs to see the text under analysis to really get the commentary on it.

Don’t panic. I won’t decrease blog production through the end of 2017, but I’m setting an initial goal of $100 per month. We’ll go from there, because even that might not be a sustainable level long-term. If it isn’t met, I’ll have to adjust accordingly. It’s just one of those unfortunate business decisions. Sometimes firing someone is the right move, even if they’re your friend.

I’ve set up a bunch supporter rewards, and I think anyone interested in the blog will find them well worth it. I’m being far more generous than most Patreon pages making similar content. Check out the page for details. The rewards involve seeing me put into practice what I talk about with video of me editing a current project with live commentary; extra fiction I write for free; free copies of my novels; extra “Examining Pro’s Prose” articles; and more!

I hope you find the content here worth supporting (I’m bracing myself for the humiliation of getting $2 a month and knowing it’s from my parents). If you don’t feel you can support the blog, feel free to continue reading and commenting for free. The community here has always been excellent.

What is an Expert?

I’ll tread carefully here, because we live in a strange time of questioning the motives and knowledge of experts to bolster every bizarre conspiracy theory under the sun. No one trusts any information anymore. It’s not even clear if trusting/doubting expert opinion is anti/hyper-intellectual. But that isn’t the subject of today’s topic.

I listen to quite a few podcasts, and several of them have made me think about expertise recently.

For example, Gary Taubes was on the Sam Harris podcast and both of them often get tarred with the “you don’t have a Ph.D. in whatever, so you’re an unknowledgeable/dangerous quack” brush. Also, Dan Carlin’s Hardcore History podcast is insanely detailed, but every ten minutes he reminds the audience “I’m not a historian …”

Many people who value the importance of expertise think that the degree (the Ph.D. in particular but maybe an MFA for arts stuff) is the be-all-end-all of the discussion. You have the Ph.D., then you’re an expert. If you don’t, then you’re not.

The argument I want to present is that if you believe this, you really should be willing to extend your definition of expertise to a wider group of people who have essentially done the equivalent work of one of these degrees.

Think of it this way. Person A goes to Subpar University, scrapes by with the minimal work, kind of hates it, and then teaches remedial classes at a Community College for a few years. Person B has a burning passion for the subject, studies all of the relevant literature, and continues to write about and develop novel ideas in the subject for decades. I’d be way more willing to trust Person B as an expert than Person A despite the degree differences.

Maybe I’ve already convinced you, and I need not go any further. Many of you are probably thinking, yeah, but there are parts to doing a degree that can’t be mimicked without the schooling. And others might be thinking, yeah, but Person B is merely theoretical. No one in the real world exists like Person B. We’ll address each of these points separately.

I think of a Ph.D. as having three parts. Phase 1 is demonstration of competence of the basics. This is often called the Qualifying or Preliminary Exam. Many students don’t fully understand the purpose of this phase while going through it. They think they must memorize and compute. They think of it as a test of basic knowledge.

At least in math and the hard sciences, this is not the case. It is almost a test of attitude. Do you know when you’re guessing? Do you know what you don’t know? Are you able to admit this or will you BS your way through something? Is the basic terminology internalized? You can pass Phase 1 with gaps in knowledge. You cannot pass Phase 1 if you don’t know where those gaps are.

Phase 2 is the accumulation of knowledge of the research done in your sub-sub-(sub-sub-sub)-field. This basically amounts to reading thousands of pages, sometimes from textbooks to get a historical view, but mostly from research papers. It also involves talking to lots of people engaged in similar, related, or practically the same problems as your thesis. You hear their opinions and intuitions about what is true and start to develop your own intuitions.

Phase 3 is the original contribution to the literature. In other words, you write the thesis. To get a feel for the difficulty and time commitment of each step, if you do a five year Ph.D., ideally Phase 1 would be done in around a year, Phase 2 is 2-4 years, and Phase 3 is around a year (there is overlap between phases).

I know a lot of people aren’t going to like what I’m about to say, but the expertise gained from a Ph.D. is almost entirely the familiarization with the current literature. It’s taking the time to read and understand everything being done in the field.

Phase 1 is basically about not wasting people’s time and money. If you’re going to not understand what you’re reading in Phase 2 and make careless mistakes in Phase 3, it’s best to weed those people out with Phase 1. But you aren’t gaining any expertise in Phase 1, because it’s all just the basics still.

One of the main reasons people don’t gain Ph.D.-level expertise without actually doing the degree is because being in such a program forces you to compress all that reading into a small time-frame (yes, reading for three years is short). It’s going to take someone doing it as a hobby two or three times longer, and even then, they’ll be tempted to just give up without the external motivation of the degree looming over them.

Also, without motivating thesis problem, you won’t have the narrow focus to make the reading and learning manageable. I know everyone tackles this in different ways, but here’s how it worked for me. I’d take a paper on a related topic, and I’d try to adapt the techniques and ideas to my problem. This forced me to really understand what made these techniques work, which often involved learning a bunch of stuff I wouldn’t have if I just read through it to see the results.

Before moving on, I’d like to add that upon completion of a Ph.D. you know pretty much nothing outside of your sub-sub-(sub-sub-sub)-field. It will take many years of continued teaching and researching and reading and publishing and talking to people to get any sense of your actual sub-field.

Are there people who complete the equivalent of the three listed phases without an actual degree?

I’ll start with the more controversial example of Gary Taubes. He got a physics undergrad degree and a masters in aerospace engineering. He then went into science journalism. He stumbled upon how complicated and shoddy the science of nutrition was, and started to research a book.

Five years later, he had read and analyzed pretty much every single nutrition study done. He interviewed six hundred doctors and researchers in the field. If this isn’t Phase 2 of a Ph.D., I don’t know what is. Most students won’t have gone this in-depth to learn the state of the field in an actual Ph.D. program.

Based on all of this, he then wrote a meticulously cited book Good Calories, Bad Calories. The bibliography is over 60 pages long. If this isn’t Phase 3 of a Ph.D., I don’t know what is. He’s continued to stay abreast of studies and has done at least one of his own in the past ten years. He certainly has more knowledge of the field than any fresh Ph.D.

Now you can disagree with his conclusions all you want. They are quite controversial (but lots of Ph.D. theses have controversial conclusions; this is partially how knowledge advances). Go find any place on the internet with a comments section that has run something about him and you’ll find people who write him off because “he got a physics degree so he’s not an expert on nutrition.” Are we really supposed to ignore 20 years of work done by a person just because it wasn’t done at a University and the previous 4 years of their life they got an unrelated degree? It’s a very bizarre sentiment.

A less controversial example is Dan Carlin. Listen to any one of his Hardcore History podcasts. He loves history, so he obsessively reads about it. Those podcasts are each an example of completing Phase 3 of the Ph.D. And he also clearly knows the literature as he constantly references hundreds of pieces of research an episode off the top of his head. What is a historian? Supposedly it’s someone who has a Ph.D. in history. But Dan has completed all the same Phases, it just wasn’t at a university.

(I say this is less controversial, because I think pretty much everyone considers Dan an expert on the topics he discusses except for himself. It’s a stunning display of humility. Those podcasts are the definition of having expertise on a subject.)

As a concluding remark/warning. There are a lot of cranks out there who try to pass themselves off as experts who really aren’t. It’s not easy to tell for most people, and so it’s definitely best to err on the side of the degree that went through the gatekeeper of a university when you’re not sure.

But also remember that Ph.D.’s are human too. There’s plenty of people like Person A in the example above. You can’t just believe a book someone wrote because that degree is listed after their name. They might have made honest mistakes. They might be conning you. Or, more likely, they might not have a good grasp on the current state of knowledge of the field they’re writing about.

What is an expert? To me, it is someone who has dedicated themselves with enough seriousness and professionalism to get through the phases listed above. This mostly happens with degree programs, but it also happens a lot in the real world, often because someone moves into a new career.

On Switching to Colemak

There’s this thing many people will probably go their whole lives and never know about. A ton of alternative keyboard layouts exist other than the default “QWERTY” (named for the letters along the top row of the keyboard). There is a subculture obsessed with this.

The two most common ones are Dvorak and Colemak. Last Saturday I started learning where the letters on Colemak are located. By the end of Sunday, I had them memorized. This meant I could type very slowly (3-5 wpm) with near perfect accuracy.

It didn’t take long to learn at all. Now, a few days later, I no longer have to think about where the letters are, but it will probably be another week or so before I get back to full speed.

Let’s talk about the burning question in everyone’s mind: why would anyone subject themselves to such an experience? I type a lot. For the past year or so I’ve experienced some mild pain in my wrists. I’ve never had it diagnosed to know if it is repetitive strain injury, but my guess is it’s a bad sign if you experience any pain, no matter how small.

I tried to alleviate some stress by tilting my keyboard and giving my wrists something to rest on:

imag0482

[Yes, that’s Aristotle’s Poetics under the front of the keyboard.]

This helped a little, but the more I looked it up, the more I realized there was a fundamental issue with the keyboard layout that could be part of the problem. Most people probably think the layout has a purpose because of how strange it is. But we’ve outgrown that purpose.

The history of this is long and somewhat interesting, but it basically boils down to making sure hands alternate and common digraphs (two-letter combinations) have large distances separating them, so that when typing quickly on a mechanical typewriter it will be least likely to jam.

If one were to design a keyboard to minimize injury, one would put the most common letters on the home row, minimize long stretches, and make sure common digraphs use different but nearby fingers. This is almost exactly the philosophy of the Colemak layout.

The Colemak layout allows you to type around 34 times the number of words on the home row than QWERTY. It’s sort of insane that “j” is on the home row and “e” and “i” are not for QWERTY. Colemak also distributes workload more evenly. It favors the right hand slightly more at 6%, unlike the massive favoring of the right hand for QWERTY at 15%. You can go look up the stats if you want to know more. I won’t bore you by listing them here.

You will definitely lose a lot of work time while making the change due to slow typing, but the layout is provably more efficient. So in the long run you’ll end up more than compensated for these short-term losses.

I’d like to end by reflecting on what a surreal experience this has been. I think I first started learning to type around the age of eight. I’m now thirty. That’s twenty-two years of constant ingraining of certain actions that had to be undone. Typing has to be subconscious to be effective. We don’t even think about letters or spelling when doing it. Most words are just patterns that roll off the fingers.

This is made explicitly obvious when I get going at a reasonable speed. I can type in Colemak without confusion letter-by-letter, but I still slip up when my speed hits that critical point where I think whole words at a time. At that point, a few words of nonsense happen before I slide back into correct words. It’s very strange, because I don’t even notice it until I look back and see that it happened.

I’ve never become fluent in another language, but I imagine a similar thing must happen when one is right on the edge of being able to think in the new language. You can speak fluently, but occasionally the subconscious brain takes over for a word, even if you know the word.

If you’re at all interested, I’d recommend checking into it. I already feel a huge difference in comfort level.

Should Roguelikes be Winnable?

A topic that I’ve been thinking about recently has to do with balancing roguelikes. If you haven’t heard the term balance before, it basically refers to making a game fair through adjusting values: enemy health, enemy strength, items you find, your health, your strength, and so on.

For a normal RPG, you balance a game so that a skilled player can win and so nothing feels unfair. An example of something an RPG fan might find unfair is an “out of depth” enemy that instantly and unavoidably kills you (this happens in many roguelikes).

Many developers and players think this is bad game design because the player couldn’t do anything about it. Why bother getting good at a game if you will just lose to unpredictable circumstances? The game cheated you somehow, and many players quit various roguelikes before getting better for exactly this reason.

This post isn’t so much on actual balance as it is on two distinct philosophies on the winnability of a roguelike. This is a design choice that must be thought about carefully in roguelike design, and it doesn’t even come up for other types of games.

The question: Should a skilled player be able to win?

Most modern game designers would laugh at this question. Their games are designed so that you don’t even need skill to win. Winning is the default position. Your hand will be held through the process. Checkpoints are made every step of the way so you can try something again if you mess it up.

This might be surprising to people not immersed in the genre, but many classic roguelike games have a steep enough skill hurdle that probably less than 10% who ever play will get a win (maybe even as low as 1%). Sometimes it can take years of playing a game to get good enough at it to win. But the game is balanced such that a really skilled player can win almost every time.

Think about that for a second. This is quite a feat. Here’s an analogy which isn’t perfect: think about running a 5 minute mile. Almost no runner (even ones that train very, very hard) achieves this. But once they do, they can reproduce it many times. This is what makes roguelikes great. The focus is on player skill and progression not on character progression. You get a sense of real accomplishment.

After I wrote this post, I did a search for the topic and found it discussed at the Brogue forums. It seems there isn’t an easy way to even define “winnable.” I’ll give you my definition in a bit, but I want to dispel the obvious one as not being a good one.

We already have to distinguish between the game being winnable and the winnability of a given seed (industry term for a particular playthrough). This is only weird for roguelikes, because the game is different every time you play.

One might try to define a game as winnable if approximately 100% of the seeds can be won with “perfect play.” But using perfect play is problematic in a roguelike because of the randomness. Perfect play means you play in a way that perfectly maximizes your chance of winning.

It isn’t hard to think of situations in which sub-optimal play will randomly luck into a win and optimal play loses the seed (e.g. you need magic reflection, so you check Sokoban, but encounter an enemy with a wand of death that kills you, but the unskilled player doesn’t check Sokoban and goes on to win).

This is kind of funny, because now we have a problem with defining winnable even for a seed. Should it mean: someone somewhere won the seed? This, too, seems problematic. I’ll try to explain why from the commentary at the Brogue forum discussion. One person claimed that at least 80% of Brogue seeds are winnable based on the fact that people got wins on around 80 of the last 100 weekend challenge competitions (not the same person).

Let’s digress to make the problem with the above analysis clear. Suppose we make a game. Flip a coin. If it is heads you win and tails you lose. Under the perfect play definition, the game is not winnable. In other words, perfect play does not guarantee a win. Under the definition that some person somewhere was able to win, it is winnable.

Here’s where things get interesting. If we think about what percentage of seeds can be won, we better find out that the answer is 50%, because this is our expected percentage of games a player that plays perfectly would win. But in the above Brogue analysis, the commenter takes a pool of players and asks if any of them has won. This should greatly inflate the win percentage, because it is like taking 5 coins and flipping them all at the same time and seeing if any were wins.

To get around this subtlety, I’ll call a game winnable if a single skilled player can get a win streak of say 10 or so. A good example of this is NetHack. The vast majority of people who play will never get a win ever. But Adeon has a win streak of 29, and many people have streaks of 10. This proves that it is a game that can be won basically every time (and many consider it so easy they self-impose crazy challenges and still win).

Other famous roguelikes that have this same philosophy are Tales of Maj’Eyal (on normal/adventure at least) or from the “roguelite” genre The Binding of Isaac (where people have 150+ win streaks).

At this point you’re probably thinking, what other philosophy could there be? No one could possibly want to play a game for which you work really hard for 1,000 hours learning to make all the best moves, and yet the design will still have you lose to random impossible scenarios. It wouldn’t be fun. It would be pure frustration.

But people do this all the time in other types of games. The best example I can think of is poker. It takes a huge number of hours of training to become good enough to make roughly the best plays. You can be the best in the world and still lose due to the inherent randomness. You can only see how good someone is through long-term averages.

One way to think of this philosophy is: losing is fun, winning is more fun, winning every time is too easy and boring. Traditional roguelikes are fun, because you get in seemingly impossible situations but with enough skill you can think your way out. You can have a lot of confidence that you will basically never be randomly put in an impossible situation. Losing is your own fault, and you can get better from it.

If you take this alternate philosophy, the fun comes from the fact that you don’t know if a given situation is impossible. Maybe you just weren’t good enough. Balancing so that there are impossible situations makes it so that the top of the skill curve can still feel challenged.

I think the biggest difficulty with balancing in this manner is that a highly skilled player may never reach a 10 streak, but they should probably still be able to win something like 6 or 7 of those 10 games. This would be a very difficult balance to achieve. It is much easier to make it winnable.

Roguelikes already have a very small market. Part of what keeps people interested is that when they lose, it is their own fault. They don’t feel cheated. A game that was upfront about containing a large number of impossible seeds would probably narrow the market even more. One way to mitigate the pain would be for the game to keep track of your monthly win percent. That way you can track your progress.

I haven’t heard of this before. I’d be curious if anyone knows of any roguelikes that fit this design philosophy. The two that come to mind are Sword of the Stars: The Pit and Brogue. Both feel like you can just not find the items necessary to get a run off the ground. But I’m not very good at either, so it could be player error. There are people with about 2500 hours of play in The Pit, so I’d be curious to see if they could get a 5 streak on Normal mode (most refuse to play that difficulty since they’ve won on much harder).

Basic Game Programming Part 3

Here’s an experiment to try purely in C++ (or the language of your choice). Print any character you want on a blank terminal screen at a specific location (say 10 characters over and on the 4th line). This is a crucial idea in game programming, because even something as simple as using the arrow keys to move something around a screen requires you to do this.

You’ll find it gets tedious quickly. Let me guess what you came up with. You have two auxiliary functions. One of them prints “\n” an appropriate number of times to move you to the correct line. The other prints a bunch of ” ” to move you over. It works.

Now suppose you want more information on the screen like health remaining or an inventory list. You can’t use that method anymore, because it depends on where the cursor ended during the last thing you drew. This, in turn, depends on information that could be changing (Health: 9 vs Health: 10 places the cursor one more space over).

Matters get even worse if you want to draw something on the right edge of the screen, because you have no idea what the player is looking at. One could use a standard terminal size, another could have maximized it to fullscreen. This changes the number of spaces on a line.

Until you actually try to do these things, or at least seriously attempt a thought-experiment doing it, you will never appreciate why adding an external library to handle this stuff is important. There are tons of these in existence, but probably the most common and universal ones are built from SDL (we will definitely not get into that today).

The simplest for C++ is probably ncurses. It stands for “new curses” and has a pretty interesting history (the name implies there was a curses). It effectively emulates a terminal, which sounds ridiculous at first (why not just use the terminal!) until you think through all the problems above. Today, we’ll make an “@” symbol move around the screen using the arrow keys.

For our purposes, the two most useful functions in the library will be clear() and mvaddch(). As we saw last time, clear() was annoying because it was OS and terminal dependent. Since ncurses emulates a terminal, there is one function that clears the screen independent of OS. The function mvaddch takes 3 arguments, the first two are ints and give the y-coordinate and x-coordinate where you want to place a character, and the third argument is a character that gets placed in that location.

Even though I want to think in terms of x and y coordinates, mvaddch actually takes the row then the column number. This means you put in y first and x second and the y-coordinate counts down from the top of the screen which can be confusing to new users of ncurses.

At this point, we understand the structure of the game loop, so you should basically be able to fill in the rest of the program. There are quite a few subtleties, though, so I’ll go slowly through it.

The only variables I need this time are the x-coordinate and y-coordinate, so I’ll make these global. I started it at (5,5) randomly. We get input using getch(). This returns an integer, but we don’t need to worry about what that integer is. Since we are using the arrow keys we can use KEY_UP, KEY_DOWN, etc which are integers corresponding to the correct arrow directions. Also, using integers is nice rather than characters, because in C++ we can more cleanly write a bunch of “else if” statements with a “switch.”

This lets us make the whole Update() function by changing the x and y coordinates depending on which arrow direction was pressed.

void Update() {
	switch(userInput) {
		case KEY_LEFT:
			XPOS = XPOS - 1;
			break;
		case KEY_RIGHT:
			XPOS = XPOS + 1;
			break;
		case KEY_UP:
			YPOS = YPOS - 1;
			break;
		case KEY_DOWN:
			YPOS = YPOS + 1;
			break;
	}
}

As before, our draw function clears the whole screen and then draws everything. Because of how ncurses works, nothing will be drawn to the terminal until refresh() is called. This is basically so you can store a whole bunch information about what is going to be displayed, and then it can work out how to display it separately:

void Draw() {
	clear();
	mvaddch(YPOS, XPOS, PLAYER);
	refresh();
}

The only thing left is to initialize a bunch of stuff, but the content of the program is really that simple. I commented the initialization lines so you can see what they do, but for the most part, you’ll just copy and paste that whole chunk in every use of ncurses.

#include <ncurses.h>

int XPOS = 5;
int YPOS = 5;
char PLAYER = '@';
int userInput;

void Update() {
	switch(userInput) {
		case KEY_LEFT:
			XPOS = XPOS - 1;
			break;
		case KEY_RIGHT:
			XPOS = XPOS + 1;
			break;
		case KEY_UP:
			YPOS = YPOS - 1;
			break;
		case KEY_DOWN:
			YPOS = YPOS + 1;
			break;
	}
}

void Draw() {
	clear();
	mvaddch(YPOS, XPOS, PLAYER);
	refresh();
}

int main() {

	//Initialize ncurses

	initscr(); //Tells it to make a terminal screen.
  	clear();   //Clears the screen.
  	noecho();  //When user types input, it doesn't appear on the screen.
  	cbreak();  //Typed character is immediately available.
  	keypad(stdscr, TRUE);  //Standard screen.
  	curs_set(0);  //Starts the cursor at (0,0).
  	mvaddch(YPOS, XPOS, PLAYER); //Draw '@' in the initial location.
  	refresh();  //Updates the screen to display the '@'.

	while(true) {

		//Input()
		userInput = getch();

		Update();
		Draw();

		if (userInput == 'q') {
			break;
		}
	}

	endwin();  //Closes the terminal screen.

	return 0;
}

This will probably be the last post in this series. I have one more topic I could do (decoupling the draw loop from the game logic loop). For the most part, you should now be in a position to look up tutorials on using fancier stuff like Unity or Monogame.

The problem I found with those tutorials is that they focus solely on how to use their engine and not on what these underlying components of the engine are (and why they exist). Hopefully after these posts, these concepts make more sense allowing you to more easily jump in.

(For the record, these posts keep getting the C# tag even though I type C++. It autocorrects it upon hitting the publish button.)

Basic Game Programming Part 2

So here’s a video of the finished product for today. If you haven’t read the last post, you should do that and try the exercises. Better yet, watch the finished product and try to create it without reading the excercises:

We’ll go through all the changes I made, but we’ll start with the most important one. Last week I gave the suggestion “Feature 6: Figure out where to clear the screen to not be so cluttered.” This is a crucial concept in drawing the graphics when making a game.

This toy example gives us the fundamental idea, but if you actually try it in C++, you’ll find it somewhat difficult. I used Linux, so I could use system(“clear”) to clear the terminal screen. You’ll need different commands depending on the operating system. Fighting with drawing things in the proper place will give you a huge appreciation for tools that aid in doing this (we’ll talk about one next week called “ncurses”).

If you watch the video, I programmed it to give the illusion that certain things were static on the screen and don’t get redrawn. In reality, on every iteration of the game loop, I cleared the entire screen and redrew the whole screen with the updated information. This makes it look like “Your Health:” stays the same while the number clicks down as you lose health.

You obviously don’t have to do it this way, but experience has taught me you can get some nasty display bugs if you don’t fully clear and redraw. As I said before, this merely amounted to adding a simple system(“clear”) at the beginning of the Draw() function. I also added a few lines of information.

void Draw() {
  system("clear");
  cout << "Your Health: " << PLYRHLTH << "\n";
  cout << "Enemy Health: " << ENMYHLTH << "\n";
  cout << "a. Attack \n";
  cout << "b. Run \n";
  cout << PLYRDMG;
  cout << ENMYDMG;
}

The other major change was to rescope the variables (you might have noticed they changed names and are all caps, my convention for global variables). Since I wanted many of the functions to be able to access and change the PlayerHealth, EnemyHealth, and so on, I made them all global. This also cleaned up having to pass all of them to each function and allowed me to refactor Update() into its own function.

At the top of the program I list them and initialize them. PLYRDMG is the message “You hit for 2 damage” and so on (see Draw() and compare to the video). It is initialized to be blank so everything writes in the same place:

int PLYRHLTH = 10;
int ENMYHLTH = 10;
string PLYRDMG = "\n";
string ENMYDMG = "\n";

The only thing that changed in the Update() function is an added if statement in a few places so that half the time you miss and half the time the enemy misses. I also had to come up with a way tell the game loop whether the player chose to “Run” and exit the game. This was easy before, because we could write if (PlayerInput == “b”) { break; } to break out of the game loop.

Now the function isn’t in the game loop, so calling “break;” doesn’t work. The way around this was something people came up with in Operating Systems programming a long time ago. I made Update() return an integer rather than be a void. This way I could always return 0 if the player wanted it to keep going. Otherwise it returns 1 and I know they want to break out of the game. This why in C and C++ main() is an int rather than a void. Returning 0 tells the OS that everything went well in the execution of the program.

int Update(string playerinput) {
  if (playerinput == "a") {
    if (rand() % 2 == 0) {
      int r1 = rand() % 4;
      ENMYHLTH -= r1;
      stringstream ss;
      ss << "You hit for " << r1 << " damage.\n";
      PLYRDMG = ss.str();
    } else {
      PLYRDMG = "You miss.\n";
    }
  }

  else if (playerinput == "b") {
    return 1;
  }

  else {
    PLYRDMG = "This is not a valid option.\n";
  }

  //Enemy attacks.
  if (rand() %2 == 0) {
    int r2 = rand() % 4;
    PLYRHLTH -= r2;
    stringstream ss;
    ss << "Enemy hits for " << r2 << " damage.\n";
    ENMYDMG = ss.str();
  } else {
    ENMYDMG = "Enemy Misses!\n";
  }

  return 0;
}

Lastly, I added a “Start Screen” to get into the game. I return to this when the game ends and ask if the player wants to play again. This was done simply by putting the whole game in a second while loop. As long as the player keeps entering “y” for “do you want to play” I keep the boolean variable WantToPlay = true. Otherwise I switch it to false and the game ends. This is also something a prebuilt engine will do for you in a much more elegant way.

Here’s the whole thing:

#include <iostream>
#include <sstream>
#include <stdlib.h>

using namespace std;

int PLYRHLTH = 10;
int ENMYHLTH = 10;
string PLYRDMG = "\n";
string ENMYDMG = "\n";

void ResetVariables() {
  PLYRHLTH = 10;
  ENMYHLTH = 10;
  PLYRDMG = "\n";
  ENMYDMG = "\n";
}

void Draw() {
  system("clear");
  cout << "Your Health: " << PLYRHLTH << "\n";
  cout << "Enemy Health: " << ENMYHLTH << "\n";
  cout << "a. Attack \n";
  cout << "b. Run \n";
  cout << PLYRDMG;
  cout << ENMYDMG;
}

string Input() {
  string tmp;
  cin >> tmp;
  return tmp;
}

int Update(string playerinput) {
  if (playerinput == "a") {
    if (rand() % 2 == 0) {
      int r1 = rand() % 4;
      ENMYHLTH -= r1;
      stringstream ss;
      ss << "You hit for " << r1 << " damage.\n";
      PLYRDMG = ss.str();
    } else {
      PLYRDMG = "You miss.\n";
    }
  }

  else if (playerinput == "b") {
    return 1;
  }

  else {
    PLYRDMG = "This is not a valid option.\n";
  }

  //Enemy attacks.
  if (rand() %2 == 0) {
    int r2 = rand() % 4;
    PLYRHLTH -= r2;
    stringstream ss;
    ss << "Enemy hits for " << r2 << " damage.\n";
    ENMYDMG = ss.str();
  } else {
    ENMYDMG = "Enemy Misses!\n";
  }

  return 0;
}

int main() {
  int State;
  string PlayerInput;
  bool WantToPlay = true;

  while(WantToPlay) {

    //Reset the Initial Information
    ResetVariables();
    srand(time(NULL));
    system("clear");
    cout << "An enemy approaches. Do you fight (y/n)?\n";
    PlayerInput = Input();
    if (PlayerInput == "n") {
      WantToPlay = false;
    }
    Draw();

    //Game Loop
    while(true) {

      PlayerInput = Input();
      State = Update(PlayerInput);

      if (State == 1)
        break;

      //Break out of the game looop if won or lost.
      if (ENMYHLTH <= 0) {
        system("clear");
        cout << "You Win.\n";
        break;
      }
      else if (PLYRHLTH <= 0) {
        system("clear");
        cout << "You Lose.\n";
        break;
      }

      Draw();
    }

    cout << "Game Over.\n";
    cout << "Want to play again (y/n)?\n";
    PlayerInput = Input();
    if (PlayerInput == "n") {
      WantToPlay = false;
    }
  }

  return 0;
}

Next time we’ll work on improving the graphics by using outside tools and getting something moving around the screen so it feels more game-like.

Basic Game Programming Part 1

A lot of people think the best way to get young people into programming is through making games. I agree. Unfortunately, it is kind of hard to find the basics, so I want to do a series on it (Pygame is your best bet for a tutorial, but I’ve personally had bad experiences with it). This is definitely not meant to be some comprehensive tutorial. It is only meant to introduce some basic ideas.

There’s a lot of tools out there to make this easy (RPG Maker comes to mind). These tools allow you to make a fairly complicated and polished game without having any idea about how it is coded. Drag and drop images on a screen, and voila, a game is born. This defeats the whole point!

Other tools like game engines (Pygame, Unreal Engine, Unity, Monogame, Cocos, etc) are important to not have to deal with complicated graphics rendering or other hassles. These should be used in real life. For the purpose of this series, we will look at rudimentary simplifications of some of the things going on underneath these engines.

I will not assume you are comfortable with programming, but I also won’t explain the code much. I’ll assume you can look at the code and are able to figure out with some prompting what it does. The most important part of learning to program is learning the ability to look things up.

I’m going to use C++ even though I know most people learn Python or Java these days as their first language. But if you want to write cross-platform games, you’ll want to use C++ (Cocos) or C# (Unity and Monogame) or whatever Unreal uses. If you want a refresher, this game will only use cin, cout, variables, if/else. This should take less than 2 hours to learn from a reasonable tutorial.

If you have a little programming experience, there is a fundamental concept you’ll have to get used to called the game loop. It essentially looks like this:

while(true) {
    //Insert entire game here.
}

The game will infinitely loop through the instructions. For most simple games, this is overkill and uses a ton of unnecessary processing power. Also, without a professional game engine underneath, you don’t have a way to limit the speed at which it loops (30 times per second or 60 times per second). Don’t worry about any of this. Just know that you will eventually want this constant loop, so it is good to get used to it.

Let’s add a touch more detail now. The game loop roughly consists of three parts: Getting input from the player, Updating the game state based on that input, and Drawing to the screen whatever has changed from the update step. This is called the engine, because it keeps churning and puts the game in motion. If you use Unity or some pre-built engine, each of these parts will exist already (and will loop independently in parallel, but that is for another time).

Our game now looks like this:

while(true) {
   GetInput();
   Update();
   Draw();
}

Again, this is needlessly complicated for the game we will make, but it is worth getting used to this flow with something basic so you aren’t learning a whole new framework with something more complicated.

Now let’s describe the game. The game will display your health and the enemy’s health. The player will have 2 choices: Attack or Run. If you attack, you hit the enemy, in which case the enemy’s health decreases by some amount (we’ll make it random between 0 and 3). If you run, you leave the game (effectively a “quit” choice). The enemy always hits you.

If the enemy’s health reaches 0, the player wins. If the player’s health reaches 0, the player loses.

A part of the engine I didn’t describe is the initialization that come before entering the game loop. In this case, we might want to describe the setup and get the initial variables set up and call the Draw() function to get something on the screen.

There will be 2 variables: PlayerHealth and EnemyHealth. Let’s set them both to 10 to start. At this point I think we can write the first form of the Draw() function, which right now will just print out and label these variables and give the two options for action. Eventually, we’ll probably want to say who got hit, too.

void Draw(int playerhealth, int enemyhealth) {
  cout << "Your Health: " << playerhealth << "\n";
  cout << "Enemy Health: " << enemyhealth << "\n";
  cout << "a. Attack \n";
  cout << "b. Run \n";
}

This might look a bit confusing, but “cout” just means “print to the screen.” So each line of that is printing “Your Health: 10” (and the \n means “new line”).

Now let’s get the input. We’ll do something a little bad, but we’re just trying to get the flow down here. We’ll worry about “good coding practices” some other time. Let’s make the function Input() return the string the user inputs, so we can store it rather than modifying some global variable.

string Input() {
  string tmp;
  cin >> tmp;
  return tmp;
}

Again, “cin” just asks for the player input. The input is stored in the variable “tmp” and then gets returned.

The most complicated part of this is going to be the Update() function, but it isn’t so bad. Update() needs to say: if the player typed “a” we subtract the attack amount from EnemyHealth. If the player typed “b” we exit the loop. If anything else was typed, we don’t do anything and notify them it is not an option.

if (PlayerInput == "a") {
      int r1 = rand() % 4;
      EnemyHealth -= r1;
    }
    else if (PlayerInput == "b") {
      break;
    }
    else {
      cout << "This is not a valid option.\n";
    }

I used here a random number between 0 and 3 (inclusive) for how much damage the attack does. (Look up rand() for how it works. It is part of the standard library.) There isn’t much left, so I’ll give the whole thing now with some comments:

#include <iostream>
#include <stdlib.h>

using namespace std;

void Draw(int playerhealth, int enemyhealth) {
  cout << "Your Health: " << playerhealth << "\n";
  cout << "Enemy Health: " << enemyhealth << "\n";
  cout << "a. Attack \n";
  cout << "b. Run \n";
}

string Input() {
  string tmp;
  cin >> tmp;
  return tmp;
}

int main() {
  //Initialize the variables
  int PlayerHealth = 10;
  int EnemyHealth = 10;
  string PlayerInput;

  //Initial Information Drawn
  cout << "An enemy approaches... \n";
  Draw(PlayerHealth, EnemyHealth);

  //Game Loop
  while(true) {
    PlayerInput = Input();

    //Update Information based on input.
    if (PlayerInput == "a") {
      int r1 = rand() % 4;
      EnemyHealth -= r1;
    }
    else if (PlayerInput == "b") {
      break;
    }
    else {
      cout << "This is not a valid option.\n";
    }

    //Enemy attacks.
    int r2 = rand() % 4;
    PlayerHealth -= r2;

    //Break out of the game looop if won or lost.
    if (EnemyHealth <= 0) {
      cout << "You Win.\n";
      break;
    }
    else if (PlayerHealth <= 0) {
      cout << "You Lose.\n";
      break;
    }

    //Print out the Updated Info
    Draw(PlayerHealth, EnemyHealth);
  }

  cout << "Game Over.\n";

  return 0;
}

Here’s some features to add as homework. Now that the core is there, if you think of one thing and add it each day (15 minutes tops?), in 2 weeks you’ll have a pretty interesting and complicated text-based game. They don’t have to be these or even in this order. These are what popped into my head.

Excercise 0: Try cleaning up the current code so that Update() is its own function like Input() and Draw(). Don’t try too hard, because it is more complicated than it’s worth. You will encounter your first struggle with how to scope variables that all your functions want to know about. Also, breaking out of the while loop will become tricky.

Feature 1: Look up how to do random numbers. Make it so that you only hit the enemy 50% (or whatever you want) of the time. Make it so the enemy only hits you sometimes. This might be a 2 day feature if you are totally new to programming in C++.

Feature 2: Tell the Player that they hit the enemy and how much damage they did.

Feature 3: Make a “Title Screen” that tells you the game you are about to play.

Feature 4: Add some backstory to the introductory text.

Feature 5: Add more options for player input (different types of attacks that do different damage amounts).

Feature 6: Figure out where to clear the screen to not be so cluttered.

Feature 7: Ask if the player wants to play again rather than automatically closing the program when it is over.

That’s a whole week’s worth of exercises, and you’ll have a basic working game at the end. Next week, I’ll go through implementing these changes and maybe make a quick video to show that end result can look like a real-life, old-school text game.

Lossless Compression by Example Part 2: Huffman Coding

Last time we looked at some reasons why lossy compression is considered bad for music, and we looked at one possible quick and dirty way to compress. This time we’ll introduce the concept of lossless compression.

I’ll first point out that even if this seems like a paradoxical notion, everyone already believes it can be done. We use it all the time when we compress files on our computers by zipping them. Of course, this results in a smaller file, but no one thinks when they unzip they will have lost information. This means that there must exist ways to do lossless compression.

Today’s example is a really simple and brilliant way of doing it. It will have nothing to do with music for now, but don’t think of this as merely a toy example. Huffman coding is actually used as a step in mp3 encoding, so it relates to what we’ve been discussing.

Here’s the general idea. Suppose you want to encode (into binary) text in the most naive way possible. You assign A to 0, B to 1, C to 10, D to 11, etc. When you get to Z you’ll have 11001. This means that you have to use 5 bits for every single letter. “CAT” would be 00010 00000 10011.

To encode “CAT” we did something dumb. We only needed 3 letters, so if we had chosen ahead of time a better encoding method, maybe C = 00, A = 01, T = 10, then we could encode the text as 00 01 10. In other words, we compress our data without losing any information by a clever choice of encoding 00010 00000 10011 -> 000110.

I know your complaint already. Any sufficiently long text will contain every letter, so there is no way to do better than that original naive method. Well, you’re just not being clever enough!

Some letters will occur with more frequency than others. So if, for example, the letter “s” occurs with frequency 100 and then the next most frequent letter occurs 25 times, you will want to choose something like “01” for “s”. That way the smallest number of bits is used for the most frequent letters.

Ah, but the astute reader complains again. The reason we couldn’t do this before is because we won’t be able to tell the difference in a long string between two frequent letters: 10 01, and a single less-frequent letter: 1001. This was why we needed all 5 bits when we used the whole alphabet.

This is a uniqueness problem. What we do is not allow “01” to be a prefix on an assigned string once we’ve assigned it. This way, when we encounter 01, we stop. We know that is the letter “s” because no other letter begins “01”.

Of course, what ends up happening is that we have to go to much more than 5 bits for some letters, but the idea is that they will be used with such infrequency and the 2 and 3 bit letters used with such high frequency that it ends up saving way more space than if we stuck to 5.

Now you should be asking two questions: Is it provably smaller and is there some simple algorithm to figure out how to assign a letter to a bit sequence so that the uniqueness and smallness happens? Yes to both!

We won’t talk about proofs, since this is a series “by example.” But I think the algorithm to generate the symbol strings to encode is pretty neat.

Let’s generate the Huffman tree for “Titter Twitter Top” (just to get something with high frequency and several “repeat” frequencies).

First, make an ordered list of the letters and their frequencies: (T:7), (I:2), (E:2), (R:2), (W:1), (O:1), (P:1).

Now we will construct a binary tree with these as leaves. Start with the bottom 2 as leaves and connect them to a parent with a placeholder (*) and the sum of the frequencies. Then insert this new placeholder into the correct place on the list and remove the two you used:

Now repeat the process with the bottom two on the list (if a node is on the list already, use it in the tree):

Keep repeating this process until you’ve exhausted the list and you will get the full binary tree we will use:

Now to work out how to encode each letter, write a 0 on every left edge and a 1 on every right edge. Descend from the top to the letter you want and write the digits in order. This is the encoding. So T = 1, I = 000, R = 010, E = 011, W = 0011, O = 00101, and P = 00100. Test it out for yourself. You will find there is no ambiguity because each string of digits used for a letter never appears as a prefix of another letter.

Also, note that the letter that occurs with the highest frequency is a single bit, and the bits needed gets longer only as the frequency gets less. The encoding for Titter Twitter Top with this Huffman code is 39 bits whereas the naive encoding is 80. This compresses to half the space needed and loses no information!

We won’t get into the tedious details of how computers actually store information to see that there are lots of subtleties we’ve ignored for executing this in practice (plus we have to store the conversion table as part of the data), but at least we’ve seen an example of lossless compression in theory. Also, there was nothing special about letters here. We could do this with basically any information (for example frequencies in a sound file).

Lossless Compression by Example Part 1: Lossy Methods

Since I’m into music, it often comes up there is a growing trend: music is sold digitally and as vinyl. Sometimes I’ll hear people mistakenly call the vinyl trend “retro” or “trendy” or “hip” or whatever. But if you actually ask someone why they prefer records, they’ll probably tell you the sound quality is better.

I thought I’d do a series on lossless compression and try to keep everything to general concepts or example. Let’s start with the terminology. First, media files can be large, and back in the day when computers didn’t have basically infinite space, compression was an important tool for reducing the size of a media file.

Compression is basically an algorithm to take the size of a file and makes it smaller. The most obvious method for doing this is lossy compression. This just means you lose information. The goal of such an algorithm is to only lose information that is “unimportant” and “won’t be noticed.”

A far more surprising method of compression is called lossless. At first it seems paradoxical. How can you make the file size smaller, but not lose any information? Isn’t the file size basically the information? We won’t get to this in this post. Teaser for next time!

Now lets talk about why people don’t like lossy compressed audio files. There is one quick and dirty thing you can do to immediately lose information and reduce the size of an audio file. This is dynamic range (DR) compression.

Think of a soundwave. The amplitude basically determines how loud it is. You can literally compress the wave to have a smaller amplitude without changing any other musical qualities. But this is terrible! One of the most important parts of music is the DR. A moving, soaring climax will not have the same effect if the entire build up to it is the same loudness.

This is such a controversial compression technique that many people switch to vinyl purely for DR reasons. There is a whole, searchable online database of albums to find out the DR and whether it is consider good, acceptable, or bad. Go search for your favorite albums. It is kind of fun to find out how much has been squashed out even in lossless CD format vs vinyl! (e.g. System of a Down’s Toxity is DR 11 [acceptable] on vinyl and DR 6 [truly bad] on lossless CD).

The other most common lossy compression technique for audio is a bit more involved, but it actually changes the music, so it is worth thinking about. Let’s actually make a rough algorithm for doing this (there currently exist much better and subtler forms of the following, but it amounts to the same thing).

This is a bit of a silly example, but I went to http://www.wavsource.com to get a raw wav file to work with. I grabbed one of the first ones, an audio sample from the movie 2001: A Space Odyssey. Here is the data visualization of the sound waves and the actual clip:

daisy

Daisy

One thing we can do is the Fast Fourier Transform. This will take these sound waves and get rid of the time component. Normally you’ll want to make a “moving window,” so you keep track of some time. For example, we can see that from 0.5 sec to 1.5 sec is one “packet.” We should probably transform that first, then move to the next.

The FFT leaves us just with the frequencies that occur and how loud they are. I did this with python’s scypy.fftpack:

import matplotlib.pyplot as plt
import scipy.fftpack as sfft
import numpy as np
from scipy.io import wavfile

fs, data = wavfile.read('daisy.wav')
b=[(ele/2**8.)*2-1 for ele in data]
c = sfft.fft(b)
d = len(c)/2
plt.plot(abs(c[:(d-1)]),'r')
plt.show()

compressed = []
for ele in c:
	if abs(ele) > 50:
		compressed.append(ele)
	else:
		compressed.append(0)

compressed = np.asarray(compressed)
plt.plot(abs(compressed[:(d-1)]),'r')
plt.show()

e = sfft.ifft(compressed)

daisyfreq

Ignore the scales which were changed just to make everything more visible but not normalized. The most crude thing we could do is set a cutoff and just remove all frequencies that we assume will be inaudible anyway:

daisyfreqcompressed

If we do this too much, we are going to destroy how natural the sound is. As I’ve explained before, all sounds occurring naturally have tons of subtle overtones. You often can’t explicitly hear these, so they will occur below the cutoff threshold. This will bring us towards a “pure” tone which will sound more synthetic or computer generated. This is probably why no one actually compresses this way. This example was just to give an idea of one way it could be done (to finish it off you can now just inverse FFT and write to wav).

A slightly better compression technique would be to take short time intervals and multiply the peak frequency by a bump function. This will shrink all the extraneous frequencies without completely removing the robustness of the sound. This is how some lossy compression is actually done. There are other more fun things with wavelets which would take several posts to describe and the goal is to get to lossless compression.

I hope that helps to see what lossy compression is, and that it can cause some serious harm when done without care. With care, you will still lose enough sound quality that many music aficionados avoid mp3 and digital downloads completely in favor of vinyl.

Next time we’ll tackle the seemingly paradoxical concept of lossless compression.

7DRL Takeaway Lessons

I promise this will be my last 7DRL post, but I thought I should record some thoughts I’ve had about it now that it is over.

This post could alternately be called “Why I Will Not Use MonoGame in the Foreseeable Future.”

First, the motto of MonoGame is “Write Once, Play Everywhere.” This sounded promising to me, because my first game had issues deploying almost anywhere. Of course, what they mean is that you can play anywhere supported by Windows.

There are ways to get builds onto other platforms so that Mac and Linux users can play, but I only had 7 days, and I’m not a trained computer scientist, so that wasn’t going to happen. This was a little frustrating, and also one Windows user already complained they couldn’t get it installed.

Second, MonoGame is effectively a re-implementation of XNA 4. Unfortunately, some of the pipelines (especially with an up to date Visual Studio) are broken and require hacks to work. This caused major problems with sound. So much so that I scratched all sound from the game.

I know that with enough time, I probably could have gotten this working (because lots of games made with it have sound), but I couldn’t waste the time in those 7 days to fight with it. This was frustrating, because one of the main reasons to use MonoGame was to make all of that streamlined and easy.

I also felt trapped into using Visual Studio as an IDE. This is certainly a fine IDE, but I’m most comfortable with Sublime Text 2. Switching editors wastes a lot of time, especially when you “downgrade.”

By this I mean VS doesn’t have half the great features of ST2 (including my most used feature: multiple cursors). In retrospect, I should have edited in ST2 and built in VS.

All this being said, MonoGame was a good enough framework to produce a full working game in 7 days, so I can’t complain too much. Also, if I were part of a larger team with a longer time frame, many of these issues would disappear. So I admit these complaints come specifically from the 7 day issue.

If I do this again, I will almost certainly try Cocos2d-x. It looks like this will fix all the complaints I had. First, Cocos2d-x is open source. This means I can actually see what the engine is doing if I need to! What a concept.

Second, it is C++, so it will deploy across platforms much easier. Lastly, it isn’t in some transition period like MonoGame where content management seems to use outdated, unsupported pipelines. I’m also more familiar with C++ than C# which would have solved a few headaches.