Mountainhome Endoktomus, “Atticshove”

Hey everybody,

I didn’t post about Dwarf Fortress earlier in the semester, but I’ve talked a couple times in class about my progress in the game. In what is surely a move to avoid working on my final project (and to make up for not posting earlier), I figured I’d show everybody a little bit of what I was able to accomplish. So…welcome to Mountainhome Endoktomus, better known as Atticshove!

First off, here’s a view of my fortress from above ground, using StoneSense to render it in three dimensions:

screenshot2

And yes, that’s a lot of vomit everywhere. But, it gives a nice view of the tower (11 z-levels tall), walls, and fortifications that I’ve built, as well as the road leading into my trading caravan entrance. That tower includes barracks and training grounds for my archers, who can then move along the parapets to shoot down at any attackers. Here’s a more conventional shot of the ground floor:

Ground

So, still lots of vomit. The Well (more on that later) and Statue Garden are all forged out of silver by my Legendary Metalsmith, so that’s pretty much what keeps everybody happy. As that “Idlers: 74” up top indicates, I’ve built up a pretty sizable population:

Status

I’m definitely not going to run out of money or food any time soon. And out of those 198 dwarves, I have 13 nobles, though some positions overlap:

Nobles

At a certain point in the game, you can meet the requirements to become the capital of your civilization, which brings with it your King. My biggest struggle lately has been trying to build quarters that are royal enough for him and his consort…

1

This level also shows my reservoir, which my Well draws from. I dug a channel to a river on the other side of the map so that I could have a source of water in my fortress while under siege. This was particularly important since I was digging in an area without any mud to farm in, so I needed to build an irrigation system to partially flood the ground to make mud. The next level down is just workshops:

2

I was planning at one point to expand my reservoir, but that project’s pretty well on hold. You can also see the continued drawbridge pit, which at some point I’ll hopefully get some poor sap stuck in. It bottoms out one more level down:

3

Lots of traps in case anybody drops down into the pit, plus my kitchen, butcher/fish cleaner, and dining hall. Next up, my metal industry:

4

And finally, the burial sites and mines:

5a

The next 11 levels down from this look pretty much the same: lots of mining, just without the coffins everywhere. Eventually I’ll have to build royal tombs for my King and Baroness Consort, but right now I’m pretty fed up with Urist McSpoiledpants and company. I haven’t made it down to the caverns yet, or found any magma, though that’s mostly by design (I don’t want to have too much “fun” and risk what I’ve built).

So yeah, that’s pretty much the tour! As far as I’m concerned, I still haven’t even begun to scratch the surface of the game, and I definitely have yet to become “fluent in Dwarf Fortress.” That being said, my civilization has yet to die out even once, and the reservoir and above ground ramparts are fairly dwarvish megaprojects. The way things are set up, I can basically close the gates and repel any goblin siege with minimal loss of life (I’ve weathered 5 or 6 of them so far), but it’s often more enjoyable to send the military out and kill things. Only problem is that the resulting bodies tend to horrify my dwarfs, who are already pretty struck with sunsickness from never going outside, which is why I have a bit of a vomit problem (understatement). It’s probably also why one of my military squads has valiantly named themselves the “Gates of Fainting”…

Military

It was something like 35-40 hours worth of gameplay to get this point, which is pretty insane. I really enjoyed myself, but I’m happy to say I haven’t played in a few weeks, so hopefully I’m over my Dwarf Fortress addiction. If anybody wants to see more, or has any questions about anything in the screenshots, just let me know!

Oh, and one last thing:

Weretortoise

The Weretortoise lady consort Buslá Demtamun has come! A large tortoise twisted into humanoid form. It is crazed for blood and flesh. Its eyes glow mahogany. Its sandy taupe scales are blocky and overlapping. Now you will know why you fear the night!

This game gets super weird sometimes…

Playing with Algorithms

I really enjoyed Ramsay’s Reading Machines, and I think he’s done a good job pointing at something that is really fundamental to working in the digital humanities: as he says, algorithmic criticism is “simply an attitude toward the relationship between mechanism and meaning that is expansive enough to imagine building as a form of thinking” (85). This reminded me of something that happened at a recent talk given by a prominent member of the video essay community. After talking for an hour about the possibilities of video essays and showing us wonderful examples of the critical tools that they could provide, a professor began the Q&A with the offhand assertion, “well play can never be criticism,” before going on to his question, which the speaker handled quite well. But the thing that many of us in the room remembered was that simple fact, that somehow there are prominent academics who honestly believe that play and criticism are fundamentally separate activities.

When it comes down to it, criticism is play, and play is criticism. The questions that the digital humanities force us to grapple with carry with them the fundamental understanding that this is the case, and it’s easy for us to forget that this is a somewhat heretical position. For my DFR I did something very simple: a while back I proposed a paper that tackled the question of contemporary animation and simultaneity, pointing out the “many things at once”-ness of a particular anime series, so I just searched for “animation” and “simultaneity” and got 408 articles that mention both. I’m looking forward immensely to playing with this data, if only because I know that simultaneity is something that comes up all the time in animation, but that it’s not often thought of as a primary mode for understanding the medium. Figuring out where simultaneity comes up and within what contexts could be a hugely powerful heuristic for my project. This is something so simple, but algorithmic criticism allows me to study it in a unique way using resources that would otherwise take months to sift through.

Which is exactly the kind of thing that the video essayist was trying to get at. Putting things side by side, mapping them out, playing with them, applying some sort of algorithm to them — these actions bring us back into an understanding of close reading and analysis, not push us further away, which is obviously something essential to the very concept of this class.

Brainfuck Typo

I’ve always been fascinated by the Brainfuck programming language, probably because out of all the weird languages I’ve heard of, it’s the one that makes the most sense to me. I’ve read about it a few times in the past, and was pretty sure I knew how it worked, until reading the Mateas and Montfort (hereafter M&M) piece and running across this snippet of code, which they say is a “Hello, World” program:

++++++++++[>+++++++>++++++++++>+++>+<<<<>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

What’s the problem? Here:

++++++++++  [  >+++++++>++++++++++>+++>+<<<<>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

That doesn’t make any sense (well, it makes less sense than a Brainfuck program should) – it has an open bracket without a close bracket! I actually think M&M do a pretty good job of describing the language in general: it creates a large array of byte cells, “>” goes right, “<” goes left, “+” increments, “-” decrements, “.” outputs, “,” inputs, “[” jumps forward to “]” if the byte is 0, “]” jumps back to “[” if it’s non-zero. However, they don’t bother to go into more detail (which I don’t really blame them) about what exactly that all does in practice. The output command uses ASCII, which just converts bytes into characters using this table:

So really, all that Brainfuck does is start moving pointers around that table. A simple program to print out “helloworld” could just keep adding until it gets to “h” (104) and then add/subtract from there in order to spell out the words – this is kind of like spelling something out on a screen using a remote where all you can do is go left or right (curse you Apple TV!!!). The only problem is that you’ll get a program that looks like this:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.---.+++++++..+++.++++++++.--------.+++.------.--------.

It’s a lot easier to start off the program with a [ loop to get some of that pesky addition taken care of more compactly. Think about it as a while loop: the byte before the [ (our counter byte) sets how many times we want it to run, and then we can move to the next byte (our target byte), increment some amount, go back, decrement our counter, and repeat, just like in Python. So if we want to add 100, it’s a lot more succinct to add 10 and loop it 10 times. This makes our “helloworld” program look like this:

++++++++++[>++++++++++<-]>++++.---.+++++++..+++.++++++++.--------.+++.------.--------.

Which is a lot nicer. This is what the M&M “Hello World!” program is setting itself up to do, it just forgets to decrement its counter and close the loop, like this:

++++++++++[>+++++++>++++++++++>+++>+<<<<  -]  >++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

This program actually works now (you can check it using this online Brainfuck interpreter)! It uses 5 bytes: byte 0 for counting, byte 1 for upper case, byte 2 for lower case, byte 3 for the space and exclamation point, and byte 4 for the new line (which is pretty standard for most of these programs). It starts off by setting the counter to 10, and then loops through to set byte 1 to 70 (right in the ballpark of “H” at 72), byte 2 to 100 (close to “e” at 101), byte 3 to 30 (near space at 32), and byte 4 to 10 (which happens to be new line exactly) – this is why the plus signs inside the brackets are in groups of 7, 10, 3, and 1:

++++++++++[             byte 0 = 10
>+++++++                byte 1 = 7         (*10 = 70)
>++++++++++             byte 2 = 10        (*10 = 100)
>+++                    byte 3 = 3         (*10 = 30)
>+                      byte 4 = 1         (*10 = 10)
<<<<-]                  decrement byte 0

From that point on, it’s just a matter of spelling things out using bytes 1-4:

>++.                    H                  byte 1
>+.+++++++..+++.        ello               byte 2
>++.                    (space)            byte 3
<<+++++++++++++++.      W                  byte 1
>.+++.------.--------.  orld               byte 2
>+.                     !                  byte 3
>.                      (new line)         byte 4

So now the programmer in me can breathe a sigh of relief knowing that the code works. I really love the taxonomy of weird code that M&M put together, as well as the examples they give for each: insane (INTERCAL), minimalist (Brainfuck), playful (Shakespeare), and impossible (Malbolge). The one other type of language I would have loved to see them talk about more would be funges, which use two-dimensional (or more!) space to direct their pointers. These can be things that still look like languages, just laid out differently, like Befunge:

 >25*"!dlrow ,olleH":v
                  v:,_@
                  >  ^

Or they can not look like languages at all. My favorite is probably Piet, name for Dutch painter Piet Mondrian, that actually uses colors in a bitmap to make things that really look more like paintings than programs. Here’s a “Hello World” program in Piet:

So cool! There’s a great gallery of sample programs “written” in Piet here if you all want to see more.

snack.py

# This is a coded version of a blog post, written in python.
# In it, I have authored some basic processes to help myself
# bring in a snack for class. Please feel free to comment
# with any analysis you might have of what I've chosen to
# include/exclude, as well as any additional suggestions.
# Here goes nothing! - Java


# And yes, as long as WordPress hasn't messed up my spacing, this all runs!


# Import the datetime library

from datetime import datetime


# Set some time variables that we'll need

snack_day = 1
snack_month = 10                      # Date I was supposed to bring snacks: October 1st
now = datetime.now()
this_day = now.day
this_month = now.month
class_hour = 18 # 6 pm
this_hour = now.hour
this_minute = now.minute


# And the functions to check those variables

def checkDate():                      # Check if it's the day you're supposed to bring snacks
    if snack_day == this_day and snack_month == this_month:
        print("You need to get snacks today.")
        return True                   # Returning booleans to let me know if I need to proceed
    else:
        print("You don't need to get snacks today.")
        return False

def checkTime():                      # Check how many hours you have left to get snacks
    hours = class_hour - this_hour - 1
    minutes = 60 - this_minute
    if this_hour < class_hour:
        print("You have " + str(hours) + " hours and " + str(minutes) + " minutes to get snacks.")
        return True
    else:
        print("You didn't bring snacks. Shaaaaaame...")
        return False


# Ok, now that we can check our date and time, let's make a Food object with useful attributes

class Food(object):
    def __init__(self, name, temperature, hasMeat, hasDairy, hasGluten, isTasty, hasBeenDone):
        self.name = name               # Give the food a name
        self.temperature = temperature # Hot, Cold, or RoomTemp
        self.hasMeat = hasMeat         # True or False
        self.hasDairy = hasDairy       # True or False
        self.hasGluten = hasGluten     # True or False
        self.isTasty = isTasty         # True or False
        self.hasBeenDone = hasBeenDone # True or False

    def check(self):
        if self.hasBeenDone:          # First things first, check if that snack's been used already
            print(self.name + " has been done before!")
            return False              # I'm returning booleans to make my looping easy later on
        elif not self.isTasty:        # Next, check if it's tasty
            print("Nobody would want to eat " + self.name + "!")
            return False
        elif self.hasMeat:            # Make sure that it meets peoples' dietary restrictions
            print("Vegetarians can't eat " + self.name + "!")
            return False
        elif self.hasDairy:
            print("Vegans can't eat " + self.name + "!")
            return False
        elif self.hasGluten:
            print("Individuals with gluten intolerance can't eat " + self.name + "!")
            return False
        elif self.temperature != "RoomTemp": # Finally, check if it needs to be kept hot/cold
            print("You would have to keep " + self.name + " " + self.temperature + "!")
            return False
        else:                            # Eureka!
            print("OH MY GOD " + self.name + " WILL PROBABLY WORK!!!")
            return True


# Now let's come up with some different food items...

chocolate = Food("Chocolate", "RoomTemp", False, True, False, True, True)
broccoli = Food("Broccoli", "Hot", False, False, False, False, False)
pitaChips = Food("Pita Chips", "RoomTemp", False, False, True, True, False)
pepperoniPizza = Food("Pepperoni Pizza", "Hot", True, True, True, True, False)
cake = Food("Cake", "RoomTemp", False, True, True, True, False)
sorbet = Food("Sorbet", "Cold", False, False, False, True, False)
tortillaChips = Food("Tortilla Chips", "RoomTemp", False, False, False, True, False)
cheeseburger = Food("Cheeseburger", "Hot", True, True, True, True, False)


# ...and put them in an ideas list

ideas = [chocolate, broccoli, pitaChips, pepperoniPizza, cake, sorbet, tortillaChips, cheeseburger]


# This last part is where the magic happens. Since my checkDate()
# and checkTime() functions return booleans as well as printing
# out their result, I can use them to run an if statement. Then I
# can iterate through my ideas list and run my check function, and
# once that returns True, exit the loop. This means I don't actually
# check the cheeseburger because I stop at tortillaChips.

if checkDate() and checkTime():
    for idea in ideas:
        if idea.check():
            break

Difficulty Tapping into the Stream

Twitterbots! It was really cool to get programming in Python “out in the wild” and actually see things happening as a result. There’s some childlike glee in seeing lines of code transformed into action, and that seems to be amplified when the output is coming from twitter rather than a simple printout. In addition to getting the bot to walk through lines of text, I also was able to get it to post photos randomly selected from some I’d downloaded to my computer, which took a little more finagling. What I would really love to do is get it set up so that it’s watching the twitter stream and responds whenever somebody tweets at it or uses a certain hashtag, but that turned out to be a whole new can of worms when I tried to get started during our workshop, especially since my hasty google search didn’t find any useful implementations of tweepy along those lines.

Overall, I think that’s the one thing that really stuck out to me: the frustrations in sifting through tweepy’s documentation trying to figure out how to do things. I’m thankful to have a library to take care of calls to the twitter API for me, but nothing sucks quite so much as knowing there’s a function defined in a class and not being able to figure out how to call it. Another option would be to just write a program that searches for the things I’m trying to respond to whenever I run it, but that’s not nearly as fun as having it actively monitor the stream live. I’ll probably play around with both implementations a bit and see if I can get either one working; all of the ideas I could come up with for bots were pretty lame, but I definitely like the idea of having it be responsive rather than just chunking out lines from a text file. Here’s hoping that instinctive excitement at writing a program and watching it tweet helps me power through the torrent of error messages that are sure to be coming my way…

Back on the Horse

I’m somewhat lucky in that my experience with coding began in a classroom setting in high school, preparing for the AP Comp Sci exam; learning in this setting meant that the basic rules of computer science were drilled into me from my very first encounter with code, such that it didn’t really matter that my first language (Java) is probably a lot less useful than the ones I’ve learned since (Javascript, C, Basic, HTML, Perl). Knowing the basic skeleton of how coding works and implementing best practices from the get-go makes the learning curve in picking up new languages a lot less steep, and it meant that I was able to get pretty far along in my 2 hours with Python on Codecademy.

That being said, Python has some things that are a little unique and harder to get used to, particularly the way in which it’s whitespace-sensitive, its use of colons, and the generic variable types. The whitespace thing just gets annoying when you want to go back and change the way you’ve nested things and have to tab everything over; the colons are kind of nice actually in that they facilitate that tabbing over and make it easier to keep track of where things are; and the fact that I don’t actually have to define whether something is an int, float, bool, etc. is great for ease of coding but makes me worry about type-checking. But all of these things are in the service of making Python as easy to use as possible. They force you to use good spacing and syntax, and the non-specified variable types make things like lists and dicts extremely mutable, to where you really can keep things simple as long as you’re checking your user input.

In terms of relevance to English studies, I think there are definitely corollaries to the way we learn normal languages (grammar, word choice, etc.), but the best connection I can find is formatting and legibility. There’s a tendency when coding to develop your own style and throw best practices out the window, but as I’ve mentioned, keeping up with those practices makes it easier to transition between languages while also making your code easier for others to read and, therefore, modify. In the same way, when writing, structure and formatting are maybe two elements of word “processing” that are also too easily forgotten, particularly when you’re only just starting to write for classes; pedagogically, learning a little bit about the strict guidelines of a language like Python could maybe be a great way to stress the importance of clarity and ease-of-reading to a freshman writing class, or really any class along those lines.