Past broadcasts

Session 131

Choose Your Fighter

We do some tweaking before the release of Blockchain 1.3, and then talk about what we want to do for the Historically Accurate Game Jam.

See more →

Session 130

The Only Blockchain You Need

We spend a long time making fun of blockchain projects, before working on our game which is also, strictly speaking, a blockchain project.

See more →

Session 128

Fog of War

We add a fog-of-war mechanic to the game. Also, adventures in programming the Unity Editor.

See more →

Session 127

Mountains

We can’t quite get multiplayer working, so we try making mountains in Blender instead. Also, we talk about what’s great and not so great about Metroid Dread.

See more →

Session 126

Tank Waifu

We deep-read tanks, tank games, and tank anime. Then Dom tries to fix our particle emitters.

See more →

Session 125

Decal Shader

We try to re-invent React in Unity, and then talk about screen-space decal effects.

See more →

Session 123

Lasersight

We play some Riftbreaker to see how they handled build mechanics on a gamepad. Next, we get rid of the targeting cursor in favor of a laser sight mechanic.

See more →

Session 121

Crosshairs

We get a better targeting cursor, and do a lot of philosophizing on how to control the game.

See more →

Session 112

Team Building

We’re in violent agreement that all great games need to include a dating simulator. Then, it’s time for our player to be able to build turrets of its own and make life challenging for their enemies.

See more →

Session 110

Wall Jumping

The tanks take a spin on the dance floor before finally learning how to turn left. Then we hop out of the second dimension to build a bridge to nowhere.

See more →

Session 109

Back in the Saddle

We’re back baby! It’s been a long break, and Dom still doesn’t have a good microphone, but the game must go on. In this session, the Unity tank finally gets to rotate, we give our players the ability to build walls, and then learn about terminology arguments in the Git team.

See more →

Session 108

ProBuilder Amateur Hour

We struggle to do basic things with a popular Unity tool. User error or poor design? You be the judge! Also: bare-bones multiplayer gameplay, a hasty outline of future game ideas, and the turrets make their re-appearance.

See more →

Session 106

Back to the land

Any self-respecting game needs foliage you can shoot, so that’s what we’re doing this time. Also: we take a look at a Unity multiplayer library called Mirror, and go toilet shopping for Dom’s new house.

See more →

Session 103

Fox Crab

We raid the Unity Asset Store for pre-animated models. We find a pretty good fox, and a pretty horrible crab.

See more →

Session 102

Collision Precision

Our RigidBodies and physics objects collide tonight…or that’s what we wanted them to do. In our second Unity session, Unity fights back, but we eventually convince to do what we want.

See more →

Session 101

Unity

We’ve decided to rebuild the game in Unity, but first, we need to learn how Unity works in the first place.

See more →

Session 100

One Final Jump

With our new vaccinated superpowers, we do our first stream together from the same room! We knock out some serious bugs in the jump point search algorithm and see it working in real game situations for the first time.

See more →

Session 98

Editor Surgery With Friends

We finally get the new map editor working in multiuser mode, with tile editing and entity placement. Also, more than one detour into the world of vintage surgery simulation games.

See more →

Session 97

Rolling with the Big Dogs

We learn the hard way (again) about soundchecking OBS and ad hoc cooling solutions for laptops. Then we attempt to add a cursor into our multiplayer map editor.

See more →

Session 96

Windows is Updating

Halfway through working on our re-vamped map editor, Windows decides that it needs to restart our stream machine. Join us on this journey of reusing our previous renderer for this bold new tool, while technical difficulties try (and fail) to stop us.

See more →

Session 94

21 Jump Point Street

Time to pick a better pathfinder, and we land on “Jump Point Search”. It’s similar other algorithms we’ve used, but optimized for a grid! A Visual Explanation of Jump Point Search Jump Point Search - author’s explanation

See more →

Session 93

The One Where Nothing Works

In which we make a total mess of the codebase, for what we think may turn out to be a good reason. We think. Also, Jeff’s audio is broken for over an hour, while half of Dom’s CPU cores go on a mysterious vacation.

See more →

Session 92

Recalculating…

After re-introducing pathfinding last session, we check out the new path caching Jeff added, but realize that the l1 algorithm we picked can only move in 90 degree angles. So we embark on an exploration of other algorithms available to us, and aim for the bright future of builders knowing how to walk diagonally. Notes/highlights: Today we learned about shiba inu coin via Vitalik Buterin’s donation to India’s crypto COVID relief.

See more →

Session 91

Losing Our Way

In which pathfinding AI makes its triumphant return, having been left to the wayside since the game went 3D.

See more →

Session 90

Stop Hitting Yourself

TFW the vaccine hits ✨ Here come some more mortars. We’ve got a funky version of our ballistic motion in place already, but this stream we start diving into actually calculating the correct angle for our shots. A lot of trigonometry is on the table in this session, so if you remember your high school math and physics classes, it’s a great time to tell us how hard we’re making this on ourselves.

See more →

Session 89

0.0001% of Communism

There’s some game programming crammed in at the very end, but this one’s mostly about one of the most important games released in the past decade. That’s right, this is the big Disco Elysium spoiler episode. We talk about time mechanics, the ending, the Left, how drugs and cops are portrayted, and the significance of trying to punch Cuno and missing. Notes/highlights The Idaho Stop: https://en.wikipedia.org/wiki/Idaho_stop “Punching Cuno In the Face Represents The Best of Disco Elysium”: https://www.

See more →

Session 88

The Lost Episode

This is just to say we have lost the VOD that was streamed on Twitch and which you were probably expecting in this post Forgive us Twitch doesn’t keep videos for very long so sweet and so cold

See more →

Session 87

Splash Mountain

Grab your pestle, because we’re making mortars today! But first, we start a fight our local SSH agent and test out a 3-player game session. Using EC2 instead of ngrok, our network performance is good enough for some real multiplayer fun! Then, we design how we want our mortars to interact with the game world, and start the process of adding splash damage and non-attacking bullets to our game systems.

See more →

Session 86

Rocketdog

We test drive a new engine feature moves particle emitters in sync with game entities. Dom’s rave review of the results: “Now the dog looks like it’s puking”. With that in the bag, we decide update the rocket triggering mechanism so the player only gets one rocket per button press. This is America, after all…no more handouts to rocket fans! Plus: Disco Elysium first takes, the Russian Civil War, and proto-communism in your favorite early civilizations

See more →

Session 85

Fake Money Real Explosions

Finally, the game gets the thing you’ve all been waiting for: rocket launchers. The ballistics look great, but we stumble into a new problem: how do we attach particle emitters to moving objects? Not a hard problem for a single-player game, but rather tricky in multiplayer. Along the way, we do some necromancy and bring our old HUD code back from the grave. Also: we discuss the Dogecoin boom, the slightly less impressive but still-booming XLM boom, and our accidental cryptocurrency wealth.

See more →

Session 84

Pumpkin Spice Doge Season

A high pressure system rolls into Manchester, and it brings a whole lot of weather with it. Or at least, one kind of weather for now… First, we add some more logarithmic sliders to our particle tool, and adjust the positions of our emitters on the dog. Then, the autumn leaves blow in, and it’s time to cozy up by the fire with a mug of hot chocolate. Notes/highlights: In discussing more Disco Elysium, we bring up Twine (a text adventure engine: https://twinery.

See more →

Session 83

Exploding Triangles

Emitters keep on emitting, and today we’re adding explosions to our bullet hits. We’ve put so much good work into the particle system, that today we get to create and try out a variety of explosions in the game with an instant feedback loop. We add gravity physics to our particles – letting the dust settle accurately from our new, majestic explosions – and update our particle tool to use a logarithmic scale for slider increments (making it easy to tweak small values).

See more →

Session 82

The Emittening

At last, after weeks of vacillation and tomfoolery, we bring 3D particle emitters to the game itself. To do this, we need to add the ability to orient emitters in 3D space. On top of this, we recall that we are masochists, having implemented a multiplayer implementation that runs the same game frame several times. This means we also have to figure out how to prevent creating the same emitters twice.

See more →

Session 81

Team Sandbar

With a lot of the groundwork out of the way, we begin adding some real features to the particle emitter tool. The tool gets color adjustments, autosave, and fancy double-handed sliders. JavaScript reveals itself to be a poor language for serializing class instances. Dom reveals himself to be a wizard of frontend web programming; the captain of the football team gives him a wedgie. Also: what Jeff did and didn’t like about Control, Suez Canal ship liberation and its discontents, and solidarity with Amazon workers in Alabama.

See more →

Session 80

Semantic Satiation

Particles particles partciles partciels patricles. With 10,000 triangles on the screen, it’s time to take our particle system to a whole new level! We add code to efficiently track thousands of particles from multiple emitters, while simulating gravity and other effects on our particles! The end result: a sweet particle fountain fit for the Vegas strip! ⛲️ Also, we gotta talk about daylight savings time, our favorite pop culture sell-outs, and the magic of mentalists.

See more →

Session 79

The Kinkade of the Meme Generation

We move some computation over to the GPU in our mad quest to reach 100k spinning triangles. In a Herculean feat of coding, Dom one-shots the shader code. Also, we discuss Loop Hero’s wonky early-game balancing, horror games and why we can’t play them, finger drumming, and the cultural wreckage of NFTs. Notes/highlights Daylight savings legislation in CA: https://en.wikipedia.org/wiki/2018_California_Proposition_7 Quest for Groove is a great YouTube channel about the emerging art of finger drumming: https://questforgroove.

See more →

Session 78

Debugging Day

After getting all our triangles on the screen, we did some off-screen refactoring to make it easier to re-use our instanced rendering code for more than just the particletoy tool. Tonight, we walk through our new implementation, which lets us bind our shader attributes dynamically, and requires less boilerplate to get particles on the screen. However…our refactor wasn’t quite working by stream time, and we spent the remainder of this session debugging our new changes.

See more →

Session 77

Psychedelic Triangle Party

Taking a new direction, today we start building a prototype of a particle emitter for the 3D engine. It’s not quite as simple in WebGL as it was in 2D, so we’ve added a new tool – “particletoy” – as a sandbox to play with new particle concepts. Since we expect a lot of particles on the screen, we explore “instanced rendering” for the first time. Instanced rendering allows us to send an object’s geometry to the GPU only once, and then render it multiple times with different positions and colors by passing only the values that change to the GPU.

See more →

Session 76

We Have a Physics Engine

With recent sessions having veered heavily into nonsense, we decide it’s time to get back to brass tacks. We want the game to have great-feeling weapons, and you can’t have good weapon feel without recoil and knockback. These are simple to implement on their own, but they represent the first time we’ve added a secondary mechanic that can influence the motion of the player. If multiple things can move the player around, how do you reconcile them?

See more →

Session 75

Mystery Machine

It’s a wild ride today. We learn about how thimbles work, the history of Monopoly pieces, fantasy languages, incorrect idioms, unintentionally right-wing quotes, and anti-neanderthal sentiment. Through all that, we do actually seek out and document some mysteries in our netcode. They’re pretty interesting and remain unsolved, but we’re a lot closer to fixing them. Don’t forget to like and subscribe! (if you’re so inclined) If you wanna use Vim keybindings in your VSCode, you can merge the two worlds with https://marketplace.

See more →

Session 74

Input Delay

We begin with Jeff’s exploration into using Rust code for browser programs. A watershed for the game’s performance, or a terrible digression into overengineering? You be the judge. We then discuss a nice article on Killer Instinct’s multiplayer code, which implements a rollback-based system that is distantly related to Manchester’s multiplayer synchronization system. This leads us down a rabbit hole where we attempt to add input delay. It’s supposed to make the dash mechanic look better in multiplayer, but instead, it just leaves us confused.

See more →

Session 73

The Rise of Dean Pupney

Jeff gets a PS5 and uses it exclusively to stream Netflix. The chatroom proceeds to goad us into adding a dog to the game; we comply. Dom immediately spends $30 on low-poly dog models. We fumble around with Blender’s bisect tool for 20 minutes in an attempt to separate a dog’s head from the rest of its body. We are forced to add more code to the renderer to get the dog to render correctly.

See more →

Session 72

Mars Baybee!

It’s a physics day! After our dashing addition of dashing, we realized our camera feels far too rigid moving in lock-step with the player. To do so, we start with a simple implementation that lags behind the player motion, and catches up based on how far away it gets from the player character. We also spend quite a while talking about how completely rad space is. You know it’s true.

See more →

Session 71

Gotta Go Fast

After spending most of the last year working on systems, we make an abrupt left turn back into gameplay. Today’s topic: a dash mechanic. This ends up presenting some interesting problems, such as preventing the player from dashing too frequently, and making sure the dash isn’t so fast that it tunnels through obstacles. The stream also takes its obligatory detours into space exploration and some of the weird corners of art history.

See more →

Session 70

Like A Dragon

We’re back ✨ After a brief February hiatus, it’s time to talk game design! To start, we walk through the new, experimental stack allocator and our future of memory management. We both agree that eliminating allocations is gonna be the key to managing performance while contending with the Javascript garbage collector. We also spent some time thinking about how to simplify our game systems by leaning more on our grid-based map for optimized querying.

See more →

Session 69

Graphics Yes Billionaires No

This is one of those sessions where the look of the game changes a lot in a short period of time. We move a bunch of our graphical experiments into the main game program, most notably the “wiresolid” object renderer. We also throw in high-DPI rendering and scroll-wheel zooming. On a lark, we happily discover that the multiplayer implementation still works. Notes/highlights Carbon API, a venerable framework for building Mac applications: https://en.

See more →

Session 68

The Collector

Join us for an exploration of future gameplay ideas, before diving back into our shader exploits. As much as we love “steve shading”, we’re now calling our method the “wiresolid” shader. We walk through the pros and cons of the different techniques we’ve been experimenting with, and add a few additional tweaks – such as anti-aliasing! We learn a great deal about our screen-space derivatives for edges, and found even more OpenGL features that we wish we could use but that aren’t available in WebGL.

See more →

Session 67

The Wireframe Wild West

The saga of wireframe rendering continues. We begin by expanding the capabilities of Rendertoy, our 3D visualization tool, so it can use different rendering modes. This allows us to compare the results of two different rendering techniques. The first is a two-pass method that renders a line mesh on top of an opaque triangle mesh. The second is what we’ve come to refer to as “Steve shading”, a one-pass method that does tricky math in the fragment shader.

See more →

Session 66

Qapla'

We start today by walking through a refactor of our GLTF model loader, which now preserves our model data after load for future processing in JS. After our last stream with Steve Foot, he came back to us with a really clever idea to use the fragment shader to eliminate triangle edges by adding a single attribute to our vertices. We talk through this algorithm, and how our new loader can help support it, before diving into some code.

See more →

Session 65

Synthwave is our Bob Dylan

Today, we’re once again joined by Stephen Foot, previously seen in Session 53 helping us out with our networking layer. Today, Steve does a deep dive with us on our OpenGL stack, and helps us brainstorm our wireframe rendering techniques. At the end of the day, Steve left us with a question-slash-mantra for graphics thinking: “are there additional attributes that I can encode?”. See our previous session with Steve here: https://jeffanddom.

See more →

Session 64

Edgelords

Our quest for a wireframe renderer continues. We begin by examining Rendertoy, a tool Jeff made for visualizing renderer output that would be a lot more useful were it not for a nasty gimbal lock bug. After staring mouth-agape at whiteboard math for a while, we make a tactical retreat into the fragment shader, where we hope to find a way to remove diagonal lines across flat surfaces. We quickly realize that the fragment shader can’t do this job without some extra information, so we run an experiment to see if adding an “erasure” vertex attribute will help.

See more →

Session 63

Wireframes and Plotlines

Now that we’ve got the most basic 3D objects drawing on screen, we commence an ill-advised charge directly toward a synthwave aesthetic of which the zeitgeist is rapidly tiring. First on the list is wireframe shading. How the hell do you do it? First, we study how to get the fragment shader to do lines, which requires adding barycentric coordinates to our vertex attributes. It turns out to be easier to implement than pronounce, although we still manage to trip over the little things.

See more →

Session 62

2020 Reviews + Grid Shaders

Welcome to 2021. Let’s pretend Dom wrote these notes before the attempted overthrow of our government, and that everything is fiiiiine out there. We start the year looking back at some of our favorite games from last year, and then exploring how to craft a wireframe shader. Our notable games from 2020: Hades (J + D): gosh we both love it. Hades manages to bridge the gap between Dom’s love of rogue-likes, and Jeff’s equal dislike of them.

See more →

Session 61

GLTFO

Our modeling system continues to progress! After working with the limitations of OBJ models, we decided to switch our model format to glTF (GL Transmission Format). We like this format a lot - today, it makes it easier for us to address and animate parts of the model with a predictable hierarchy, and in the future provides support for a lot of advanced modeling features. To start the day, we tracked down a bug in our new glTF render pipeline and got our tank rendering from the new format.

See more →

Session 60

Lighting

We recap a bunch of new features and tweaks that got added during our weeklong vacation away from the stream: there’s a new shader and interface for handling 3D debug draw, a few of the most annoying bugs have gone away, and the code got refactored a bit for ease of use. Next, we decide to try adding lighting, after spending several sessions talking about it but not actually doing it.

See more →

Session 59

Tightening up the graphics

We begin with a demonstration of our nifty new cloud development setup, which lets us build the game and run the game server using cloud-based computers. Then we attempt to add 3D lighting into the game, which necessitates reading vertex normals from OBJ files. A bungling misadventure in refactoring unfolds, leaving the game looking slightly more broken than before. But it turns out the real treasure is the conversations we had along the way.

See more →

Session 58

Sometimes the Model Flips You

Dom reports that he was able to sneak out of Amazon.com with a PS5, and is now enjoying his last-gen games in sweet, sweet 60FPS. He then unveils his latest work, which lets us load OBJ files and draw actual 3D models into the game. Soon, the game is filled with life-like trees and tanks. We quickly discover there is no agreed-upon standard for orienting 3D models, we spend the rest of our time flipping and rotating objects so they draw correctly.

See more →

Session 57

We're 3D at Last

Manchester finally makes its leap into 3D graphics. Last time, we had a renderer working with 3D primitives, but it generated a firmly two-dimensional result. This session, we move the camera into 3D space, and give it a tilt to emphasize the perspective effect. We also get our entities drawing again, and most important of all, we fix the garish terrain colors. Notes/highlights - Quaternion, an expanded complex number used for representing rotations and orientations: https://en.

See more →

Session 56

OpenGL: The Awakening

We pull all the wires out of Manchester’s 2D renderer, in the hopes of replacing it with a shiny new OpenGL replacement. There are many blank stares as we try to remember how matrix multiplication works. To our shared surprise, we’re able to get terrain rendering working, although something about the colors seems a bit off… Notes/highlights A nice explainer on the difference between normalized device coordinates and other coordinate systems: https://computergraphics.

See more →

Session 55

A Matter of Perspective

Returning to OpenGL, we dive into perspective rendering. Previously, we’ve rendered a single square in a flat plane, but to draw a scene that looks three dimensional to our brains, we’ll need to get more complex and start mimicking how our eyeballs perceive the world. After going through the math, we sketched out a clean-room implementation for drawing a cube in perspective based on the WebGL2 Fundamentals examples. Stick around to the end of the video to see one heck of a red-and-black spinning cube.

See more →

Session 54

Buffering...

We walk through the WebGL 2 Fundamentals state diagram, an interactive tool that will help to demystify the OpenGL API. Nobody would ever accuse OpenGL of being intuitive or easy to use! We walk through an example that draws a colored triangle, truly the “Hello, world!” of graphics programs, and then try a more complex example that uses perspective projection, texture mapping, and diffuse lighting. Notes/highlights: Here’s a link to the WebGL 2 Fundamentals state diagram tool: https://webgl2fundamentals.

See more →

Session 53

Feat. Stephen Foot

We think you’ll learn a ton and have fun with this one; we certainly did! This is our first-ever three person stream, with guest Stephen Foot dropping knowledge gained across 15 years in the game industry. We play Manchester with 3 players for the first time ever (there are, aheam, some kinks to work out). Then we review our multiplayer architecture and ask Steve for thoughts and suggestions. Of course, it turns out he has studied everything we have, and more.

See more →

Session 52

Fine Art

Our blind charge into the world of 3D graphics continues! This session we grapple with the classic game developer’s rite of passage: staring for two hours at a sea of magenta, trying to get a square with gradient colors to draw on top of it. Both of us proceed to badly misremember the lessons of past graphics classes and projects. OpenGL’s brutal ergonomics offer no extra assistance; we arrive, as many before us have, at the conclusion that the API is bad.

See more →

Session 51

Another Dimension, Another Dimension

We’re doing it. It’s finally time to move our renderer from 2D to 3D (and take a short break from working on our netcode). We’re still going to be using the Canvas element, but switching the rendering mode to use WebGL2. As we dug in, we found that some parts were similar, and – as expected – some that weren’t. After updating our screen clearing function, we looked at the changes that would be required for our camera and renderable systems.

See more →

Session 50

Hades Racing

This is our 50th Twitch stream since we started this project. Five-Zero! Wow!! We’re having such a fun time, and here’s to 50 more ✨ For the first hour, we continued our move to immutable objects in our game systems and applied our ComponentTable pattern to our damageable objects. In the process, we had to refactor both our Damageable and Hitbox classes to be pure data types instead. We followed the Typescript errors and were able to refactor cleanly…but only after touching nearly ever entity!

See more →

Session 49

Four Seasons Immutable Entities

Forgive some audio issues at the beginning of the stream! OBS gonna OBS. In this session, we started sending mouse position in our multiplayer events to allow players to see where other players are aiming in realtime. We started playing the game together, and at a buttery smooth almost-60 FPS. Our hiding system got an upgrade to hide tanks from other players as well as enemy turrets. For the second half, we dug into our twin implementations of immutability.

See more →

Session 48

Ghosts in the Machine

Dom returned to the stream after a hard weekend of public service, only to find that the game no longer has a entity class. Instead, we’ve got a bunch of maps and sets, keyed by entity ID. It sures seems like you can take the web programmers away from the web, but you can’t take the web out of the web programmers. After that, we finally turned on some old systems like turrets, but have to deal with the perennial problems: bad synchronization logic and poor performance.

See more →

Session 47

“Build Back Better” is hard to say

With the election right around the corner, we’ve got politics on the mind. Expect some anxiety over bleak outcomes and lots of armchair philosophizing about the possibilities of democracy. But we were able to cram at least a little programming into the stream. We add some new container classes, true catnip for the programmer trying to procrastinate while avoiding the hard problems. We also got rid of some redundant particle emitters, which was a nice frame rate optimization.

See more →

Session 46

Always Index the DB

After reviewing Jeff’s latest type and prediction updates, we continued to pick away at simulation performance. With some digging, we spent some time indexing our entities by their individual component types. We eliminated ~30k iterations through the entity manager during re-simulation by looking entities up by component type, and saw our frame rate start to climb. We’re using an “opaque type alias” to keep our entity IDs typechecked. Since Typescript doesn’t have built-in support for opaque types, we simulate it with a clever intersection of an impossible-to-satisfy type signature: https://codemix.

See more →

Session 45

Vote No on California Prop 22

As we continue to integrate spatial indexing into the game, we take a couple of field trips. First, we refine some function names that make our multiplayer prediction system much easier to understand. Naming things is hard! Then, we take another shot at improving our frame rate issues, this time looking into how our background terrain gets drawn. Notes/highlights: This is an important election for many reasons. If you’re a voter in California, please consider voting against Prop 22, which would dismantle hard-won protections for gig workers: https://www.

See more →

Session 44

Purgatory is a Quadtree

In between trading tips about Hades (one of the best games of the year!), we continue plugging away at our spatial partitioning system. Notes/highlights: Paradise Killer, a vaporwave detective game that’s been making the rounds: http://paradisekiller.com/ Ever have a program that uses the same data type for different concepts, like currencies and measurements, and wished the typechecker could tell them a part? That’s called an “opaque data type”, which some languages support, but not TypeScript.

See more →

Session 43

Blame Infinite Recursion

We plug our shiny new quadtree code into our collision system, only to run into an infinite recursion bug. Boy do I hate those! Notes/highlights Hades is the game Dom and I both playing right now. It’s great! https://en.wikipedia.org/wiki/Hades_(video_game) Coinbase, a company of dubious social value, has adopted the dubious policy of no politics in the workplace: https://gizmodo.com/silicon-valley-is-fighting-a-losing-war-against-politic-1845239358 The “pimpl” design pattern, a C++ technique for hiding implementation details: https://en.

See more →

Session 42

Quad-Nuggs

After our successful multiplayer trials, we considered updating more of our existing gameplay for netplay. However, it was clear that we had a growing performance problem in some of our systems that required a deeper fix. Enter the Quadtree: a data structure that provides logarithmic-time lookup for an entity in our map based on its position. We implemented and tested multiple subroutines for the tree, and are excited to put all the pieces together in our next session.

See more →

Session 41

Awkward Simulations

The day has arrived. Finally – we can play a game together and blow up the other tank! It’s a little tricky to aim, as we’re always shooting at where the other player was instead of where they are, but we’ll start getting into the prediction business sometime soon. After adding OVERDRIVE mode last week to help clients catch up to the server, this week we added a slowdown message to bring clients back to normal speed.

See more →

Session 39

Dependency Management

Okay, it’s been long enough: we want a real server process, not a fake one running in the browser. To get there, we have to fight through a mess of confounding issues: how to get both the in-browser client and server-side process to restart, and how to get them to talk using WebSockets. Along the way, we run into not one but several false starts using off-the-shelf libraries. Notes/highlights “The Case of the Missing Hit”, a all-time great podcast from Reply-All, about a song someone swears they remember but doesn’t actually seem to exist: https://gimletmedia.

See more →

Session 40

Time Dilation

This session marks the first appearance of “true” multiplayer in Manchester, with the game running on three different processes. It’s the first time Jeff and Dom have played the game at the same time! Of course, we run right away into a tricky bug: the game stops working if one client runs even slightly faster than the other, which means we need to compensate somehow. This is an interesting problem, but we all know you’ll watch this episode because it has cats and dogs in it.

See more →

Session 38

War with the Machines

As we gain confidence in our multiplayer implementation, we start to flip the lights back on for several other gameplay systems. Bullets move again, and the player can’t drive through walls anymore! But new systems mean new problems. We wrack our brains to figure out a mysterious collision issue, and begin to suspect our client-side prediction system is getting too expensive. Notes/highlights You can’t use UDP in the browser! Here’s netplay guru Glenn Fielder’s exploration of this tricky limitation for games running the browser: https://www.

See more →

Session 37

Sprinkles and Jimmies

We factor out a common simulation abstraction for the 3 or 4 places where we simulate the game: server, client reconciliation, and client prediction (twice). To combat the performance issues caused by duplicating our game state too many times, we added checkpointing to our entity management, reducing clones in exchange for state-handling complexity: now we have to mark objects as dirty before modifying them. Finally, we re-enabled the shooting system…but not our bullet physics.

See more →

Session 36

Prediction is You

We added a second simulated tank with a simulated keyboard input, and the beginnings of a world with multiple players in it. En route to that, we fixed a bug where we weren’t actually processing server messages. This all reintroduced serious performance problems…we sense optimization in our future. Notes/highlights Working Effectively with Legacy Code https://www.oreilly.com/library/view/working-effectively-with/0131177052/ Alan Wake: a cool “old” game: https://en.wikipedia.org/wiki/Alan_Wake Remnant from the Ashes: good if you liked Destiny or Dark Souls: https://en.

See more →

Session 35

Your FPS Display Needs a Bigger Font

We fixed some gnarly frame rate issues! To help with the optimization, we built an FPS display into the debug overlay, which ended up being so cool that maybe it should just be the whole game. Notes/highlights: The new website is done-ish. Check it out at https://jeffanddom.com. Nice work, Dom! We took our inspiration from the character select screen from Turtles in Time (https://en.wikipedia.org/wiki/Teenage_Mutant_Ninja_Turtles:_Turtles_in_Time). The game is now code-named “Manchester”.

See more →

Session 34

Simulated simulations

Our goal today was to attach multiple clients to the server. Instantiating multiple clients means we had to split the game object into “client” and “server” portions, a change that we started working on last stream. Along the way, we encountered a significant slowdown when running a second client loop, which means some optimization is due. Notes/highlights “1500 Arches on a 28.8”, a classic article about the low-bandwidth multiplayer implementation in Age of Empires 8-Bit Game Graphics Converter, a website that will downres your photos with retro style We teased our website!

See more →

Session 33

Client-side prediction

We get the game (or at least player movement) working smoothly again with a minimal implementation of client-side prediction.

See more →

Session 32

Server-to-client communication

We continue to build up netplay foundations. This time, we start to move away from a shared-memory model for sending state from server to client.

See more →