Skip to main content
whitep4nth3r logo

2 Jan 2024

46 min watch time

Entertainment as Code

Learn about streaming live coding, and how writing silly code in front of a live audience is a powerful (and hilarious) way to build community.


Click the video above to play

Slides

Transcript

My name is Salma Alam-Naylor. I had to double-barrel my name when I got married otherwise I would have been a disease. And this is entertainment as code! [Heavy rock music]. That's where you clap! [Applause].

I write code for your entertainment. I'm a live streamer on Twitch, software engineer, and developer educator. I got Covid for the first time a few weeks ago, when I started writing this talk, and I change my hair all the time. This hair cut is still six years (I meant days) old. Still not sure about it!

Let's travel back to 2008, when I graduated from the Royal Northern College of Music in Manchester with a degree in composition. I wanted to be a film composer for your entertainment, and, at the time, I was also in a folk band. We released an album, played weddings and festivals for your entertainment, and I was also making terrible websites, graphics, and album art for my musician friends. But as a musician, in order to pay the bills, you usually end up being a teacher.

My name's Salma, one of the lead tutors here at the School of Rock and Pop. We combine the possibility to perform, each centre holds two gigs at recognised rock music venues, a chance to meet like-minded teenagers and rock out in a way that can't be done at home.

I actually started learning the drums properly like eight weeks ago. So it is a lot of fun. Didn't know how to play the drums then.

Anyway, in 2010, I set up the School of Rock and Pop in Manchester, teaching children how to be in rock bands for your entertainment. It was about helping them put music into a real tangible context rather than practising alone in their rooms. And I really liked this whole teaching thing, so I got a teaching qualification, and I worked as a music teacher in secondary schools and sixth forms for a few years. Around this time, I was also a musical comedian, for your entertainment. We played some good gigs, won some competitions, and we went viral on the internet a few times. Unfortunately, you can't watch our music videos now because, unlike HTML, JavaScript, and CSS, some comity is not evergreen.

What is funny, though, is that whenever I'm on stage with a mic, I instinctively try to tell jokes. I need to, like, stop myself. I'm not going to tell any jokes today, but I do just want to take a brief intermission and talk about a new business venture that I'm working on now I'm on the stage, now, because I've got your attention. I love tech. As I'm sure all of you do here. And breakfast is the most important meal of the day. You all love breakfast more than tech. So I want to merge the two. And open a tech-themed breakfast and brunch bar. Tech-themed breakfast and brunch bar called TechFast, and there will be things on the menu like Full Stack of Pancakes. Eggs and JSON. POP3 Tarts. ChatGPTea. Serial Numbers. And it'll all be served in little containers. Microservings. And the service will be Blazing Fast. And if there are any investors in the audience today, I'm trying to raise the chia seed round right now. Please talk to me later at the social. No more jokes! It's time to be serious, Salma, which is often the feedback I get on my PRs.

Let's fast-forward to 2014 when I quit teaching and I got my first job in tech. I don't have the time to tell the full story today. It's on my YouTube channel if you're interested, but this led to many more jobs in tech. As a front-end developer and a tech lead at product agencies, start-ups, global eCommerce brands, you know, boring, boring same old, but in 2020, as a lot of other people have alluded today, everything changed. The pandemic descended, everyone stayed inside, and we all found new ways to spend our time. And here's where Twitch comes into my life.

The main focus and the largest categories on life streaming platform Twitch have always been centred around gaming, but as time went on, creators started streaming music, arts and crafts, talk shows, charity events, 24/7 live feeds of farm animals — anything you could probably ever dream of. That was not a joke. In 2020, for a short time, I was also glued to a behind-the-counter live stream of the comings and goings of a fish-and-chip shop. I think it might have been in Brighton. I'm not sure. I'm probably making that up.

Twitch ended 2020 with its biggest numbers ever, 17 billion hours were spent on Twitch in 2020 which was 83% higher than in 2019. I was part of that. I started watching Twitch in the first lockdown of 2020, and the category that caught my attention was software and game development. People were writing code, live on stream, and people were watching. It sounds like madness! In the last year, over 14 million hours of software and game development streams have been watched. The category has around 1.6k average viewers at any one time, and there are always around 100 live software and game dev channels at any one time. It is a small category compared to gaming but with that comes a big opportunity. On Thursday 25th June 2020, I went live on Twitch for the first time. Under the user name whitep4nth3r, I don't have time to tell the story about this user name, ask me later if you're interested. It didn't make sense, but it was quite unintentional that panthers would become integral to everything, and you will see later. Here is the earliest stream clip I have. It is not the first, but it's very early.

So standard and DROP D is working, but DADGAD is not.

Typical stream, typical development, everything goes wrong all the time. In this clip, I was building my first open source app called the Fretonator. It is true. That's not a joke! It exists now. You can go to see it. The Fretonator. And I was having problems. People in the chat were helping me.

The Fretonator is a guitar app to help you learn scales and modes, and you can use it in the browser. So why did I do this first of all? Other than boredom and Boris not letting me out? The channels I saw were mainly back-end development, you know, C Sharp, Rust — boring stuff! They were being streamed by mainly men. I thought maybe I could fill a gap in the market. I'm not a man, and I'm a front-end developer, that's my specialism. Also, I started building the Fretonator a few months before because I wanted to learn Angular, and I learn best by building stuff, and putting things into real context. I was also building this app for my husband. He wanted to learn scale and mode theory on the guitar, but my traditional music-teaching methods why failing him and he desired a way to learn interactively on his own. I show what I'm building. It does exist. You choose a starting note, you pick a mode that you want to learn, and you use the guitar fretboard to play scale. It uses the web audio API as well. You can dive deeper into the theory of modes and scales if you want, but most importantly, every scale for every note comes with a backing track for you to practise with. 160 jam tracks for every note and scale combination were painstakingly manually source (not using ChatGPT) for your entertainment.

So the Fretonator is about rather than just playing the scale on your own without any more musical context, it's about putting the theory into practice in tangible and meaningful ways much like the mission of the School of Rock and Pop. This concept of putting theory into practice, of making tangible things has underpinned everything I do in tech and on my stream, for your entertainment.

My original cheesy tag line, build stuff, learn things, love what you do, put the focus on building. Which is representative of how I learn. I actually retired this tag line this year because I had the realisation that it was too similar to "Live, laugh, love". [Laughter].

You can still buy this, though, if you want to enjoy living, laughing, loving. But through streaming on Twitch during the pandemic, I was starting to discover that demonstrating and practically applying technical concepts in front of a live audience was making tech more accessible. It was making it more human. Pretty much exactly like when you perform music with others. It was also at times like pair programming with 100 people all at once. You know how like camaraderie developments through top experiences, and especially through the inevitable pain and suffering of software development, like this ...

I quit. I quit! I'm going to do something else. I can't make this. Every step of the way is just an absolute piece of shit. [Laughter].

So the documentation was telling me that I needed to provision an SSL certificate in order to make an API call on my local machine. And I was just done. But when you have problem-solved as a team with you and the viewers, and your code finally works, you feel good, right? Those brain chemicals, they bring you closer to, they form those human relationships even more.

If it does work, I will feel sick that I have succeeded. Argh! Look! [Laughs]. I did it! I did it! I did it!

So as I was working out what this whole streaming thing was about, people were coming, they were watching me, they were helping me, and returning back to my stream days later to see progress. They were pair-programming with me, and wanted to see me succeed. Without even setting out to do this, there was a community forming around me and my stream. And in just seven days from that first day that I went live, I had streamed enough and had enough average concurrent viewers to gain affiliate status on Twitch which meant I could make use of community engagement tools such as, VIP status for viewers, channel-point redemptions, and people could throw Twitch currency at me in the form of subs and cheers. So I wrote about what I learned in those early days on my blog, and the most important thing I took away from this is that the most valuable element to your stream, whatever you stream, is you. The code you are writing is only a small part of the experience. Viewers don't actually watch you to learn how to code. That is just a side effect. They come to hang out with you to feel safe in the presence of people with similar interests, and to be entertained.

Now, I haven't rehearsed this slide because I added it after a conversation with Maggie at lunch. But, in the before times, right, before there was software and game development, the one category that programmers streamed in was Science and Technology. And science and Technology became overrun with 24/7 live feeds of farm animals and earthquake detectors, and just nonsense, and so we raised an issue on Twitch User Voice for a particular category for us — Software and Game Development. It was going well, and we were really looking forward to the new category launch but Twitch decided to release a new category before our category which was "Hot Tubs, Pools and Beaches". It was basically a soft porn category designed to take away all the people who want to sit in a hot tub from Just Chatting and to put them in their own category, presumably to hide them, but they're just more easily discoverable now, but the core theme of Hot Tubs, Pools and Beaches is that people follow or sub, or donate in order to get anywhere name written on the streamer's body, so they can feel like they're part of something. They are closer to the streamer, and they are in the stream.

Now, Hot Tubs, Pools and Beaches became a meme in the programming community, people put hot tubs in their overlays, writing names of their followers on their faces. The conclusion of all of this deep down at the root of everything, everyone just wants to be part of a stream on Twitch. Whether it is getting your name written on someone's leg, or having your avatar and user name rain down on the stream in an exciting way, everyone wants to be part of it. And this is going to become a running theme later on.

So I didn't start streaming from a hot tub, but the community was forming around me, and to support that, I created The Claw Discord on 30th July 2020, apparently a claw is a group of Panthers, but I've only seen it referenced once, so I don't know whether I got that wrong. But people started gathering here when I was offline, relationships started to form, and now we have a co-working channel where remote workers from around the world log into the channel, they have their cameras on, and they just keep each other company while they're working from their bedrooms all day, and it is pretty nice to see.

So Twitch viewers are not passive like YouTube viewers, they're active participants in the experience. And so I started thinking about how I could build on this, and how I could bring people further into this the stream make them feel even more involved with what they were experiencing, without having to write their name on my face.

So I built a Twitch bot, and this is an application built using the Twitch API and other third-party tools, to allow viewers to make things happen on the screen via chat commands and channel-point redemptions to level up their participation in the stream.

There are pre-existing tools that exist to bring interactivity to your streams if you can't build your own, such as NightBot which I use as well. Making a Twitch bot is not a new and innovative thing, but here I had the opportunity to build a Twitch bot that reflected my personality and the entertainment value of the stream I wanted to build on. Plus, building stuff for your stream live on stream with viewers for viewers is the best way to test functionality, get the QA going, crowd-source ideas, and again make people feel part of that process, part of the product, and part of the stream.

Here is some probably very over engineered architecture for your entertainment. This is everything I used to currently power my stream interactions, and everything that happens. We start with p4nth3rb0t, storing stuff in MongoDB, it sends events over a WebSocket connection, the back-end. It uses the Twitch API and a third-party wrapper around the Twitch API called tmi.js. We have two apps listening for WebSocket events. There is a types package that both the front-end and back-end applications use, and it also uses a Discord API and all of this is brought together in OBS, which stands for "open broadcaster software" which I use to stream, where each piece of functionality is added to my stream scenes as what we call "browser source URLs". If you can get a browser URL in the browser, that does some stuff, you can easily put that into OBS so it can do the stuff there. I also use another tool called Aitum that allows me to control OBS itself Twitch stuff. That's it. I've been building this over three years. I want to show you some of the key functionality of my Twitch bot. The whole thing did used to be open source but it got to bespoke, far too silly, now it is private, but I have core maintainers in my community who help out with bugs and features, and general fun stuff.

So follows, subscriptions, and cheering are core part of the Twitch experience. And as a viewer myself, I like to sneak into other viewers' streams and follow streamers to see how much I become part of the stream when I press the follow button. If they don't notice me, I will bounce right out, because making your viewers feel welcome and part of something is key to getting them to stick around, especially in this smaller more intimate category of software and game development. So here's how my alerts started out.

PewWTD, thanks for the follow. Pew Pew. I need a Pew Pew Panther.

So that was using StreamLabs alerts, added as a browser source to OBS. I did make a Pew Pew Panther. It's actually my most used emote because my bot uses that the most. The bot uses the event sub API from Twitch which lets your application subscribe to events that happen on Twitch. When an event occurs for a subscription or follows, it sends my Twitch app a notification. When I receive a follow event, in order to protect against viewers spamming alerts on my screen, we first check for an existing follower in the database. If we don't find one, we find the Twitch user, I've got a wrapper around the Twitch API here, and send a follow event over the WebSocket connection. Most importantly, the event contains the follower name and their profile image which is how we will put the viewer into the stream. So there are a number of front-end URLs which are listening for WebSocket events from the back-end. Here is a little React component that powers all of the alerts. There's a queuing system because you want to account for a lot of things happening at once especially with a substantial amount of viewers, and each type of alert shows a different image and subtitle depending on what is sent. Each alert plays a different alert sound which both me and the viewer here when I'm streaming, all sounds are custom sounds written and recorded by me and my husband, and I do have a funny story about custom sounds.

When the repo was open source, I stored the MP3 files for alerts in my Google Drive and used environment variables to access them when needed so people couldn't steam the files from the open source repo. At random times, the alert sounds would just stop working, and it took me and my viewers months to work out why. It turns out that too many alerts at any one time would DDoS the connection to Google Drive and deny the bot access. So my Twitch viewers DDoSed Google, so that was fun.

Thank you for the follow!

This is when I accidentally coloured my hair to match my stream background. [Laughter]. Total accident. And I am yearning for that one now. Also, notice two other events that happened. One that changes the Panther logo overlaid on my camera at random, and one that rains down my Twitch emotes, all on separate browsers, listening to WebSocket events in the back-end. As you watch the stream, you accumulate channel currency, and you can choose to spend it on fun stuff set up by the streamer. I enable streamers to trigger the logo change manually by redemptions whenever they want, triggers a sound per Panther, and viewers can trigger the emote rain by rain, hail, snow, blizzard by writing in chat. It's gone through a lot of iterations throughout the years, including needing to limit the amount of emotes dropped at any one time because this was just ridiculous.

RIP my frame rate. That is when someone decided to spend stupid money on 50 gift subscriptions to my channel all at once. It broke everything, kept on coming, and, yes, we heard that guitar riff 50 times. That is entertainment. Writing code to make that happen live on Twitch was entertainment. Viewers making happening anything on my stream from anywhere in the world is entertainment. What sometimes happens unexpectedly as a result of writing that code is also entertainment.

So you probably also noticed in my screen clips that I show chat messages on stream. Chat is another custom browser overlay powered by the central Twitch bot which listens to message events from tmi.js and sends events over the WebSocket connection — extremely over-engineered. A lot of information is sent over the WebSocket to power chat messages, and viewers have been eager to act at QA for chat and suggest ideas for new features, such allowing the use of a marquee tag which is an undocumented Easter egg, and numberonym mode: a numeronym is a number-based word, numeronyms are used in tech to shorten long words such as accessibility, internationalisation, localisation, Kubernetes, et cetera. And here is the code for numeronym mode.

The makeNumeronym function splits the full message by space, and for each word it returns the first character, the count of characters in the middle, and the last. For some reason I published this to NPM so I could use it in multiple places and people are downloading it. Why? So that is fun. Because I've never used it in any other project, but go off. I also built a giveaway mechanism into my Twitch bot which are powered by typing commands in Twitch chat. To enter, viewers write exclamation mark win in chat. tmi.js listens for commands, so when the command is found, we run the handler for that command. If it reads !in, we enter the viewer into the giveaway. To draw, I type !drawga in chat, and a random winner is selected from entrants who are still present in the chat. We send the event over the WebSocket, browser overlays, and OBS, and the key thing here is to send the user's profile image URL over the WebSocket to put them in the stream. Here is a clip of the giveaway in action.

I like giving away things. Mo gets a T-shirt!

And someone else gets a T-shirt today! Congratulations! [Applause]. Well done! I seriously, just did something to my back! Right, so I've given away things like stickers, merchandise, JetBrains licences, FFConf T-shirts. The postage costs for sending things people around the world have got a bit much so I haven't given away much recently and it is very difficult and very non-inclusive to say UK people only! But it is lots of fun, and I got to build some cool stuff.

Back-seating has always been a thing. It is like an meme now. New viewers often come into the stream and tell me what to do with no context about the problem we are solving, and it is the worst thing ever, like back-seat driving.

Why aren't you doing this, I thought you should use this. Blah blah blah blah. Back-seating.

One of my viewers thought it would be a good idea to put back seaters in a literal car. While I was streaming, sent me these very lo-fi three drawn layers of a car that I added to the scene in OBS on the fly.

A layer in front of me. [Laughter].

The car has evolved and is now a permanent fixture in my stream and can be triggered my viewers.

One second ... two Taco Bells, please, with sparkling water. Thank you.

I've never had Taco Bell in my life. I don't know what it tastes like. Sparkling water is the superior water. Here is how the car works. Again, tmi.js listens for a command in chat. Exclamation mark BS. What BS stands for is open to interpretation. We grab the user name from the message and only put people in the back seat who are actually viewing the stream. The point of the car now is to be as offensively obtrusive as possible like back-seaters, and it looks like this.

Hey there!

There is all sorts of magic, like Aitum, filter-changing, and some tough. It's probably going to get worse.

Now I want to show you other silly things I built on stream that are not part of my stream, and how it brought people together, what we learned along the way, and just how much fun it was.

GeoCities, big up, GeoCities! Something so close to my heart. The original website builder of the 1990s. And in GCSE IT, while people were making spreadsheets and text documents, I was making websites with GeoCities. I don't know how I got away with it, to be honest. This is the first home page of GeoCities from 22nd October 1996. Left-aligned content, Times New Roman, full of links and gifs, and table-based layouts. Isn't that beautiful? The semantic HTML in there is pretty wild, description lists and description term, but it's not followed by a description definition. So I'm very disappointed. I'm very disappointed in GeoCities right there. I'm going to call them out on Twitter!

This is the Style Stage project. Style Stage, we have already have Stephanie Eccles mentioned today, maintained by Stephanie, about showcasing the capabilities of modern CSS. Your challenge with Style Stage is to completely change the look and feel of this HTML page with CSS only. So it forces you to be really creative, and learn more about CSS in the process. So I wanted to make Style Stage look like a GeoCities website.

There is a lot going on here, isn't there? If you've got internet been you can scan the QR code to go to this. It is responsive, right? And I know that is not authentic. But I couldn't not make it responsive. Now, I do know what you're thinking. Salma, how did you pull off getting those iconic dancing baby gifs in there without editing the HTML? I'm glad you asked. Base 64 encoded data URLs added as pseudo elements to existing HTML elements on the page, and assigned to CSS custom properties to be able to use those data URLs easily, because those string are long. It was a complete nightmare, that CSS file, because only more than one I've done of this, isn't there?

The fake visitor counter is also powered by a CSS animated pseudo element attached to the h2 above it, and, yes, I did manually specify 100 key frames, live on stream, much of the frustration of my viewers, as they were forced to watch me do it! I do what I want!

Other highlights include this stunning marquee using the papyrus font added by another convoluted pseudo element, powered by a CSS animation using transform: translate. It is all in the name of entertainment. And these globes! Which are powered by the CSS list style property, and a custom property of a data URL of another Base 64 encoded gif. I learned loads about CSS and how you can stretch the possibilities, and me and my Twitch viewers bonded over our love of the web of yesterday.

Speaking of 1990s internet nostalgia, I made a web ring. A web ring is a collection of websites linked together in a circular structure, usually organised around a specific theme, such as technology. And they were popular in the 1990s and early 2000s, particularly among amateur websites, so all of our websites in here. If you were a member of a web ring, you would display that on your website. So the aim of the claw web ring was to make it as easy as possible to display the web ring widget on any website built with any or no framework. I wanted to make sure that updates, for example, when new members joined the ring, would be automatically pushed out to all sites without a redeploy.

So what you see here is a web component, and clicking "join" takes you to the GitHub repo. You can navigate back and forth between the ring and click to go to a random site in the ring. To add yourself to the web ring, you open a PR to the Claw Web ring Repo and add an entry with your name and site URL. After the original release, I had 26 more people add themselves to the web ring, and for some, this was their first open source contribution.

When your PR is merged, this will make your site data available on a public URL which is fetched by the web component at runtime which means that every instance on every site of the web component stays up to date. To show the web ring widget your site, add the custom element tag and you include some optional fallback content in case JavaScript isn't available, or you don't want to use JavaScript at all which looks like this, progressive enhancement, and you can configure light and dark mode, whether or not to show the full scrollable member list, and is also a hidden Easter egg, of course. Just disappears. Why not?

And now, for the biggest meme of my streaming career, I built a random code generator, and it was the funniest thing I did on stream. This probably won't be funny today, but it was a kind of you had to be there. Suppose I needed JavaScript for my project, I select the options, I scroll down, and bam, perfect JavaScript for me to copy and paste into my project! Perfect. This is how it started.

Quality memes!

Chat's loving it.

I love it. I love it! I need to write more code!

How does this work? Don't even know any more! But here's the JavaScript example. It is a bunch of methods that return a random thing. Some methods return an array which will be processed by a helper function to return a random value from that array. Some methods mash together values. Here are some helper functions, get random noun, verb, single character, which was often used for nonsense variable assignments, and here are the verbs and nouns array. So when the random code is generated, we will always start with a function name which mashes a verb and noun together. For example, initialise array, and you can go through all of them. That is what writing code is, right? It goes on like that. This is the full — it is not the full, there are millions of lines of this. I'm not going to explain this, it's stupid. If you want to generate random code, maybe show it on your website, what I'm coding right now, similar to what I'm listening to right now on Spotify. You can, because I published it to NPM! Again, no idea why people are downloading this! What are you doing with it! There were 105 downloads in a week in September. But this was actually the first package I published to NPM live on stream, of course, and I wrote about it, and the blog post was really popular. If you search for "build, test, release node module" on Google, it is the top result with a featured snippet. It is like one of my biggest achievements that came out of writing stupid, pointless silly nonsense code in front of a live audience on Twitch. It doesn't matter what you do. The algorithm will decide. [Laughter].

This led me to publish a few other nonsense get random NPM modules and I did start building a random website generator, and a get random headline and get random tech business name but it wasn't funny enough. I received 75 pull requests to the original random code generator site before I turned it into an NPM module. People loved adding their own favourite programming language to the catalogue of random code generators, and again for some people, it was their first contribution to open source, and I'm warning you now, I'm going over, but not over the time I'm allotted in the schedule.

In August 2021, I achieved Twitch parter status, to be honest, it's not that special. There are many, many Twitch partners these days, but being a Twitch partner meant I could form an official stream team on Twitch, bringing the community closer together, the Claw currently at 28 members across multiple time zones streaming software and game development in a variety of formats and programming languages who are welcoming and inclusive to all, and, yes, I need to update the live, laugh, love banner on the top of that page.

I used this opportunity to add more functionality to my Twitch bot including go live announcements. Powered by the Twitch bot and the Twitch events API, so when a member goes live, an announcement is published in Discord, alerting all members who have opted in to the Discord role, bringing everyone closer together. We were not far now. For a few more miscellaneous examples, I want to show you some smaller projects.

So last year, I discovered a streaming channel called ZengoWeb, a development agency in Hungary, live streaming their work day from the office. It's great to have on in the background. There is a co-working vibe but it was difficult to remember their Twitch user names and who was who in the office. I decided to build something for them, another browser overlay to display each person's Twitch user name on the stream. Here's the moment when it first went live.

It works! There is a house! All right. Great!

So how does it work? It is a plain HTML page hosted on Netlify. In order to give the team overlay without the need to edit the code, it uses an edge function which is a serverless function that runs the closest server location to the request, using an URL query parameter to show team members working from home whenever they need to, by intercepting the HTTP request for the index page parsing the wfh query parameters, and modifying the response accordingly, and returning it, and the ZengoWeb office has a tradition of eating pancakes, so client-side JS that runs on page load that assigns a random team member a pancake emoji, so they know it's their turn to make, purchase, or source pancakes. The team have also submitted new PRs. I was excited to merge them all.

I've also experimented with creating some fun educational resources. One example of this is Game of Codes. It is an HTTP status code quiz and I think it might be a good fame for you, Amber. Here is the QR code if you have the internet. Here is a very sped-up video of me completing the quiz. I did it in one take. I didn't like try to think too hard or do it over and over again to get ten out of ten. This is my current HTTP knowledge. When the quiz is complete, it gives you a summary of what you got right and wrong, correct answers, so you can learn and try again. Game of Codes is written in plain JavaScript, and with Game of Codes, I also wanted to sow what is possible without JavaScript, without a JavaScript framework, or any dependencies, so instead of using a state management library, we are using good old JavaScript object to keep track of the game state, and the whole thing is written with a functional programming approach, so it is easily testable. There are no tests. And you might think ... [Laughter]. This is easy. Salma has used plain JavaScript. The HTML must have an identifier for the correct answer so JavaScript knows what I've selected to determine the outcome so I can do a cheeky, inspect the DOM, check the answer. Surely, I can game the system? I did think about that, of course. Each answer generated is given a string of random numbers to identify it by. One of them is correct, the game state knows which one, but there is no other way to know in the HTML. You could use the browser debugger but you would be like an mega nerd. I did have plans for competitions, a leaderboard, but at this point I was learning some projects don't need to be finished and can exist just as they are. Almost finished, I promise!

As well as sharing my love for GeoCities, sharing my love for the most enchanting, intriguing website of all time. I've been recreating a website that was burned into my brain since I first encountered it in 1999. It is hell.com.

This is my favourite part of the internet. Access prohibited. This is a private web. You're being rerouted to the public information site. I love it!

That is a random dialogue prompt thing programmed to come up, and the public information site is just Google. But when this happened to me as a teenager, I believed it. You can read up on the lore on Wikipedia, but the tl;dr is hell.com existed from 1995 to 2009, and I wanted to recreate that mystery on the modern web. There are too many Easter eggs and things to share, but I used the a combination of the page pages and user journeys described in Wikipedia, and the ones I found on the Wayback machine to create it before I'm clicking around. It is built with Astro and jQuery, because I wanted to preserve the nostalgia of an earlier web, even though it is the most popular JavaScript library used on the web today. It was difficult to get jQuery working in Astro, so I wrote about it.

If you like to blog, or want to write about it, the best things that are difficult and the problems you solved. The chances are someone else has experienced this too, and you can help people and yourself when you've forgotten how to do something. If I have a closing piece of advice to you, it is to ship your silly side projects. Have fun, like this stupid piece of website! It tells you whether I'm live on Twitch or not. It takes more inspiration from GeoCities, plays with CSS, the fake marquee makes another appearance. I learned a lot from making it, because silly things stick.

I remember vividly in primary school when we were learning about the effects of alcohol, and instead of just standing at the front of the class and telling us how dangerous alcohol was, our teacher spent the lesson wobbling around the classroom, slurring his speech, and generally being silly, making us laugh, but we learned. And I've never forgotten this lesson, and I've always drawn on this approach for inspiration when I was a music teacher, and it is one. Core driving principles of entertainment as code. I'm Salma, I write code for your entertainment. Find me opt internet everywhere as whitep4nth3r, and I will see you on Twitch! [Rock music]. [Cheering and applause].


Salma in her office, backlit with pink, smiling and looking into the camera.

Salma Alam-Naylor

I'm a live streamer, software engineer, and developer educator. I help developers build cool stuff with blog posts, tutorial videos, live coding and open source projects.