Friday, June 30, 2017

Code For Twitch Chat Bot

Stole Modified some fantastic code I found on the internet to build a python bot to deal with some unsavory characters on my twitch channel. Some scumbag was making rape threats against my family members, so me or my mods would ban them. Problem was, they would just fire up new twitch accounts and continue the barrage. So, being lazy, I built a bot that can be turned on/off, that would look for brand new accounts, and automatically time them out of chat for exactly one day. That way, they would still watch my channel and boost my twitch numbers, but they would do so in glorious silence.

Also my bot is called DavidSPumpkinsBot and will type "Any questions???" as it does the things.
(It's the little stuff, right?)

Posting the Python code here (minus my authentication codes, for obvious reasons), so my friend Das Ranger can build his own! Enjoy!

Python code:

#! TwitchBotBusterCode
# -*- coding: utf-8 -*-

from __future__ import print_function
import socket
import time
import re
import requests
import json

# The twitch user which will be acting as your bot
chat_user = 'davidspumpkinsbot'

# The oauth password for the twitch user which will be operating
# Obtain this value by visiting this page while logged in as your bot user:

# The channel the bot will be operating in (your channel's name)
chat_chan = 'gundaymonday'

# Punishment method; change to timeout (or any word other than ban) to make it timeout instead of ban
punishment = 'timeout'

# If using timeout punishment, duration of the timeout
timeout_duration = 3600

# Twitch IRC server info: the host and port should not need to be changed
chat_host = ""
chat_port = 6667

# List of commands which use regular expressions. Only change the left side and make sure to leave the ^
commands = {
    '^!startbans': 'start_banning',
    '^!blacklist': 'blacklist_user',
    '^!bld': 'blacklist_date',
    '^!unlist' : 'unlist_date',
    '^!whitelist': 'whitelist_user',
    '^!stopbans': 'stop_banning',

# Initial IRC socket connection and authentication
s = socket.socket()
s.connect((chat_host, chat_port))
s.send("PASS {}\r\n".format(chat_pass).encode("utf-8"))
s.send("NICK {}\r\n".format(chat_user).encode("utf-8"))
s.send("CAP REQ\r\n".encode("utf-8"))
s.send("JOIN #{}\r\n".format(chat_chan).encode("utf-8"))

mitigation_active = 0

# Function for threaded asynchronous functions decorator @async
def async(func):
    from functools import wraps
    def async_func(*args, **kwargs):
        from threading import Thread
        f = Thread(target = func, args = args, kwargs = kwargs)
    return async_func

# Sends messages to chat
def chat(sock, msg):
    sock.send(bytes('PRIVMSG #%s :%s\r\n' % (chat_chan, msg), 'UTF-8'))

# Permabans users
def ban(sock, user):
    chat(sock, "/ban {}".format(user))

# Unbans users
def unban(sock, user):
    chat(sock, "/unban {}".format(user))

# Times users out
def timeout(sock, user, secs):
    chat(sock, "/timeout {} {}".format(user, secs))

# Punishes chatter with specified method
def punish(chatter):
    if punishment == 'ban':
        ban(s, chatter)
        print('Banning {}'.format(chatter))
        timeout(s, chatter, timeout_duration)
        print('Timing Out {}'.format(chatter))

# Gets list of chatters and updates admin list
def get_chatters():
    # Loop ends when a value is returned
    global admin_list
    while 1:
        chatter_list = ()
        admins = ()
        # Uses try because sometimes the connection times out
            r = requests.get('{}/chatters'.format(chat_chan))
        if r.status_code == 200:
            r = json.loads(r.text)
            # Builds the list of chatters
            for chatter in r['chatters']['viewers']:
                chatter_list += (chatter,)
            # Dynamic moderators list, kinda hackish but if you unmod someone they will be removed on the next loop
            for moderator in r['chatters']['moderators']:
                admins += (moderator,)
            admin_list = admins
            return chatter_list

# Function for returning the user's creation date
def creation_date(user):
    # Loop ends when a value is returned
    while 1:
        # Uses try in case of request timeout
            r = requests.get('{}'.format(user))

        if r.status_code == 200:
            # Captures only YYYY-MM-DD
            date = re.match(

# Thread for watching and banning chatters
def watch_chatters():
    global chatter_list
    while 1:
        # Gets the list of chatters in the room, needs to run while mitigation is off
        chatter_list = get_chatters()
        if mitigation_active:
            for chatter in chatter_list:
                if chatter in banned_users:
                if chatter in whitelisted_users:
                if creation_date(chatter) in banned_dates:
                    if punishment == 'ban':
                        ban(s, chatter)
                        timeout(s, chatter, 3600)

                    print('Current number of banned users: {!s}'.format(len(banned_users)))

def process_chat(chat_object):
    user =
    msg =
    # Initialize variables
    global banned_users,whitelisted_users,mitigation_active,banned_dates
    banned_users = []
    whitelisted_users = []

    banned_dates = []

    #Processes possible commands from the command dictionary
    for command,action in commands.items():
        if, msg):
            #manual blacklisting of dates, uses GMT always
            if action == 'blacklist_date' and user in admin_list:
                input ='^'+command+'\s+([\d]{4}-[\d]{2}-[\d]{2})', msg)
                if input:
                    #adds date to the banned list
                    chat(s, 'Error: invalid format. Use !bld YYYY-MM-DD')
            # Manual unlisting of a date, can also !stopbans to clear the list
            elif action == 'unlist_date' and user in admin_list:
                input ='^'+command+'\s+([\d]{4}-[\d]{2}-[\d]{2})', msg)
                if input:
                    chat(s, 'Error: invalid format. !unlist YYYY-MM-DD')

            #Automatic lookup of a user's creation date blacklisting it.
            elif action == 'blacklist_user' and user in admin_list:
                target ='^'+command+'\s*@?([\w\-]+)', msg)
                if target:
                    #Makes sure the user is actually in the room to prevent erroneous bans.
                    if in chatter_list:
                        user_date = creation_date(
                        chat(s, 'Blacklisted: {}'.format(user_date))
                        chat(s, 'User {} not found in the room. Check spelling or try again in 15 seconds.'.format(

            #Stops bans and clears blacklist
            elif action == 'stop_banning' and user in admin_list:
                mitigation_active = 0
                banned_dates = []
                chat(s, 'Turning off chat mitigation.')

            #Starts banning users
            elif action == 'start_banning' and user in admin_list:
                mitigation_active = 1
                chat(s, 'Turning on chat mitigation ═══█❚')

            #unbans and prevents future banning of the user
            elif action == 'whitelist_user' and user in admin_list:
                target ='^'+command+'\s*@?([\w\-]+)', msg)
                if target:
                    chat(s, 'Whitelisting user: {}'.format(
# Thread for reading chat and watching for user commands
def read_chat():  
    # Starts infinite loop listening to the IRC server
    while True:
        response = s.recv(1024).decode("utf-8")
        #PONG replies to keep the connection alive
        if response == "PING\r\n":

        #separates user and message.
        chat_object ='^:(\w+)![^:]+:(.*)$', response)
        if chat_object:
if __name__ == '__main__':
    chat(s, 'Any questions???')

Thursday, November 12, 2015

Nukulibrium Art Assets

Concept art for a potential game I'm working on. Sketches by Jody Osentoski, tech tree by Joe Hopkins.

I'm imagining the intro/hype video to have the Death God throw a necrotic looking spear, only to have the Life Goddess wave her hand and turn it into a spray of flowers and a dove. The dove then flies up only to be struck by lightening and turned into a drumstick, which the God of Fried Chicken then catches and chows down on. Zoom out to game title, tap anywhere to begin playing.

Waximus, the God of Death - Rough Character Sketch

Waynia, the Goddes of Life - Rough Character Sketch

Drumstick, the God of Fried Chicken - Rough Character Sketch

Another idea for Drumstick.

Example objective tree of things the gods would need to help humanity build to colonize Mars.

Tuesday, May 19, 2015

Bad Experiences by Design

Bad design, well, sucks.

We live and play in a designed world. The screen you're reading, the seat you're sitting in, the electricity you're consuming is all there, for better or worse, by someone's design.

I can count the number of times these have been used on one hand.

Which is why it's important to study design, both the good and the bad, to understand how to build better systems. Thinking through systemic design is important. Without foresight, you can leave your users frustrated and extremely vocal about the system's shortcomings.

So how do you avoid a design problem like this? Well, a simple trick is to put yourself into the shoes of a future user. If they knew nothing about the design, would they understand what to do at a glance?


Another tactic is to test drive your design before it hits the big stage. Jesse Schell recommends using kindergartners. If they get your design, then everyone else will probably understand too. They're also pretty brutal with their feedback and hold nothing back. You'll recognize a problem very quickly when a 5 year old is tearing your design a new one.

Any door with an instruction manual is a design failure.

Design is like a joke, it's not very good if you have to explain it. How many times have you pulled on a door with a "Push" sign above the pull handle? This design flaw is EVERYWHERE! There are books with entire chapters dedicated to badly designed door handles.

It's pretty clear you have to push this, hence no "PUSH" sign.

Riot Games recently made a frustrating design decision with their League Point (LP) system. When you win a match of League of Legends, you gain LP. When you lose a match, you lose LP. Win enough, and you are promoted to a new shiny tier with a new shiny badge. Lose enough, and the opposite is true.

Sounds great right? A clear indicator of how well you're doing and if you're getting better or worse at the game! Well, sometimes.

Riot decided to add in an extra tier just above diamond (where the top 1-2% of the playerbase plays) called Master Tier. When they did this, they made it so players newly entering the Diamond tier could not gain or lose LP in a regular fashion. Essentially, you would win a game, get +10 LP, lose a game, get -30 LP. So a win and a loss was one step forward 3 steps back. Check out what it did to the Diamond player distribution:

Click the picture to make it bigger. The player count in Diamond V is the interesting part.

Currently ~73% of Diamond Players are stuck in Diamond V. This is significantly higher than any other tier's V distribution (For example, it's only ~42% for the Gold Tier).

This has left a lot of the top players frustrated. The system that's supposed to tell you if you're improving or playing worse is automatically set to tell you that you do not belong (regardless of how you're playing). The reddit rage is pretty hilarious to read.

That frustration is translating into gameplay. The top 1-2% of the playerbase is now trapped in the most toxic part of the player distribution. You have a mix of the frustrated players desperately trying to get to Diamond mixed in with the chill players that got Diamond, but don't care anymore and are learning new champions. Add to this a dash of tryhard rage stuck in a one step forward, three steps back cycle, and you get a play experience where every match is pretty angry. That anger is sucking the fun out of the game.

A system designed to give feedback on performance, now has a choke point that does the opposite. This has created a ton of frustration which is translating into toxic gameplay (people raging at one another, intentionally throwing games, quitting the games early). Riot Lyte recently gave a talk at GDC showing that this kind of toxicity makes a player 320% more likely to stop playing a game.
They probably want to fix this since their most diehard players are getting hit with this systemic toxicity. Lyte also has the solution in his talk when he says that "Clear feedback is everything." This would all be fixed if the LP system did it's job, and told players how they were performing. Fix that, fix the toxicity, everyone's happy. Hopefully Riot realizes this soon and saves the day!

Don't be a victim of bad design.
So when you're designing the next big thing, take a step back and look at it with fresh eyes.

Is it easy to understand?
Is it working as intended?
Can a 5 year old get it?

A little foresight goes a long way.

Tuesday, January 20, 2015

Sejuani Mathcrafting for Patch 5.1 (League of Legends)

Tomorrow Season 5 of League of Legends begins. This means that the ranked ladders will reset and and everyone will need to climb back up to the top! Generally Riot will do something like:

(Your preseason MMR + 1200) / 2 = Your new Season 5 MMR

Worldwide League of Legends player distribution.
Compliments of

1200 MMR is the average league of legends player. So Riot will do a soft reset pulling everyone towards the average. This means that I get to be matched with and against lower MMR players, who will probably make more mistakes than what I'm used to. To compensate (and win games doing it), I did a little math to figure out a solid build/strategy for early game dominance.

(One of the top ADC players playing against the very bottom of the playerbase)

Against less skilled players, games are often decided in the first 20 mins of the game. If you can apply enough pressure or demoralize the enemy team, they'll often surrender at this point. My favorite champion is strongest late game (~30-40 mins), so I need to adapt my playstyle/build for the start of the new season. Here's my plan (math included) for doing this.

How to win the early game

Have you ever heard of a player named Ryan Choi? He is one of the best Rengar players in the world. The reason I mention Ryan, is that he made popular an interesting strategy to mitigate early game statistical weaknesses on his favorite champion. He stacks Doran's items (items that are cheap, give very good stats per gold spent, but don't build into stronger items) until he has enough gold to afford his more expensive late game build. Here's an example of how it works:

My favorite champion is Sejuani. She is a late game monster tank that becomes pretty damn unstoppable as the game goes on. But like I already mentioned, most games are decided in the first 20 mins, so I need to tweak my starting item build path (much like what Ryan Choi does) to compensate for my weak early game. Here's the item that's going to win me games tomorrow:

Here's why. Sejuani's damage scales with her maximum health, and ability power. It usually takes a while for her to buy enough items to be really scary though. Early game, she has trouble staying out on the map due to running low on mana (fuel for her abilities that do damage). Stacking Doran's rings gives her extra damage, and extra mana to compensate for her early game statistical weaknesses. Here's some math comparing what we could buy when we recall ~7 mins into the game ~level 5 with ~1600 gold (We should already have our upgraded jungle item).

What would you want to buy with ~1600g, to be strongest in the next 5 mins of the game?
The idea here, is to get our upgraded machete as quickly as possible since it gives us 30g per large monster kill and a bunch of extra damage/sustain. On our next buy, instead of buying REAL items, you grab 3-4 doran's rings. BECAUSE THEY GIVE US MORE STATS than real items at this point in the game!!! We will have more damage, and due to the mana regen and passive (free mana per unit kill), we should never run low on mana in the jungle. We'll also be using some % max health seals/quints to make the health worth a little more as well (we already talked about why this is smart in a past post). If we buy 4, we're spending 1600g. We can sell these back for 640g, so we're really only down 960g. If we can farm a few extra camps, get a kill or two, or win a tower/dragon after this buy, the Doran's rings pay for themselves.

(The power of Doran in a championship game)

As the game progresses, we'll sell off our Doran's rings to make room for better items. Hopefully we will have already made a bigger early game impact by the time that happens. The season resets tomorrow (1/21/2015), so feel free to tune into my stream on Twitch if you'd like to watch and see for yourself:

Watch live video from GundayMonday on

Thursday, January 15, 2015


New year, new goals.

Over the past year I focused a lot on my job at Quicken Loans. Would spend weekends building my coding chops (I am now a SQL deity) and learned how to do a lot of cool stuff. But I didn't get a chance to do a lot of the things I used to love. This year I want to fix that.

Got over my fear of public speaking in this band. Also my fear of everything.

Music has always been a big driving force in my life. Nothing is better than a great song. I admire those that create masterworks capable of shaping emotion from sound. My heroes are those that conjure the obscure, the triumphant, and the different kinds of tunes that make feet tap and smiles form.

(My favorite song)

I used to make music every day. Last year, maybe a month or two? And I only finished two songs.

This year, I want to change that. I want to create a full album that I can really be proud of. I want to take my time and really do it right. Spending an immense amount of time focusing on tweaking the little things to make it perfect. Don't even care if anyone else likes or listens, this one's for me.

So that's resolution #1, make an entire album of music that I can be proud of.

Next resolution's a little nerdier. I'm a pretty good League of Legends player. I'm the best Sejuani (Pig riding champion) in North America currently, and am in the top 10k players out of the entire continent (Just hit D3 ranking last night!). That's pretty good for a game with a multi-million playerbase. I want to do better though.

Riot recently created a new Master Tier to hold the absolute elite of the competitive player base. I want to break into it. I want to do it my way too. Most of the players up there use a specific playstyle that specializes in killing other players (they carry bad teammates this way). I want to break into the top tier by playing tanks and supports (champs that specialize in making teammates better). I'm already pretty close, and I think it's doable, but there aren't many tank/support players currently in the top 0.01% of the player base. I want to be one of the first.

Resolution #2 is to break into Master Tier for my favorite game while still having fun and playing it my way.

3rd and final resolution coming up (Wanted to keep it doable!).

Watch live video from GundayMonday on
Recently built my own computer from scratch, and started streaming on Twitch. This is honestly one of the most fun things I've ever done. After ~2 months, I have some quality individuals hanging out in my chat watching me play. Which is super weird! Complete strangers are looking at me while I play video games and sometimes posting penis emoji (seriously, what do you think will happen if you click that link?) all over my stream! But it's awesome and SO MUCH FUN.

I want to get better at streaming. I am going to arbitrarily validate my success via my follower count. Right now I have 58. I would like to shoot for 1000 by the end of the year. I think that's doable if I keep at it, but definitely a tough goal to have (wouldn't be fun if it were easy). Plus, always nice to make new internet pals!

So there you go. Resolutions for the year. Wish me luck!

Monday, December 29, 2014

How To Deal With Toxicity in League of Legends

What is Toxicity?

Toxicity is any in-game behavior that negatively affects other players. That means your average toxic player could be doing anything from intentionally throwing the game, to simply being a jerk in chat. Here are a few quick examples from the League of Legends tribunal, as read by Stephen Hawking:
The phrase "toxic" was carefully chosen, since players exposed to toxic behavior, will often become toxic themselves. This can lead to a huge positive feedback loop (for negative activity) where the toxicity flame can literally (and figuratively) rage out of control. That is, unless you stop it early.

More often than not, the toxic player is simply upset and not trying to be a complete scumbag. In this post, we'll go into detail about how to defuse toxic situations and optimally work with difficult teammates. Now trolls do exist, and we won't always be able to stop everyone, but more often than not these tactics work. The same methods we talk about are used by hostage negotiators and behavioral psychologists, so feel free to use them outside of video games (I know I do every day!).

Why you should care about this

Dealing with toxicity is a pretty common problem that most players feel powerless about. This is the wrong way to think about it. If Riot can influence how players behave by changing the color of a font, then we can definitely change the behavior of our teammates with our words and actions.

I'm not playing games with you. You're playing games with ME.

Here's a thought experiment showing why this is useful. Riot recently mentioned that 95% of active players in 2014 never received a punishment (for behavior) of any kind. Which is great! Most players you play with aren't scumbags! But if you do some math...

95% of players never punished for toxicity.
That means 5% of players were punished for toxicity.
5% means 1/20 players were toxic in 2014.
With 10 players per game of league of legends, then 50% of your games have a toxic player.
With 5 players per team, then 25% of the time the toxic player is on your team!

We're going to run into difficult players in 1/4 of our games. I'd be willing to bet that the 1/20 ratio holds up when applied to real life as well. Definitely worth knowing how to deal with toxic people since they're all around us.

Okay, so how do we deal with toxicity?

Most of this I'm going to paraphrase from Eric Barker's very excellent blog (which I highly recommend). I've applied his ideas to a team setting with a League of Legends focus. Here's how you deal with a toxic player.

Step 1: Keep calm. 

One person is freaking out and going toxic. Two people freaking out is even worse. Dr. Albert J Bernstein refers to the toxic state as "dinosaur brain", which is very fitting:

…the basic idea is that in many situations, you’re reacting with instincts programmed into your dinosaur brain, rather than thinking through a situation. If you’re in your dinosaur brain, you’re going to play out a 6 million-year-old program, and nothing good is going to happen. In that case, the dinosaur brain of the other person is going to understand that they are being attacked, and then you’re responding with fighting back or running away, and either one is going to escalate the situation into what I like to call the “Godzilla meets Rodan” effect. There’s a lot of screaming and yelling, and buildings fall down, but not much is accomplished.

Never panic, always keep a level head and think through the situation.

Step 2: Ignore the toxicity (don't get baited).

Dr. Bernstein recommends treating the toxic individual like a child. When they're throwing a tantrum, do you argue with them about why they're being a baby? Of course not! Dismiss their actions and focus on the underlying problem. Do not drop to their level. Ignore the toxicity, and zero in on what's causing it.

Step 3: Slow down the situation and make them think.

We want the toxic player to slow down and start thinking. We need to say things like:
"Please help us understand, we'd like to help."
"Why is this happening and how can we fix it?"
"What can we do to help?"

Notice that all of these can't be responded to with a simple yes/no one-word answer. We're trying to switch the toxic player from dinosaur brain mode to thinking mode. This will force them to start answering open ended questions that require a lot of typing. We want to avoid any criticisms that could put them on the defensive. So stay away from "You" and focus on "We" statements. This makes the toxic player feel like they're still part of the team, and stops them from feeling attacked.

I'll often offer criticisms for a single player in the form of an open ended question. If a player is dying a lot (due to mistakes), I could say:
"You need to stop overextending and dying, it's costing us the game!"
But that will turn on the player's dinosaur brain and put them on the defensive. Instead I prefer to say:
"What can we do to stop dying so much and win the game?"
I'm saying the exact same thing, but now it's constructive and inclusive versus negative and alienating. The open ended nature of the question also appeals to the thinking brain instead of the dinosaur brain.

Slow down the conversation with questions like this to calm down a toxic player before they go beyond saving.

Step 4: Let them have the last word.

Leave your ego at the door. Your goal is to stop the toxicity and win the game, not proving that you are right and the toxic player is wrong. Give them the last word and stomach any of their crap until you've claimed victory.

As a jungler, you'll often be blamed for every single thing that goes wrong in a lane. There are a lot of players out there that need to blame something besides their own incompetence (or poor luck) when things turn for the worse. These are the same players who will push up in lane without wards and then cry at their jungler for not anticipating that they were going to get ganked. Sky sums this up nicely in one of his videos:

Now a win or a loss is shared amongst a 5 person team, and there are always improvements to be made and mistakes to avoid. That said, raging at your teammate WHEN YOU F*CK UP, is one of the worst things you can do for your team. More often than not, you piss off the entire team (they will probably mute you) making them play slightly worse with their dinosaur brains on. Sometimes you'll start a chat battle and then one of your teammates will type "Stop being an assho" right before they die (you can't move or do other actions while typing in league). Raging, nitpicking, or complaining about teammates does nothing to help your team win. Nothing.

So how do you stop it? Lie.

"You're right, it's my fault. What can we do differently so we do to turn this around?  Where should we focus on the map since they're ahead now? How can I help us win?"

This will usually calm the rager (and your team) down and switch the conversation back to team strategy. They will probably continue being a jackass. Hold your tongue (errr typing), and let them get it all out. Good players have enough EQ to suck up their pride and win games. Part of being a leader in league (and in life) is knowing how to stomach the special players that grace our games from time to time long enough to get a victory on the board.

The ends justify the means. Let the toxic player have the last word if it means victory.

Final Words

Sometimes the player that can control his teammates best is the one who will win the game. Here are the 4 steps necessary for fighting toxicity and pushing players towards teamwork:

Step 1: Keep calm.
Losing your cool will create two toxic players instead of only one.

Step 2: Ignore the toxicity (don't get baited).
Do you argue with a screaming toddler? Don't validate the toxicity.

Step 3: Slow down the situation and make them think.
Ask open ended questions.
Avoid statements that put the toxic player on the defensive.
Use "We" instead of "You".
Words matter. Choose them wisely to disarm your teammate's toxicity.

Step 4: Let them have the last word.
Suppress your urge to be right if it means winning the game.

And remember, after the game you are free to do whatever you want. Best of luck everybody!

Want to see these tactics in action? Want to learn how to jungle? Follow me on Twitch.

Wednesday, November 19, 2014


Today I want to talk about and a recent decision they made that could have been executed better. If you're not familiar, Twitch is an amazing platform designed for gamers to broadcast themselves playing games out to a pretty avid audience. The tools are extremely mature, the community growing, and Twitch was recently bought by Amazon for 970 million dollars.

Twitch - Making it possible to live in your mom's basement WHILE following your dreams. Kappa

And it deserves every penny. Twitch created a way to make professional gaming financially feasible. There are gamers out there making around a million dollars in annual salary. If you're good enough, and entertaining enough, it's feasible that you can bring in ~$8k per month just from streaming yourself playing games (Like Aphromoo in the video below).

Remember how I was complaining about certain players being ranked higher than me in League of Legends? A couple months ago, I finally hit my goal of reaching the top 1% of the 67 Million+ playerbase (old data, probably bigger now). That's kind of a big deal. I used to be ranked 27th in the world at Dr. Mario for the Wii, but that game probably had less than 10k players, and being a top player was like being an honors student in special ed. With League, being better (or at least ranked higher) than MILLIONS of other hyper-competitive players is a pretty solid accomplishment. My team recently won the League of Legends tournament at Youmacon against top Michigan players too. Long story short, I'm pretty confident that I'm good enough at this game to stream on Twitch and actually have at least a handful of people pay attention to me.

So I started streaming this week. I built a gaming computer from scratch, configured my stream via Xsplit, and cleaned up my channel so it's all pretty and welcoming. Even messed around with some Twitch Bots to answer questions in my stream automatically. I still have no idea what I'm doing, but so far it's been a lot of fun!

After two nights of streaming, I used the Twitch "Highlights" feature to make some video clips of me and my team making the top 1% of the player base look silly. I main the pig-rider champion (naturally), which makes this even more fun since the vast majority of the playerbase thinks that she isn't very good (I think they play her wrong). Anyway, Twitch has a nifty feature which lets you export these clips directly to youtube so you can make things like this:

So I was surprised this morning when I went into my broadcast file from the night before and noticed that ~half of it had been muted by Twitch. Apparently they have a new service which scans stream videos for copyrighted music, and then mutes a 30 minute block of audio around whatever track they've found.

Even worse, this service is terrible with false positives. It gets confused and will mute music from the game being streamed. It mutes music made by the artist in their own streams! It even (incorrectly) muted a few official twitch videos! There isn't any feedback mechanism explaining why your audio got muted either. So I have no clue what songs to remove from my playlist to fix the problem! People aren't happy.

As a n00bie streamer and amateur musician, this decision makes zero sense from either perspective. As a streamer, this is going to make me hate and stop using any music that mutes my audio. As an artist, I would never want my music to be blocked for any reason. Streamers listening to my tracks are supplying free advertising for me, similar to how League of Legends became the most popular game in the world driven largely by free streamer word of mouth (or broadcast) hype. Sure the music industry folks won't like that, but there are MUCH smarter ways to solve the problem of getting paid.

It's not the easiest task to make money online as an artist.

This is especially true since most stream viewers aren't tuning in to listen to background music. They are there to watch the player pull off some highly skilled gameplay, or hear the player's thought process, or interact with a community of like minded peers. The background music is just there to set the stage, and it makes no sense to censor the entire production if the music sounds similar enough for a faulty algorithm to flag it as copyrighted content.

"BUT WHAT ABOUT FIGHTING PIRACY??!??" the music industry cries!

No, stop right there. I'm one of the few people who still buys music. I think pirates are f*cking scumbags and am not shy about sharing this opinion openly. Every song I played on my stream is from a CD that I purchased directly from the artist at one of their shows or from their official online store. So it's comical to me that my videos (which less than 50 people have actually watched) are being censored due to background music that I already paid for.

You can always build a better system.

So what's a better way to do this?

Making the censoring process Opt IN instead of Opt OUT would be a great start. Currently artists (who do not want their music censored) cannot turn the censoring off because their music is automatically included in the list to block. Sure you'll have a handful of Nicklebacks that will want their money, but I would want that crap censored anyway. Creating transparency over what can and can't be played would be amazing too. If a Spotify or iTunes or Pandora were to make a filter for Twitch approved music, they would gain A LOT of business. Another thing Twitch could do is simply pay out a fraction of any revenue to artists as royalties. You'd want to make it proportional to their time on the stream, and this would likely be far less $ than the artist would get for being included in the soundtrack of a movie or tv show since it's only background music. This again would only be for the Opt IN scumbags.

Please give me the opportunity to promote and pay my favorite artists instead of censoring them.

Or even better, set it up so streamers can choose to donate a fraction of their ad earnings to the artists they listen to. I would do this. I would love for the Tally Halls and the Aquabats and the Mustard Plugs of the world to make some extra cash so they can make more music for me to enjoy every day. By opting in (as a streamer) to this system, you unlock the ability to have those artists' songs unmuted from your stream.

BOOM everyone's happy.

This wouldn't be a lot of money either. Probably ~$10 out of a $10k monthly paycheck judging from Spotify artist revenue. Personally, I would love the option to give more to my favorite artists out of my streaming revenue (maybe a flat % of whatever I make?). That would create a feedback loop where the music industry would want to support streamers and streamers would want to support the music industry. I'm inclined to believe that most people will opt into a system like this, given the chance.

So that's my two cents on how to fix a system to make all parties happy, instead of most parties miserable and angry. What do you think? Is there an even BETTER way to do this? Let me know in the comments below. Honestly curious what others think!

Give me a follow on Twitch if you want to watch me ride a pig and throw ice bolas in a virtual world against other really good players. Also, feel free to ask questions in the comments below if you'd like to try Twitch for yourself and want some help setting up. Took me about a month to figure out and I'm more than happy to spare you from a couple setup headaches!