The !!Con Talk Anonymization and Selection Process

Another conference organizer recently asked the !!Con team what our anonymization process was, and we realized that we didn’t have a good source for them. While we tout our anonymization as a major component of our quest to eliminate implicit bias during the talk selection process, we haven’t written what our anonymization and talk selection process actually looks like in a while.

Julia Evans wrote a great post about our anonymization outcome after the first !!Con in 2014, and Lindsey Kuper has an update from a year later that goes into a lot more detail. We’ve changed some processes since (we no longer use github issues to track the proposals, for example).

One thing I want to point out is that if you’re submitting a talk proposal to !!Con, you shouldn’t worry about how your proposal will be anonymized! Just submit your talk like you want it to be listed, and we’ll take care of the anonymization process.

Here’s the blurb about anonymization from this year’s Call for Talk Proposals! page:

Proposals will be anonymized to avoid bias. Although we ask for your name, email address, and so on in the proposal submission form, only one or two organizers who serve as anonymizers will actually see this information, and they won’t review your proposal. The rest of the organizing team will review your proposal without knowing who you are.

I also think we have a pretty cool way of doing the talk selection, so I’ll cover that as well in this post.

Here’s the secret sauce:

  1. Each year, before we open the Call for Proposals, we decide who is going to be on the anonymization team, and who is going to be on the talk selection team. Generally the anonymization team is one or two organizers plus potentially one or two outside helpers who we recruit. The talk selection team is the remaining four or five organizers. This year, Alex Clemmer and I are the anonymizers, and the rest of the organizing team is the talk selection team.
  2. The anonymization team is the only team with access to the google form (and resulting google spreadsheet) that we use to collect talk submissions. Then we open the Call for Proposals!
  3. It’s tradition that the anonymizer who is supposed to close the google form falls asleep before midnight and forgets to close the form until the next morning. This year it was me and I didn’t close the form until 9am. Whoops!
  4. The “chief anonymizer” saves a copy of the original spreadsheet and begins going through it to anonymize it. Each talk is given an ID (a random unique integer, so that we don’t give away when the talk was submitted), so that we can track and re-aggregate our data at the end of the review process.

Let’s talk about the anonymization process. Here’s an example talk proposal (by me right now for demonstration, this probably wouldn’t be accepted):

I work at FiniteAutomata Corp, so my talk is about how knowing how finite automata work gives you regex superpowers! People will look at me and say, “wow he is so cool with his regex” and I’m like “heck yes I am good because I know how finite automata work let me teach you”. Here’s a link to me giving a longer version of this talk at FiniteAutomataCon 2011: http://example.com

The anonymizer takes this proposal and does a couple of things:

  1. Remove/Obscure any names of people or companies. We generally leave in product names unless the talk submitter is the main author of that product, in which case we will remove the product name as well. For example, “FiniteAutomata Corp” in the example above would become “[Large Tech Firm]”, in square brackets (or similar).
  2. Remove/Obscure any pronouns or other identifiers. For example, my proposal above says “he” and “his”, which gives away my gender. We would replace these pronouns with “[they]” or “[author]”.
  3. We also try our best to watch / read any associated material and give a quick synopsis of it. For example, the link in the proposal above would become “[Video of the author giving a 30-minute version of this talk at a well-known conference. The talk is well received by the audience.]”

During anonymization, we try not to remove aspects of the speaker’s identity that are essential to the message of the talk. For example, the abstract for Sina Bahram’s 2016 talk about screen readers begins, “I use a computer very differently than most people, because I’m blind.” It wouldn’t have made sense for the anonymizer to remove this fact, because it is Sina’s personal experience that makes the talk proposal especially compelling. We try to use our best judgement here (and probably get it wrong sometimes!)

Once we’ve created the anonymized version of all the talks, we create a copy of the anonymized spreadsheet for each of our reviewers. If I were on the reviewing team, I would get a spreadsheet called “!!Con 2018 – Talk Proposals [Erty]”. This is my personal copy of the anonymized spreadsheet.

The next step is for each reviewer to give each talk a grade. !!Con co-organizer Lindsey Kuper introduced this grading scheme, based on the Identify the Champion process (Specifically Make Champions Explicit):

A – I really like this talk and will advocate for it to get into the conference
B – I like this talk, but not enough to advocate for it
C – I don’t like this talk, but not enough to advocate against it
D – I don’t like this talk and will advocate against it being included in the conference
X – I think I know who submitted this talk, and abstain from giving it a grade

The chief anonymizer then creates a spreadsheet that aggregates these grades into a single place (did you know that you can include cells from one spreadsheet in another using google spreadsheets? It’s pretty nifty!). We look at the best grade and the worst grade for each talk.

Some examples:

A talk that got grades A B B C would have a final grade of AC (A is the best and C is the worst)
A talk that got grades X A A X would have a final grade of AA
A talk that got grades X D C A would have a final grade of AD

If a talk got 0 or 1 grades due to abstain votes, we would handle that as a special case. I’m pretty sure that hasn’t happened in the 5 years we’ve been running !!Con.

We all get on a conference call at this point and start going through the talks! This is really fun! AA talks generally get in immediately. AB talks are usually also admitted as well, if we still have room. AC talks we usually discuss, but they’re generally not admitted, and AD talks are really interesting, since it means someone will advocate for it and someone else will advocate against it! Generally, someone misunderstood the proposal, or two people have differing ideas about what kind of talks should get into !!Con. It’s usually a no, but these talks will sometimes get in (especially if they got AAAD).

More generally, this means that only talks that get at least one A are considered. Your talk needs to convince one of our reviewers to become a champion for it. As Lindsey noted in her blog post Scaling !!Con, last year (2017) we had 86 talks with an A out of 215 total, which we then had to narrow down to just 30!

Remember that all of this is still being done with anonymized talks. The anonymizer(s) will usually sit in on this call and answer any questions about the proposals that the reviewers have (usually around things like the descriptions of videos that were with the proposal). But never speaking up to sway a decision in one way or another. This is difficult! Last year I spoke up because I was really excited about a talk proposal (that ended up not getting in, anyway) but I definitely shouldn’t have done that, since I knew who the speaker was and therefore had implicit bias.

Once we’ve decided which talks we’ll approve for the slots we have available, we take our next favorites (generally about five of them, but it varies) and hold those as backups in case our acceptances aren’t accepted (it happens!).

The anonymizer then goes through and makes sure that we didn’t select the same speaker twice (some people have submitted as many as six talks in a single year!) If we did, we bring some more people off the backup list, then replace them to keep our backup list full. Usually if someone submitted two talks that were accepted, we let them choose which one they’d rather give. Although, if there’s a clear favorite, we might suggest that they choose that one 🙂

At this point we do the dramatic reveal and show the review team who got in! Then we email these people. This is really fun 🙂

One important thing to note: If you didn’t get accepted, then your name is never revealed, not even to our review team. The anonymizer emails out our famous rejection letter after we’ve figured out our lineup. This is not so fun 🙁

That’s it! I hope this is useful information, especially if you’re starting a conference yourself.

a e s t h e t i c 💫 g e n e r a t o r

Update: the a e s t h e t i c g e n e r a t o r is now online.

 

Ryan McVerry, Per-Andre Stromhaug, and I got together this weekend to do a mini-hackathon. We’d been inspired by a Chicago-based artist on Tumblr named Galactic Castle. Specifically, this image:

Our goal, was to write python to generate images that looked like Galactic Castle’s. We used the Pillow python library for the most part, messing around with 256×256 arrays of integers, limited to 10 or so colors.

We experimented with a few different rendering techniques, eventually settling on a layered technique. I’ll start with some examples of the finished product, and then a quick walk through some of the fun images we generated along the way. You can run it yourself at https://aesthetic-landscape.herokuapp.com/.

Here are a few shots from the process along the way.

This is one of the first renders we saved. You can see most of the elements coming together, and the dithering in the sky is already in place.

Experimenting with color palettes:

I messed up the color palette:

Getting reflections working. At this point I was doing two things that I eventually stopped doing: reflecting the actual colors (instead, we just use a single color to represent any reflection) and at this point we weren’t doing any sort of layering, so the reflections were crude and unaware of what they were reflecting. In the latest version we use a different algorithm for things above the horizon (mountains, moon) and things in the water (rocks/land).

Better reflections, added a moon.

Re-worked the rocks code. We were originally using polygons that were then filled by PIL. The new code instead generates an enormous int buffer and we manually fill in from the edge. The rocks at the base of the land spits are just handled by keeping track of a number that grows and shrinks, and switching colors when we reach that threshold.

We were originally working at 512×512 (scaling up x4 for the final image), but eventually realized that Galactic Castle works at about 150×150, so we scaled down. The resulting pixelation is much more pleasing. Added trees and improved the mountain cross-hatching.

I hope you enjoy this! You can see it for yourself at https://erty.me/aesthetic.

In 2024, I rewrote it in Typescript so that it runs fully in the browser (instead of a thin frontend on a Python backend). Code here 🙂

We Built an Arcade Cabinet in a Weekend!

We built an arcade cabinet! In 72 hours!

The team:

Project Lead
ERTY SEIDOHL
Software Engineers
RYAN MCVERRY
MAX FELDKAMP
Hardware Engineer
BEN GOODING
Music and Sound
EVAN CONWAY
Cabinet Construction
ERIC VAN DER HEIDE
MATT GOLON
Cabinet Art
HALEY WHITE-BALLOWE

Finished image first 🙂

We had the idea to build an arcade cabinet several months ago, and by the time Ludum Dare 38 rolled around, we had the time and space to make it happen! We met a few times beforehand to test out ideas and hardware, and parts started arriving in early April:

We decided to use the LÖVE framework on Raspberry Pi 2-Bs, via the PiLove raspbian image.

Ideas started flying on Friday at 7pm Mountain, though, when we all got together to create the game. Sadly, our game idea about slipper and flipper the penguins didn’t make it to the final round.

We quickly began to mock out the cabinet design, and started building the game!

Our first prototypes were… okay 🙂

But things began to come together…

The cabinet really began to come together! We thrifted the TV for about $30. The speakers were old computer speakers we had lying around, and the coin door we purchased on Amazon for about $40.

More construction pics:

Haley (our artist) couldn’t join us until day 3, but she did an amazing job!

The yellow paint was a little… weird. Ah well :\

Finally, we had the whole thing rigged up! Time to plug everything in and turn it on!

A few touchups on the title…

And, about 15 minutes before the deadline, we had a functioning, working arcade game!

Here’s a quick video of the gameplay:

 

 
YAY!

We ran into a major issue right at the end, where (to get technical for a moment), our audio would cut out from time to time and just stop working. It seemed like an issue with pulseaudio. The way we solved it was to kill pulseaudio on startup. And for some reason that worked? So, I have no idea what’s playing the sound, but whatever it is crashes less.
 

We also had a wonderful “blur” effect that pulsed in time with the music, but it turned out to be too intensive for the raspberry pi, so we had to turn it off in the end. We tried doing it with shaders (way too intensive) and we tried doing it with just drawing translucent, larger versions of everything (just a little too intensive) and finally turned it off. Ludum Dare definitely requires you to just cut things if they’re not going to work, no matter how much time you put into them!

I’m going to attempt to get a copy of the game working so you can play it online by Friday, but no promises!

Dictionaries and Word Lists for Programmers

I love to play with words, and I especially love to play with words programatically. I’ve written three small apps (so far) which use some form of a dictionary to create readable, humorous text:

I’ve had some people ask, so here are some great resources that I’ve found while building these apps.

Dictionaries

/usr/share/dict/words (~235k words)
Available on any *nix system, this word list is a local way to check for words using a simple grep. You can also read the file in as long as you have permission to do so. Won’t work well if you’re trying to write something for the internet or windows.
Most of these dictionaries are licensed very freely, but you should check on your own system. Versions of this are available online, e.g. the FreeBSD version at  https://svnweb.freebsd.org/csrg/share/dict/ (click “words”)

GCIDE (~185k words)
http://www.ibiblio.org/webster/ or http://gcide.gnu.org.ua/download
This dictionary contains words and definitions. Very useful if you actually want to look up the words you are using. Sources for the definitions are available as well. There are two versions – GCIDE which comes in a strange format and needs its own reader software, and GCIDE-XML. Licensed under GNU.

SCOWL and friends (variable word count)
http://wordlist.aspell.net/
A very complete set of wordlists, used for the aspell spell checker. My favorite part is the customizable interface where you can create your own custom dictionary. Many links and different dictionaries are available on this page, including some with part-of-speech and/or inflection data. Be aware: many versions of SCOWL contain swears and racial slurs.
Variable licensure, but all are released for private or commercial use as long as you maintain a version of the license.

CMU Pronouncing Dictionary (~134k words)
http://www.speech.cs.cmu.edu/cgi-bin/cmudict
Contains not only words but their phonemes, meaning this is a great dictionary for text-to-speech, rhyming, and syllable counting. There are CMUDict libraries for node/browser, just node, python, and many other languages (send links please).
The file is copyright Carnegie Mellon, but is unrestricted for personal or commercial use.

Corpora (Lists of ~1k words)
https://github.com/dariusk/corpora
A really neat set of lists, broken down by category (e.g. /data/foods/beer_styles.json). A great starting resource for small projects that don’t need an extensive dictionary of the English language. Licensed under CC0 (no copyright).

Wordnik Developer (Web API)
http://developer.wordnik.com/
A powerful web API. From the site: “request definitions, example sentences, spelling suggestions, related words like synonyms and antonyms, phrases containing a given word, word autocompletion, random words, words of the day, and much more.”
Free 15k calls per hour, licensed for anything that isn’t a direct clone of Wordnik itself.

(Please, send any more dictionaries you know of my way and I’ll add them to the list!)

Libraries

FastTag / jsPos
https://github.com/mark-watson/fasttag_v2 (java) and https://code.google.com/p/jspos/ (js)
Java and Javascript libraries to tag parts of speech in words. Very handy if you’re doing any sort of lexical generation.
Licensed under LGPL3 or Apache 2 licenses

(Please, send more libraries my way if you know of them!)

People / Blogs

Peter Norvig
Probably my greatest source of inspiration on this front is Peter Norvig’s How to Write a Spelling Corrector (python). He shows that you don’t need any sort of fancy tooling or arcane knowledge to write something that at first seems complex – just don’t be afraid of making the computer do a lot of work for you. That’s what they do – they do work really, really fast. (see, for example, this scrabble solver)

Allison Parrish
Allison plays with words in amazing ways. She is the brains behind @everyword. Her website and research are full of great inspiration for playing with words and experimenting with language.

(please, send anyone doing interesting things with words my way and I’ll add them to the list!)

Project Idea: “Lanky” PHP Middleware Language

I keep not writing weekend web apps because I know that my projects generally follow this trajectory:
1. Build a database
2. Build some thin PHP middleware to expose an API to that database
3. Build a slick react/angular/whatever frontend
4. Realize a bunch of things I’m missing in my API and add them, lamenting the entire time that my “thin” PHP middleware is starting to bulge at the seams.

I keep realizing that that PHP layer is not really necessary. R0ml gave a great Recurse Center talk (if someone has notes I’ll link it)  on a postgres extension which renders the middleware unnecessary.

I’m not quite ready to make that leap and throw out the middleware entirely (even though I think it’s a great idea…). So I’d like to build a language to really easily describe a PHP API. My goal is to have the PHP routing be as thin as possible and mostly handled by one fast function. In fact, I’d love to eventually have this language implemented in node, or even C/C++ for a pure-speed kind of thing. I’d also love to figure out a way to cache the parsed document so that I don’t have to parse the entire thing every time, but that’s a future optimization.

I’ve started a github repository https://github.com/ertyseidohl/lanky  with an example of how I’d like a Lanky document to look at https://github.com/ertyseidohl/lanky/blob/master/thoughts.txt.

I may end up abandoning this at some point because of time restrictions but that’s why I figured I’d get my first ideas about it online – maybe if there’s something good in there someone can steal it, or even better, point me to a project which already does this but better.

I called it “Lanky” because that was the first synonym for “thin” that didn’t have outright negative connotations or an existing PHP framework (slim, gossamer, etc).

From Boulder, CO

–Erty

Notes from PAX Prime 2015

I attended PAX Prime 2015 this past weekend with a friend, and ended up going to two talks.

Ask a Dungeon Master

Chris Perkins

  • Dungeon Masters are unique.
  • Gary Gygax
    • Had the players declare a “caller”, who was the only person to talk to the DM, who sat in an adjacent room.
  • Learn first by emulating existing DMs and running existing campaigns.
  • In older modules, location is key. In “modern” DMing, characters and politics are key.
    • The older modules are often named after the location, “crypt of the…”
  • Chris learned a lot from a few TV shows
    • Star Trek: The Next Generation
      • Character-Driven story
      • Focus on teamwork and character development
      • Episodic content with a repeating cast
      • Some episodes are standalone, while others feed a larger arc
      • In a serialized story, each character has an arc and needs to grow
      • Don’t introduce characters and then not allow them to shine for at least a moment
        • Give everyone a journey
      • Characters:
        • We know nothing about them
        • Choices are made
        • Shit happens
        • Now we know a lot about them
        • (They might not make it to that final step)
    • West Wing
      • Q: How did Aaron Sorkin make politics so interesting?
        • A: Have three or four things going on at the same time
        • Make it overwhelming so that the characters must make choices
        • Give quests with political importance
        • If one conflict gets boring, make sure there are others at the same time to fall back on
    • Buffy
      • (No notes?)
  • Storytelling is the art of using narrative to elicit an emotional response
    • PCs get attached to things. NPCs, Locations, Items.
      • But they can only get attached if those things have personality
  • Let characters make “real” choices and deal with the consequences
  • DMing is challenging as storytelling because it is performed LIVE
  • Constantly Improvising
    • (Here, Chris plugs Acquisitions, Inc.)
    • There are no (or, very few) takebacks in DMing
      • Remember what NPCs sound like!
  • Chris’ evolution of a DM:
    • Run published campaigns
    • Write your own campaigns
    • Improvise everything
      • This takes practice!
  • Good DMs…
    • Have fun!
    • Don’t over-prepare
    • Roll with the punches
    • Don’t fret about the rules
    • When in doubt, just say yes!
  • If everyone dies, call it a night
    • Death is the beginning of another story
  • Tricks
    • Hoard Maps
    • Use the Three-Story Arc
      • (Example)
        • The heroes need to find a route out of the underdark
        • There are drow kidnapping surface dwellers
        • There are spore-infested creatures
      • All three of these storylines are happening at the same time, the players bump into them as they move through the dungeon
    • Write things as episodes
      • Use episodic recaps to remind your players what happened last time, on D&D…
    • Chris prepares each session as a one-sheet summary
      • What is the basic outline of the episode
      • What are all the notable NPCs that the PCs might run into
      • What major events will probably happen during this episode?
    • There is nothing you can do wrong with NPCs. Give them EMOTION
    • Ask the players what they want!
      • (It’s their game too!)
      • Example Qs:
        • Magic Item wish list
        • Campaign Knowledge wish list
        • Accomplishment wish list
    • Use foreshadowing
      • The players will try to connect things even if you don’t purposely foreshadow.
      • So do it purposely!
    • Imagine an actor to play each NPC if you want a handy way to remember
  • Traps
    • Over-Preparation
      • Your PCs will never go where you expect. And if they do, you’re…
    • Railroading
    • Rules Inconsistency
    • Time Travel
      • (You think it’s fun, but experienced DM’s know, it’s a recipe for disaster)
    • Things players hate
      • Don’t do them!
    • “Me vs Them” attitude
      • Remember, you’re all on the same side – everyone just wants to have fun!

So, You Want to be a Game Writer

Toiya Finley (Schnoodle Media), Qais Fulton (Freelance), Anne Toole (The Write Toole), Bobby Stein (ArenaNet), Tom Abernathy (Massive Entertainment), Leah Miller (Carbine Studios)

  • Q: Even if you do understand storytelling, what should you know about game writing?
    • Average text length in games is decreasing
      • Avg length of text in Wildstar: tweet length (140 char)
    • Know the audience and technology. What works in the game?
    • These are interactive and nonlinear stories.
      • Sequence and Timing go out the window.
    • Don’t make your stories linear. Make them player-centric.
    • The player cares about “my story”, not “your story”.
    • They should have the choice of how to play the character
    • “The player’s story will trump whatever heartfelt thing you write [for NPCs]”
    • Designers and programmers will do their own thing with your story. You have to deal with their requests. It’s writing in a team setting.
      • Know how to communicate with the people who are actually building the game, to keep them in sync
  • Q: Game writing is competitive. How do I get a job?
    • “It’s like breaking out of prison. Once you figure out your path, it’s probably not going to work again.”
      • Try not to copy existing successes. Make your own.
    • Some companies you can start out at the bottom and work your way up to writer over years.
      • Many others, you can’t – you have to get hired in at the top
    • (Ed note, this is good job advice for any field!)
    • Work on your own projects. Have a portfolio that you can show people.
      • Have it online.
      • Make sure it’s recent
      • Work consistently
    • Practice your “Story Sense”
    • If you want to make your own games, you don’t want to be a writer. You want to be a Creative Director
    • Check out text-based game engines
      • Twine
      • Inform7
      • Episode Interactive
      • Pen & Paper RPGs
    • Play with level editors so that you know what the developers are working with
  • Q: Portfolio? What should I showcase?
    • BE ENTERTAINING
    • Genre diversity!
      • Have some horror, action, humor, etc.
    • No two employers want the same thing
      • Aim for around 2-3k word games for your portfolio pieces
        • That said, have lots of different length material. Every company wants something different
        • “Short, concentrated awesome”
      • Dialogue Samples
      • Lore Documents
      • Technical game design documents readable by non-writers
    • Know the types of games the company makes, and tailor your portfolio to them
    • Don’t assume the company knows anything about (good) writing
    • Copyright theft is real!
      • Use watermarked PDFs
      • Only post samples
      • Protect yourself against plagiarism
  • Join the IGDA
    • Int’l game devs assoc
      • Writers’ interest group
        • Facebook group
  • In meeting people, it’s more important to have an interesting conversation, than to “network”
    • Make friends, not contacts
  • Q: Freelancing v Employment
    • It’s good to have at least one staff job on your resume, esp. if you did “the trenches” (crunch, ship)
    • Freelancer, you also have to be a salesperson. Always be selling your writing
      • Read marketing books, sales books
      • You’ll also have to be a collections agent
        • Don’t work for free
        • You can get consistent work, but it won’t be consistent money
    • Don’t be afraid to fire bad clients
    • Make “work for hire” agreements
    • DON’T TURN OVER THE RIGHTS TO THE WORK UNTIL YOU’VE BEEN PAID
    • Full Time:
      • Benefits!
      • Work at an office (external motivation)
      • Structure!
      • But: They own you
      • Be aware of your self
      • Better mentorship opportunities
      • Get pushed into weird projects (which is great for experience!)
      • At a smaller place, you can make things happen!
        • Just talk to the CEO
      • When you work on staff through crunch, you become really good friends (which turn into really good contacts after you leave)
      • If you work at a large company, make sure you make friends with people outside your small team. You have an opportunity to get a large network. Use it!
      • Remember that personal work done at work (Even if not on the clock) belongs to them. They own it. Be careful about how/when you work on personal projects.
        • Or, just pitch your ideas to them and see them get made!
      • Know your rights
  • Q: How do I write?
    • Write!
    • Just write. Don’t be attached to your writing.
    • FEAR OF BEING YELLED AT  > FEAR OF WRITING POORLY
    • Work back and forth with the developers and designers
    • Write shitty first drafts
      • You’ll have time to revise
      • You’ll have people to get feedback from
    • Be prepared for blunt feedback and people who don’t understand your intent
    • Be prepared to admit failure, but have some confidence, Know your strengths and weaknesses.
    • When you’re working on a game, everyone is on your side. (They all want the game to be good!)
    • Be prepared to throw everything out and start over
  • In games, don’t tell, don’t show, do.
    • Let the players learn organically through the environment, instead of trying to cram instructions into words.

Prps

My good friend Angela told me about the Service a week ago. Once you press the button on your phone, you no longer know what’s real. Every person you bump into on the street arouses suspicion. Are they part of the Service? Is that man across the street just taking a picture, or recording your location to call more of their actors in? Everything becomes paranoia. Everything becomes… exciting.

I downloaded it from the app store. Prps itself is free, but each week of the Service costs $100. Angela told me she bought the deluxe package, which included a month’s worth of the service and a mission involving a trip to a foreign country. She couldn’t tell me what country. According to her, she’d woken up in a jungle with a dart in her neck.

The Terms of Service were long. Very long. “There is a real possibility of permanent injury, disability, or death while using the Service”. “We accept no liability for any allergies to substances you may be injected with during the Service”. “There is a real possibility that when you return home, you will be unable to return to your job, have a criminal record, or find regular life incredibly boring”.

Real Total Recall shit is what it was, but without the dream. Without the ability to say, “I’m dreaming and I want this to stop.” Once you press go, you’re in it and there’s no safe word. The only way out is to get caught by them and “lose”. But losing might mean death.

I’d heard on the news about a guy who thought that he was interacting with the Service but ended up accidentally getting involved with some branch of the Mexican Mafia. There’s no way to tell. The Service don’t announce themselves. It’s illegal, of course, to purchase the service, or to work for them. But that doesn’t stop people from doing it. Hell, AirBnb is illegal in New York and look at the millions of dollars in business people do there.

I hear that nearly 70% of people who survive Prps end up working for the Service afterward. They get bored with anything else.

I agree to the terms of service. The app shows a single button. “Go”.

I take a deep breath, and tap.

Within moments I get an email from my bank. “Suspicious activity in your account.” Tap. Holy shit. There’s two million dollars in my bank account.

I hear breaking glass downstairs. That was fast. I probably should have gone somewhere with two exits bef…

A gunshot interrupts my thoughts. Splinters fly from the door. They’re using live ammo. I bolt for the window.

From Manhattan,
–Erty

 

Should You Prefer Prefix over Postfix Increment?

I’ve been told in the past by a programming mentor that ++x is faster than x++, and I found myself refactoring a few increments in javascript the other day.

But then I got thinking – is it really faster? Wouldn’t most modern compilers optimize out the difference? I decided to do some science.

Here’s an outline of the code I ran on JSPerf:

    var x = 0;
    
    var obj = {
      x: 0
    }

  // test one: 
  x++;

  // test two:
  ++x;

  //test three:
  ++obj.x;

  //test four:
  obj.x++

Results:

For the most part, ++x has the same microperformance as x++.

Modern versions of Android Browser, Chrome, Firefox, Internet Explorer, and Safari all have similar performance for each of the benchmarks. This overrides my existing belief that prefix notation is faster.

In some browsers, there is a small but noticeable difference.

In FF19, ++x is faster than x++. But ++obj.x and obj.x++ are the same speed.

In FF31, ++x is faster than x++, but obj.x++ is faster than ++obj.x.

One interesting thing is that some browsers prefer x++ and others prefer ++x. The largest difference, FF31, is around a 1% increase in performance. But, Chrome Mobile loses that same amount (~1%), preferring x++ over ++x, so ultimately it’s a wash unless you’re targeting a specific browser.

From Manhattan,

–Erty

Making Tea With Javascript: OOP with the Prototype Chain

Javascript is weird.

Prototypical inheritance is really powerful, but it’s quite a bit to wrap your mind around if you’re new to it. My first language was Java, and I’m comfortable with the “traditional” OOP paradigm. In this post, I’ll build a traditional Superclass/Subclass relationship in Javascript in an attempt to untangle the weirdness that is Javascript’s prototypical inheritance model.

All of the source code is available in a repl.it.

Part 1: Superclass Constructor

Let’s brew a cup of tea.

//Superclass constructor
var Tea = function(options) {
    this.color = options.color || "herbal";
    this.caffeine = options.caffeine || 0;
    this.tannins = options.tannins || 0;
    this.minsSteeped = 0;
}

Here, we’ve created a constructor for some tea. This tea can’t really do anything, but it holds some useful information on whatever tea object we create in the future. I can make a cup of herbal tea by calling this with the new keyword.

var myHerbalTea = new Tea({});

 Part 2: Superclass Prototype

Now that we have an idea of how prototypes work, we can go ahead and construct a prototype that will be applied to instances of Tea.

Tea.prototype = {
  steep : function(cup) {
      //caffeine
      this.caffeine = Math.max(0, this.caffeine - 1);
      if (this.caffeine) {
        cup.caffeine ++;
      }

      //tannins
      cup.tannins += this.tannins * this.minsSteeped;

      //color
      cup.color = this.color;

      //minsSteeped
      this.minsSteeped ++;
  }
};

Now we create an object with a single method, steep, and assign that to be the prototype of Tea.  We usually want to put methods on the prototype, so that there’s only one copy of the function shared among all instances (this saves us a lot of memory).

After calling var myHerbalTea = new Tea({}), we’ll have the following inheritance structure:

Prototype Inheritance of myHerbalTea

 

Notice that the Tea function is not part of the prototype chain. It is simply a constructor function used to add the member variables (color, etc) to myHerbalTea. However, because Tea.prototype exists, it is chained to our instance of the Tea class.

Part 3: Subclass

Herbal tea is boring. Let’s make something to wake us up!

//Subclass constructor
var BlackTea = function(){
    //Put instance properties from the superclass constructor on the subclass instance
    Tea.call(this, {
        color : "Black",
        caffeine : 10,
        tannins : 3
    });
    this.hasMilk = false;
}

Here’s where the Javascript magic begins. And by magic I mean less of the Harry Potter and more of the Goat Sacrifice.

Let’s make some black tea:

var firstCup = new BlackTea();

This is another constructor function, composed of two main parts. First, we call the Tea() function, binding to the current instance. The call to Tea will have firstCup bound to this, which will apply all of the instance variables (color, etc), to firstCup. This is kind of like calling super() in a constructor in Java.

Here’s the relevant code. Everything that refers to firstCup when we create it is highlighted red.

var Tea = function(options) {
    this.color = options.color || "herbal";
    this.caffeine = options.caffeine || 0;
    this.tannins = options.tannins || 0;
    this.minsSteeped = 0;
}

// ...

var BlackTea = function(){
    Tea.call(this, {
        color : "Black",
        caffeine : 10,
        tannins : 3
    });
    this.hasMilk = false;
}

var firstCup = new BlackTea();

// ...

Ok, pop quiz. what is currently the prototype of firstCup?

Answer: undefined.

If you thought it was Tea, remember that Tea is just the constructor and is never really a “thing”.

If you thought it was Tea.prototype (I totally did), know that even though we do Tea.call(...), we haven’t bound BlackTea‘s prototype yet, so firstCup.__proto__ is nothing.

Let’s set up the prototype and make a second cup.

Part 4: Subclass Prototype

Remember that the prototype of a class is the object that will be assigned to the __proto__ property of any instances created of that class. So in order to create a second cup of tea, we need to first change BlackTea.prototype.

BlackTea.prototype = Object.create(Tea.prototype);

var secondCup = new BlackTea();

It wasn’t obvious to me at first why we don’t bind BlackTea.prototype directly to Tea.prototype. Instead, we create an object whose prototype is Tea.prototype, and then set BlackTea.prototype to that new, empty object. Our secondCup object can still see the steep(cup) function, but it checks an empty object on its way up the prototype chain. Hmm…

But say we want to be able to add milk to our black tea. (Adding milk to green or herbal tea is icky and we shouldn’t allow our users to do that). If I modify BlackTea.prototype to be able to add milk:

BlackTea.prototype.addMilk = function(cup) {
    //adding milk makes the cup of tea less harsh!
    cup.tannins = Math.floor(cup.tannins / 2);
    this.hasMilk = true;
}

Remember that BlackTea.prototype is not Tea.prototype! It’s an object whose prototype is Tea.prototype. This means that addMilk is only available to instances of BlackTea, not any kind of tea.

Our prototype chain now looks like

withmilk

Yay!

Part 5: Actually Make Tea

//ok, let's make some tea
var myTea = new BlackTea();

var myCup = {
    color : "clear",
    caffeine : 0,
    tannins : 0
};

//steep for three minutes
myTea.steep(myCup);
myTea.steep(myCup);
myTea.steep(myCup);

//add some milk
myTea.addMilk(myCup);

//drink up
console.log(myCup, myTea);

This produces:
myCup is { color: ‘Black’, caffeine: 3, tannins: 4 }
myTea is { color: ‘Black’, caffeine: 7, tannins: 3, minsSteeped: 3, hasMilk: true }

Part 6: Recap

  • Javascript prototypal inheritance is super weird
  • Use the new keyword to treat a function as a constructor
    • The prototype of that function will become the __proto__ of the object, which is where the object looks for methods that aren’t declared locally.
    • Then you can call that constructor (like Java’s super()) using Class.call(object)
  • Explicitly set prototypes to an object with the prototype you want to create
    • e.g. myObject.prototype = Object.create(Constructor.prototype)

I hope this blog post cleared up some of the mystery around prototypes and inheritance!

From Manhattan,

–Erty Seidohl

P.S. Thanks to Ryan McVerry and Julia Evans for proofreading! Also Michael Mulley for helping me understand the WTF-ness of .prototype not actually returning anything on an object.

Notes from PAX East 2015 (Part 3 / 3 – Dungeon Mastering)

I went to PAX East 2015! It was awesome! I took a lot of notes!

(Part 1: Social Stuff)
(Part 2: Making & Selling Games)

Here are the notes from the one talk that I went to on being a good Game Master.

Playing Between The Lines

Luke Crane, Adam Koebel, Sage LaTorra, Thor Olavsrud

  • DMs are authoritative. (this is bullshit)
  • DMs enforce a social contract.
  • DMs organize & wrangle humans
  • THE DM IS JUST ANOTHER PLAYER WITH DIFFERENT RULES.
  • Prep
    • Creating Scenarios
    • Homework
    • Game Design
    • “Lonely Fun”
      • The DM who creates adventures that will never be run. And has a great time doing it.
  • Prep in the most minimal way possible.
  • Find and create things that will drive action.
  • The GM is expected to always be thinking about the game. (this is also bullshit)
  • What does prep look like for…
    • D&D
      • Reading
      • Research
      • Environment Building
      • Narrative Stuff
    • The Great Pendragon Campaign
      • Reading Le Morte D’Arthur
      • Reading about the current period and year
      • Tying in past family events and scandalous rumors
    • Dogs in the Vineyard
      • Towns, Sins, Demons, People, Relationships, Mormons, Guns
      • Play a GM Minigame to create the campaign (Lonely Fun)
      • Use their system for “creating problems”
    • The Burning Wheel
      • Building Characters
      • Developing Relationships, both oppositional and supportive
      • Challenging Beliefs
    • Dungeon World
      • Make shit up
      • Wave hands like muppet
      • Talk in funny voices
      • Buy more copies of Dungeon World [note: the publisher of D.W. was on the panel]
  • 90% of DMing is making shit up (improv)
  • Building a cool world:
    • If you are playing a game with characters, you need to build the map in personal terms instead of locational terms.
    • Your campaign doesn’t exist in a vacuum. Learn to build external media into your campaign. Steal from pop culture. Don’t worry about it as long as it’s fun.
    • Read A Wizard of EarthSea
      • Names are magical. They give things solidity. Going after a +3 broadsword is way less cool than going after Sunbrand, Sword of the Western Hills
      • Use language dictionaries. “What langauge is magic performed in?” (mongolian!)
  • Have a folder.
    • Name List
    • Map
    • Notes
  • DRAW MAPS, LEAVE BLANKS.
    • (JIT DM)
    • Collaborate in worldbuilding with the players
  • Character (NPC) prep:
    • Use the rules. Then fudge the rules.
    • Build opposition to the characters
    • The axiom of antagonists: “They have something appalling that they want, but use methods that the players approve of” or “They have something good that they want, but use appalling methods to achieve it
    • Then take it a step further and make sure the antagonist wants something from the PCs.
  • For any character in the game, you should have 3 things that describe them.
  • Story:
    • Relationship Maps! (example)
    • NPCs should have reactions to player events.
      • “What does your NPC dad think of what your PC is doing?”
      • “What do the rest of the goblins do after you’ve killed their king?”
    • Behind the scenes, or indirect action.
  • rtfm
  • Game Mastering is Learned, Not Borned
    • Skills, not genetics
    • These skills can be taught
    • Anyone can become a GM if they’re not afraid