Archive

Let the reader beware, especially as you scroll further back in time.

How to Exfiltrate Code from Bitbucket

Every year or so, something compels me to start over with a fresh OS image. Most recently, that something was an unfortunate water bottle incident. Once again, I need to pull down my digital life from the internet. The code and assets for this blog currently live in a 500 MB Git repository, which was hosted on Bitbucket until earlier today. Let's try cloning it! evantodd@HW-0063 ~ % git clone git@bitbucket.

The Poor Man's Netcode

The more you know about a given topic, the more you realize that no one knows anything. For some reason (why God, why?) my topic of choice is game development. Everyone in that field agrees: don't add networked multiplayer to an existing game, you drunken clown. Well, I did it anyway because I hate myself. Somehow it turned out great. None of us know anything. Problem #1: assets My first question was: how do I tell a client to use such-and-such mesh to render an object?

The Poor Man's 3D Camera

Each of us have our own giants to face. This is a story about one of my giants. Something I never imagined could make a grown man cry, until it did. A 3D camera. No one can face your giants for you. This is a story, not a walkthrough. Expect no useful information. For that I recommend 50 Game Camera Mistakes by thatgamecompany's John Nesky. His job title is literally "

Thirteen Years of Bad Game Code

Alone on a Friday night, in need of some inspiration, you decide to relive some of your past programming conquests. The old archive hard drive slowly spins up, and the source code of the glory days scrolls by... Oh no. This is not at all what you expected. Were things really this bad? Why did no one tell you? Why were you like this? Is it even possible to have that many gotos in a single function?

The Poor Man's Voice Acting

Allow me to regale you with an exciting tale: the birth of a janky dialogue and voice system. I have a JSON file with all the localized strings in my game, like this: { "danger": "Danger", "level": "Level %d", ... } A preprocessor takes this and generates a header file with integer constants for each string, like this: namespace strings { const int danger = 0; const int level = 1; // .

The Poor Man's Threading Architecture

The game industry hit Peak Advice Blog a while ago. Every day I read skim ten articles telling me how to live. Fear not! I would never give you useful advice. This series is about me writing bad code and you laughing at my pain. First Contact Say you have some voxels which occasionally get modified. You regenerate their geometry like so: voxel.Regenerate(); Because you are a masochist, you want to do this on a separate thread.

Ludum Dare 34 Postmortem

Friday 21:15 Fifteen minutes after the theme announcement, my friend Ben Homan walks through my front door. Not really my front door, I'm just a subletter. But this is a first. Normally he ignores our instructions to walk in without knocking. The first time, he texted me from the driveway. 21:30 Jesse Kooner walks in, also unannounced, bearing frozen pizza. Before he can even kick his shoes off, I loudly explain the theme: a never-before-seen tie between "

One Weird Trick to Write Better Code

Developers hate him! We'll cover some standard tips and tricks here, but we're not really interested in those. We're looking for the One Weird Trick to rule them all. Hopefully each trick we encounter brings us closer to coding Mecca. In the beginning The first video game I ever wrote was called Ninja Wars. Yes, that is an HTML table of images. I changed the src attribute to move stuff around.

The Poor Man's Postmortem - Lemma

The big secret of our industry is, we don't actually enjoy making games. We slave away in obscurity for years in anticipation of one glorious day. Not release day, no. The day we can finally write a postmortem full of pretentious anecdotes, bad jokes, and unsolicited advice. Well I just finished a game, and doggone it, I am going to exercise my inalienable rights as a developer. Lemma is immersive first-person parkour in a surreal, physics-driven voxel world.

The Poor Man's Character Controller

Let's say that, like so many of us, you want to make a surreal voxel-based first-person parkour game. You're trying to figure out a production schedule. What will take the longest? Graphics? Sound? Level design? I bet it will be the character controller. And I bet it will take 4½ years. Why? In running/jumping games, player movement is paramount. It takes forever to nail the right feeling.

Screenshot Saturday 213

It's the end of February and this game is supposed to be content-complete. In a sense, it actually is. All the levels are done. Twenty in all. I thought this month would never end! Just so you know, there are sixty of those lights and I had to hook up each one individually. It fell just barely beneath the "worth it to automate" threshold. Don't look too closely at this next one, it's a bit spoilery.

The Poor Man's Voxel Engine

This is not a tutorial. It's a story. A Voxel Odyssey. The story starts with 19 year old me in a dorm room next to the Ohio State stadium. I don't have the repo from this stage of development (SVN at the time), but I remember the process clearly. Photo by Kristen Sutton XNA 4 comes out in September 2010. I immediately dive in. This turns out to be a poor life decision.

Screenshot Saturday 211

Last Saturday we had the Short North gallery hop. Hundreds of people came through our gallery to see art. The guys helped me set up the Oculus and a projector on the wall. Sometimes I had to go out and pull people in, but most of the time, there was a line. My favorite customer by far was this kid: He jumped right in and played like a pro.

Screenshot Saturday 210

I finished last week's map. It has some spinny things. Then I made this week's map. Who knew purple and green could look so... not terrible? Anyway, this puts me ahead of schedule. There are three levels remaining. My goal is to for the game to be playable from start to finish by the end of February. It's ambitious, but I'm confident I can do it! Today I took a break from level design to do some hardcore coding for the first time in a while.

Screenshot Saturday 209

This week was crazy productive. I finished last week's level, finished another level, which looks like this: ...which also included some story-related writing and scripting, and actually started working on NEXT week's level, which looks like this: I seem to be on a purple streak lately. Actually, purple may rise unintentionally to be the most prominent color in the game. Also, this last level is apparently a subconscious ode to Monument Valley.

Screenshot Saturday 208

This week's level is not quite done yet, but I have an excuse! Power was out at the incubator for two days, and the internet didn't come up fully until just yesterday. Still, the level should be done some time this weekend and is already looking pretty good. I finalized the promotional graphics and published the game to Steam in "coming soon" mode. I'm incredibly grateful to Sam Gebhardt for contributing his Hollywood artistic talent!

Achilles

This past weekend I participated in the CivicHacks "Game Jam for Good". The goal was to raise awareness of the global water crisis and ultimately promote PackH2O, a Columbus-based startup that designs water backpacks for developing water-stressed regions. The jam lasted 48 hours. My entry is called "Achilles". Achilles is a multiplayer text-based simulation. You the player must manage a village in a third-world country experiencing a water crisis.

Screenshot Saturday 207

Records continue to be broken. This week's map was actually done on Wednesday! Although most of Lemma is a strange hybrid of natural and alien-looking architecture, my design calls for a few "industrial / man-made" themed maps. For story reasons, and also because I just want to parkour through a skyscraper. So on Monday I asked Twitter this question: Would people be upset if I do a few levels in the visual style of Mirror's Edge?

Screenshot Saturday 206

I moved my office into an incubator / art gallery this week. The move is mostly for my own sanity. Turns out, working alone in your apartment for 9 months isn't the most fun in the world. It's a Herculean effort just to stay motivated. I also lost all semblance of a disciplined sleep schedule. Productivity has been great since the move, and I'm back on a normal sleep schedule.

Screenshot Saturday 205

For the first time in the history of Lemma, I'm actually keeping up with my self-assigned pace of one new level per week. These past two weeks I made two more frost levels. The plan calls for one more frost level, then it's on to the other two biomes. Both of these levels have interesting quirks and unique features. They're probably too tough right now, but I'm scheduling plenty of time to playtest and sand down the sharp edges.

Screenshot Saturday 203

Big update this week! My voxel renderer now has the capability to overlay everything with any texture I want. I'm using it on a new set of interconnected winter levels. This way I don't have to manually come up with a frosty version of each texture. Without giving away too much, this week I built a new system that has implications for both puzzle solving and movement mechanics.

Screenshot Saturday 202

I've come to several realizations this week. Lemma is going to be good, but not great. I have to accept my limitations and finish the thing to the best of my ability. Lemma is more of an experience than a traditional video game. With these two ideas in mind, I am focusing the next few months on making Lemma the least frustrating, most enjoyable experience I can. So I'm trying to come up with puzzles that seem difficult but are actually simple to solve.

New blog, new app, new screenshots

Lots of stuff going on this week. New dev blog First off, my website got a much-needed overhaul. The horrible slowness of Wordpress.com was driving me nuts, so I switched to a custom-built site. I used Jekyll, which is a static site generator. It spits out a bunch of HTML files which you can upload to a server, as opposed to Wordpress, which generates fresh HTML every time someone loads your page.

Screenshot Saturday 199

"Level design for days" has been my motto for several months now, and this week is no different. Behold, new challenge levels! These are timed, bite-sized maps with simple goals that can be completed in under a minute. They're the kind of things you can create in the level editor and share on Steam. I need to find a new texture for that garish green material. Lots of other things are happening, but they're more like a million tiny updates rather than a few conveniently screenshot-worthy ones.

grepr - 7DFPS 2014

I survived 7DFPS, barely. Here are some fascinating statistics: Days to create an FPS: 7 Hours spent: 93 Levels built: 5 Lines of code written: 2313 Hours to spare before deadline: 2 Functioning brain cells remaining: approximately 4 I'm happy with the result, though. Jack did a great job on the audio as usual, although at the last minute I had to throw in some clunky placeholder sfxr sounds.

7dfps work in progress

I'm participating in 7dfps this year, which means I'm making an FPS game in 7 days. Here's what I've got so far: In Soviet Russia, you are bullet. In my 7dfps entry, moving and shooting are the same thing. Here's my favorite form of humor: physics glitches. Here's me getting killed: Here's a better shot of the city: Lots to do still.

Screenshot Saturday 196

This past weekend I exhibited Lemma at the Ohio Game Dev Expo. It was an awesome time. Extra Life raised over $9,000 for charity (yes, it is in fact over 9000). The Oculus Rift was a huge hit! I worked on various improvements right up to the expo. First, some new textures for moving platforms and doors: This is the first texture I've created that has any kind of directional meaning.

Screenshot Saturday 194

Just a quick update this week to confirm that I am in fact alive. The iOS contract game is just about done. I'm pretty happy with it. Now it's back to work on Lemma: I'll be running a booth, speaking, and participating in a panel at the Ohio Game Dev Expo next weekend! Come on out and hang with us!

Shaders: How Do They Work?

Yesterday I gave a talk at Dev Workshop Conf introducing the basic concepts of vertex and fragment shaders. Unfortunately I don't have a video, just this one potato picture: It's probably for the best, because Chrome locked up on me halfway through. The slide deck is pretty cool though. It includes over 20 interactive WebGL samples, complete with source code. Check it out and let me know what you think!

Screenshot Saturday 190

Well friends, Lemma is still on pause while I do some contract work. I also have only a few slides done for my shader presentation next week. This whole month is crazy. But I thought I'd hijack this dev blog to show you the game I'm working on, because it's starting to look kinda cool! It's a top-down iOS survival shooter designed as a sort of franchise tie-in. The budget is pretty low so most of the assets are pulled from the Unity asset store.

Screenshot Saturday 188

I'm taking September off to work for some clients, so Lemma is temporarily on the back-burner. HOWEVER. Wednesday night a certain something arrived in the mail. I immediately tried it out with Half-Life 2 and was shocked at the massive improvement over DK1. I was so impressed that I've spent pretty much every waking minute since then trying to get it working in Lemma. Current status? It's very, very close.

Screenshot Saturday 185

Hello friends. Yesterday I finished the 5th level! It took much longer than anticipated because it's actually 10 separate maps connected together. It includes some simple but hopefully interesting puzzle mechanics. It also advances the story through notes and several text conversations scattered throughout. It's hard to see in screenshots, but I added a subtle cloud shadow effect as well. It doesn't respond to the actual clouds, so in a sense it's slightly faked.

Screenshot Saturday 184

This week was a lot of level design. I'm working on a group of "fractured" but interconnected worlds that the player has to progress through. Here's a screenshot: Here's the thread where I got that rock texture. It's a gold mine with a bunch of totally free diffuse, specular, normal, and even displacement maps. Unfortunately that's all I have time to talk about today. Thanks for reading!

Screenshot Saturday 183

I hit a milestone today. Three of the four levels so far in Lemma (Rain, Dawn, and Forest) have undergone at least one massive redesign in their short lifetimes. This week I finally gave the same treatment to the fourth level, Monolith. It is aptly named. Let me try to convey just how monolithic this level is now. This is a perfect example of my patent-pending Design by Trial and Error™ process.

Screenshot Saturday 182

What's that you say? You didn't even notice the absence of Screenshot Saturday last week? How convenient. Let's pretend it never happened. Or rather, pretend that it did. Whatever. MGDS was a huge success! There was almost always a line to play the game, and I got a ton of useful feedback. Here are some pictures: Most of the feedback was related to level design. I came home with a phone full of "

New trailer!

Gearing up for Midwest Game Developers Summit this weekend. Tune in next week for my first expo post-mortem. In the mean time, the old trailer was looking woefully outdated, so here's a brand new one!

Screenshot Saturday 178

Small update. This week was bug fixes and more improvements to the level editor (more on that here). In other news, we were grateful to get some coverage from Monday Night Indie! Unfortunately the stream highlighted some pretty major issues with the tutorial, so... Brand new level design! That's it for this week. Thanks for reading.

Screenshot Saturday 177

Our animator Antoniohas been hard at work on new animations. Check it out! Guys, the level editor is really close to being done. Here's some cool features: You can link entities together. For example, you can have a door open when the player enters a trigger volume. Or have a light turn on. Or both. The UI now displays buttons for all available commands at any given moment, and their keyboard shortcuts.

Screenshot Saturday 174

First, a couple project updates. I pre-ordered an Oculus DK2! Come August, Lemma will have Oculus VR support. Huzzah! I also got a sign for our booth at the Midwest Game Developer summit. Got it from eSigns, whom I highly recommend! Insanely cheap, fast, and high quality. I am currently scrambling madly to complete a build for the Indie Megabooth submission deadline on Sunday. Stuff that's done: The beginning of the game (aka the apartment) finally got some textures!

Screenshot Saturday 173

Last week was a huge update, so this week is a bit smaller. First, we're hard at work on the animations. Here are some early WIP animations: There are also a ton of new player sounds to accompany those animations, but those aren't very screenshotable. :) I also vastly improved the god ray effect from last week, so everything is much smoother. Here's another 4K screenshot of it:

Screenshot Saturday 172

Big update this week! First, I updated the logo. I rotated the cubes 45 degrees to try and convey a better sense of speed and movement. What do you think? Next, I added support for 4K screenshots. Now I can hit Alt-S and my renderer resizes all of its buffers to 4096x2304 (biggest 16:9 resolution supported by XNA), renders the scene, saves it to a PNG, then resizes everything back to normal.

The Poor Man's Dialogue Tree

As some of you may know, Lemma has an interactive dialogue system that lets you exchange text messages with an AI character. I implemented every conversation manually in code (well, scripts) until this week, when I got fed up and decided to automate the process! Like the last article in this series, my system has all the hallmarks of a Poor Man's solution: developed in-house, tailor-made, simple, and based on free and open source software.

Screenshot Saturday 170

Hello and welcome to another week of Lemma development progress updates! This time I did a lot more work on the player character. I spent a ton of time in GIMP working on the texture map. I didn't skimp on memory space, it's a full 4096x4096. The GIMP file is over 150MB. I also split the model into three distinct materials: a shiny one for the chest, neck, and pants, a less shiny one for the hands, and a completely dull one for the hoodie.

Screenshot Saturday 169

This week I finally implemented SSAO! It's pretty basic, but it works. Check out the effect source code here. It's a big deal for me because I tried it once before and it came out like this: I'm also still working on the player model. I think it's close to being in a usable state. What do you think? Is that a ponytail, or a brain slug?

Screenshot Saturday 168

This week was a ton of performance optimizations and graphics upgrades. Cascading shadow maps! Basically that means all the shadows are much sharper. It was surprisingly easy to implement and barely impacts performance. Here's a screenshot showing off the new shadows, plus a new character modeling experiment. Just testing things out for now. What do you think? Turns out, Blender has something called Rigify that can automatically generate an absolutely kick butt IK rig for your character, complete with blend weights for skinning.

Screenshot Saturday 167

With the Kickstarter finished, it's back to our regularly scheduled programming! I am in the middle of a major graphics engine upgrade. This whole time I've been using fake HDR. Basically I divide every color by 2 when storing it in a texture, then multiply it by 2 whenever I read it from the texture. It works but you end up with lower color fidelity. Now everything is done in full 64-bit floating point textures.

Final hours

Here we are folks, counting down the last remaining Kickstarter hours! I'm happy to announce that regardless of the Kickstarter outcome, production of Lemma will continue. To be honest, I originally planned to cancel everything if the campaign failed. I figured a failed Kickstarter would be a sign that people aren't interested, and that I should cut my losses (nearly 4 years of work) and move on. But in the past month I realized a few things:

FINAL WEEK!

We are now in the midst of the final week of Kickstarter funding! With the campaign nearing the end, I thought I would give you another development update. First, I spent a few days completely rewriting every bit of text in the game to support multiple languages. You can now change the language from this nifty selector on the main menu, and the whole game instantly switches: Now all we have to do is translate ALL the things!

GREENLIT!

From the Kickstarter: It's not every day you see this email in your inbox. WE ARE ON STEAM! Thanks everyone for your votes! We were part of a batch of 75 titles, even though we hadn't reached the top 100 yet. Go check out the other games that were greenlit today! Here are the statistics for anyone interested: My theory is that the traffic dropped off a cliff at the end because we were already approved and got removed from the rotation.

Cheat your way through life

From the Kickstarter: Just an update on development progress for Lemma! Thank you so much everyone for your support. I'm still getting tons of useful feedback from people playing the demo. Levels have been tweaked, bugs have been fixed, writing has been edited, and graphics have been tightened. Expect a new build very soon! Here's some new features to look forward to: First, a minor technical detail. Saved games do not carry over between builds.

Player model and animations

An update from the Kickstarter: One concern that pops up a lot on Greenlight is the low quality of the player model and animations in Lemma. The reason it's so bad is that I did all of it myself, and I'm not a character artist. People ask, "but couldn't you just try harder? What's so hard about modeling and animating a character anyway? Also, couldn't you just borrow an existing public domain model?

Movement in-depth

Update from the Kickstarter: I know it's only been 24 hours since the last update, but Lemma is now over 61% of the way to the top 100 games on Greenlight with well over 4,500 yes votes. Thank you all for being a part of this project! I realized that the 30 seconds of gameplay from the Kickstarter trailer is not enough to really see what's going on, so here's a more in-depth video explanation of the movement in Lemma.

Looking forward

From the Kickstarter, a quick status update before I talk more about Lemma: At the current rate, we are just minutes away from 4,200 yes votes on Greenlight! 56% of the way to the top 100. A big thank you to our new backers! There are now 174 of you lovely people (wow) and we're over 32% funded. Rock Paper Shotgun covered Lemma yesterday! And with that headline, we've added Bastion to the incredibly long and disparate list of games it's been compared to.

Greenlight update + streaming tomorrow

Hello! First: I wanted to thank everyone for the amazing support you've shown so far. We're already over 24% funded, which is more than I was expecting this early, so thank you! Second: A quick update on the Greenlight campaign. We are 26% of the way to the top 100, with 1,918 "yes" votes! Keep on voting, we'll be on Steam in no time. Third: If you wanted to see more gameplay from Lemma but didn't have time to check out the demo, several YouTubers have posted "

Lemma: first-person parkour demo

Download the demo for Windows Back the Kickstarter Vote for Lemma on Greenlight Follow me on Twitter After an unexpected 24 hour delay, the demo is finally out, and the Kickstarter is live! I'm running on 3 hours of sleep, but here's some things you might not have seen since the last release: The bouncy cubes are now more like crumbly cubes. They crumble when you touch them.

Screenshot Saturday 162

The Kickstarter for Lemma launches on Monday! Keep an eye out, and tell your friends! Prepare yourself for tons of giant GIFs. You can click each one to watch a much faster HTML5 version (can't wait until the internet ecosystem finally lets us embed HTML5 gifs...) This week I revamped the materials... again. Check it out: It had some interesting implications for the "snake" enemy: Also added a whole new section to one of the levels:

Screenshot Saturday 161

This week I finished what will probably be the last map in the Kickstarter demo. It teaches the player about the "extended wall-run" ability, demonstrated here: Normally, you hold Shift to wall-run. Now you can just keep holding Shift after you run out of wall, and you'll keep going. I also fixed the water bugs from last week, so it looks much better now: I've been worried that I don't have time in the demo to introduce every idea I have at a reasonable pace, so I'm thinking of including a "

Screenshot Saturday 160

This week I finally fixed my water code to allow finite bodies of water like this: (It's so dark because I still have a pesky rendering bug) I also realized I accidentally had pre-multiplied alpha turned on for my cloud texture. Here's what it looks like when you use pre-multiplied alpha incorrectly: And here it is fixed (I also made the clouds fade in over distant objects):

Screenshot Saturday 159

This week I overhauled the menu. It's very Valve-ish now: I also distributed a number of mysterious notes around the levels to help flesh out the back story. They're actual 3D objects rendered and lit in the game world. WHAT COULD IT MEAN? THIS REVELATORY NOTE HAS ADDED HEFTY NUANCE TO THE PLOT AND SIGNIFICANTLY INCREASED MY IMMERSION IN THE STORY. Other than that, just lots of level design iteration, scripting, and tweaking.

The Poor Man's Gameplay Analytics

You don't want to take time away from your awesome game to write boring analytics code. So you either call up some friends, hire playtesters, integrate some 3rd party SDK (ugh), or just do without. WRONG. You roll your own solution. Here's why. Why you don't do without The OODA loop models the way human individuals and groups operate. It goes like this: Observe the situation Orient your observations in the context of goals, past experience, etc.

All Ahead Full

Progress report. Sir, we have inbound screenshots from the first two weeks of full-time development. Bearing zero nine five, range three hundred. Prepare countermeasures. I added motion blur around the screen edges when the player is at their maximum speed: The phone has returned, but now it's in full 3D glory: Some parts of the levels now build up dynamically when the player reaches them. I finally tightened up the visuals on the tutorial level:

Ramping Up

I'm sorry, I've been terrible at keeping everyone up to date with Lemma. If you want to see what I've been up to since Alpha 3, my TIGSource DevLog has a few posts you might have missed. Starting now I'll be focusing more on blogging, so expect more posts in the coming days! Here are some highlights from the past... gosh. Seven months? Wow. Player movement has been drastically improved.

Auto-generating JSON serialization code in Objective C

I wrote this article for the Sidebolt company blog. Reposting it here for your reading pleasure! Our latest game Skyward Slots makes extensive use of JSON. We send Gigabytes of it flying back and forth haphazardly between client and server over a WebSocket connection. At first, we wrote code by hand to pack and unpack each message. Later on we decided that life is too short for that. In the beginning, we just dove into the JSON right where we needed it.

Simulating UIScrollView in Cocos2D

I wrote this article for the Sidebolt company blog. Reposting it here for your reading pleasure! We publish our games on both Mac and iOS. Since UIKit is not available on Mac, we have to build all of our UI by hand in Cocos2D. One of the hardest parts to get right was emulating the UIScrollView bouncy scroll formula. Here it is in action: There are tons of implementations available in nearly every language and framework, but few of them nail all the important properties of the UIKit scroll:

Lemma - Alpha 3 Ready to Play

Download for Windows Check out the IndieDB project page Like on Facebook Follow on Twitter After seven months of hard work, Alpha 3 is ready to play! Some interesting statistics: 28,000+ lines of code 29 MB of compressed voxel data 63 MB of sounds and music 38 animations 60+ textures and normal maps 220+ revisions since Alpha 1 Incidentally, most of that is open source! If you're a developer, check it out on GitHub.

Quantity Brings Quality

As I suspected, I have an almost insurmountable case of coder's block after a full day at work. Nevertheless, things are getting done. In fact, this might be the best thing that's happened for Lemma because it's forced me to cut a lot out of the design and focus on core things. It's the only way I'll ever finish. Screenshot below gives an idea of the new direction. I've dropped any pretense that the game occurs in our world as we know it.

Anecdotes ahoy

A smorgasbord of anecdotes carefully compiled just for you, dear reader. This is #2 in a series of three posts which were originally one, before I decided I just had too dang much to say. OpenStack I spent a few weeks at work building a fully operational death star OpenStack cluster. What does that mean? Basically, we have our own little private version of Amazon Web Services. We can create virtual machines, virtual hard drives, even virtual IP addresses, all with just a few clicks.

My Biggest Fear for the Future of Human-Computer Interfaces

I recently had to install and configure an 18-node OpenStack cluster, a process which involved a lot of SSHing and text-editing in terminals. I thought about learning Vim, but I was afraid of the incredibly steep learning curve, so I made do with GNU nano. It's not at all powerful, but it's easy. Eventually I realized, "This is my job. This is what I do every day. Why am I holding off on learning something now, thinking it will slow me down, and that I'll have time to learn it later?

Internet is Back

I just got internet back after being without it since before Christmas. It was a tearful reunion, to be sure. Turns out, I was actually more productive than usual without internet. There's a one-word explanation for that, and it rhymes with "edit". ANYway, here's what got done: Analytics When you finish a play session, you'll see something like this:   I haven't figured out the server side of this system yet, but all it really needs to do is accept plain text file uploads.

Progress Report

Lemma has been radio silent recently, but that does NOT mean things aren't happening! I've been able to do a ton of work almost every day these past few weeks. Here's what's going on: Did some massive surgery on the very first tutorial section after getting some feedback from a limited alpha release. It introduces, jumping, climbing, vertical wall-running, and rolling/crouching. Added a second, underground section that introduces horizontal wall-running, wall-jumping, and some important story elements.

Mac and Linux Support

How's everyone doing? I'm doing okay. It's a Monday. Hope you're doing okay too. Surviving Sandy aftermath, school, work, and whatever other forms of oppression you may be under. I don't have anything pretty to show for the past... wow, it's been three weeks. I've been working on a very lofty addition to Lemma's feature bullet list. And that is Mac and Linux support, via the awesome MonoGame project. Don't get too excited.

Voxel Levitation and Rain

I present to you, "Voxel Levitation: a Step-by-Step Guide". Step 1: Step 2:   Step 3:   Step 4:   Also, check it out. Hurricane Sandy has spilled over into Lemma. It's raining! That is all.    

Allocating large arrays in .NET

I experienced a strange memory issue with Lemma this week. Memory usage skyrocketed each time I loaded a level; it never dropped back down. Now granted, I am definitely the garbage collector's worst nightmare. (I'll just say this: closures. Closures everywhere.) But at this point I am setting fields to null all over the place and manually calling GC.Collect() after unloading a level, all to no avail. Enter the .NET Large Object Heap.

Slowmo! Stamina! Sprint! Socialism! What?

Stamina and Sprint I finally realized that speed is perhaps the most important resource in a Parkour game. Up until now, Lemma hasn't really understood the concept of "faster" and "slower"; you were always going the same speed. Acceleration from a dead stop was almost instantaneous and the Parkour moves didn't change your speed (with the exception of wall-running). With this in mind, I decreased the acceleration a lot and made all the moves preserve your momentum.

Scary Monsters and Nice Clouds

Nice Clouds I got sick of my old pixelated skybox powered by Google Images and decided to make a real one. I used Spacescape to generate a sufficiently trippy outer space skybox, chopped up some cloud photos in Gimp, fought with my code for a couple hours, and wha-la: Scary Monsters What's that glowy green thing you say? It's the new monster I just added, creatively named "the vine". See that string of dark blocks coming out of it?

Now with 100% more frame buffer distortion!

Flying in the face of midterms and other IRL issues, Lemma boldly marches on! Spawn Point Graphics I realized you need a way to know where you'll respawn if you die, so I added some spawn point graphics. Got the idea from Borderlands. Actually can we talk about Borderlands? Man, every time I play a good game I have to resist the urge to start incorporating its ideas into my projects.

Story Design and Loading/Saving

I now have the complete backstory and in-game story options written out! After the initial tutorial, you'll get to a central area of the island which connects to four other areas. At that point, you'll be able to leave the island whenever you want, or you can visit one or more of the four adjacent areas before leaving. In each area you'll have to make a yes/no decision. You'll get a different ending depending on which decisions you make and at what point you exit the island.

Lemma Release 2

Here's an extremely cut-down demo! No tutorial, no story, no explanation, just showing off new moves, new enemies, and the new weapon. Download it here for free. Please let me know what you think! Super-Awesome Change List Totally new block dissolve effects and sounds. Preeeettty A new move that builds a platform of blocks and jumps you to the end of it. The kick is gone; instead you can now roll at any time, which not only prevents you from receiving fall damage, but also blasts through any breakable blocks in front of you and if you're in mid-air, tries to build a platform beneath you.

Brace yourselves

Everyone pretend this blog didn't die for six months, okay? Okay. Here's a brain-dump of random things I've learned while not blogging. Distributed programming is tough but really, really fun. gevent, Couchbase, Fabric, and pyzmq are awesome. Django's admin interface can be twisted fairly easily into a CMS for a dynamic website. Bed bugs + week-long power outage + another week with still-broken A/C = fun summer. Leaky washing machine + computer in basement directly beneath = new computer.

Finals week

Sorry, no news to report on Lemma this week. School is keeping me busy. But I thought I'd share some of the projects I'm working on for school, since they're kind of cool and actually somewhat related to Lemma. First up: a 3D rapid prototype of the original toon-style Parkour Ninja! Here's the model rendered in Cinema 4D: And here it is printed out in 3D: The pictures look a little weird because actually, I had the negative filter accidentally enabled.

Alpha feedback

Thanks so much to everyone who made the alpha a great success! I'm blown away that people were able to look past the bugs and crashes and clunky controls and somehow get a positive experience out of it! It gives me hope and motivation to press on. I got a ton of very useful feedback. Here's a quick summary of what I learned: The atmosphere and tone is cool and unique.

Lemma Release 1!

It's finally here! Alright I'm just going to dump everything here. Prepare for face melting. Windows MSI Installer (60 MB) Note: You might get a malicious file warning. It's because I can't afford a code signing signature at the moment, so the installer has not been signed. If you're NOT reading this on the shiny new website, did you know that you COULD BE? It's right here: lemmagame.com Please play the alpha and leave your comments!

Help me pick a logo!

I'm going to try and post smaller, more frequent articles. This whole "two months between massive walls of text and screenshots" thing is not working out. So, the alpha I promised is *still* inbound. I'm working as fast as I can! And I think it's paying off. For a while I was very worried about performance. In my last post I talked about how I optimized the renderer, but there were still issues with the physics engine.

Global Game Jam 2012 Liveblog

Update: Snakes in a Tower is complete! Downloads with source available for Mac and PC. Friday 4:59pm This is my first Global Game Jam. Super excited. So I'm going to liveblog it. I'll be working on a MacBook, so I decided to port the essentials of my XNA component entity system over to MonoGame. Here's what I got so far! Breathtaking, I know. Saturday 12:20am Opening meeting was awesome. Heard some fantastic keynotes from fantastic people.

Quick update - Alpha inbound soon!

This week was a lot of under the hood improvements. The voxel engine got a TON of performance optimizations, which allow my Nvidia GTX 260 to render my test scene at 100-200 FPS. Screenshots: New features: Rough-draft tutorial level with instructions and whatnot. Fullscreen toggling on-the-fly by hitting F11 Rudimentary fog effect Performance optimizations: Voxels are now rendered as surfaces, rather than complete cubes. This lets me cull a lot of unnecessary geometry.

Digital art, Facebook 3D Graph Explorer, and more Project Lemma

My last two posts focused on general game development topics, but no longer. It's the end of the year, time to look back and review before looking forward to the new year! Digital Art First off, some fun diversions. In my pursuit of an art minor at Ohio State, I took a digital art class autumn quarter. The instructor let me use software I was already familiar with, so I didn't learn much.

C# for scripting - runtime compilation

I set out to add scripting support to Project Lemma the other day. End result: I can recompile C# scripts on the fly and cache the bytecode in DLLs. The best part: there's no special binding code, and no performance hit. There are a lot of .NET scripting solutions out there. Here's a few I found in my research: IronPython. Fully dynamic, kinda slow. Requires marshalling of some kind between the script world and .

Tools are everything

You've probably heard the whole "don't make engines, make games" shtick. As I progress I am learning another important lesson: tools are the most important aspect of any project, game or engine. Whether you're rolling a custom engine or shopping around for middleware, tools should be absolutely top priority. Seriously. The question should not be "how many shiny graphics techniques can I incorporate?". It should be "how easy is it to create content for this game?

Physics and lighting fun

Sorry to post two videos in quick succession, but this was too fun not to record!

Parkour Ninja update: first-person camera, physics, deferred rendering

Parkour Ninja is still alive! And it's looking more like Mirror's Edge now, complete with first-person camera. The old direction of the game just had too much frustration and not enough fun. Hopefully things will change now. I re-integrated a physics engine, this time BEPU physics, which is a screaming fast open-source XNA physics engine with unbelievable support. I was able to get my existing block simplification/rendering code to work with BEPU, so now you can add/remove blocks to/from existing objects on the fly.

As promised: Component Binding "BEHIND THE SCENES"

In the wake of this brief description of my component binding system, I was asked to provide more details on its implementation. This article is my best attempt to do so! This is a tale of intrigue, excitement, and wonder, in which I try to implement a component-entity system in C#, and stumble upon a remarkable paradigm that merges components with data binding. Note: If you don't have at least a vague concept of component-entity design, read this article first.

Game dev job, Macs, and re-focusing my project

Apologies for the lack of Parkour Ninja updates. I do have fresh info about it somewhere in this post. But first! A list of potentially interesting goings-on of late: School's out for summer! And I'm one year closer to a Computer Science & Engineering undergrad degree from Ohio State. I'll graduate in about a year and a half, right around my 21st birthday actually. I haven't the foggiest idea what to do after that.

Pistol: Part 2 - Texturing

And here's episode 2 of the Sig Sauer Saga! In which I attempt to UV map and texture the model from Part 1. And do lighting and compositing for a decent somewhat photo-realistic render. Take a gander. Feedback appreciated!

Pistol - Part 1: Modeling

Poking my head in here to confirm that I am in fact not dead. I humbly offer this nifty time-lapse video as proof. Started a small project to brush up on Blender skills. Modeling a Sig Sauer P220 in Blender 2.57. The model is low-poly and incomplete (need to finish the other side, the magazine, some bullets, etc.), but it's close. Next up, textures, materials, lighting, rigging, and animation!

Parkour Ninja Alpha 1

It's here, and it needs lots of play-testing! Please help me out and play it. You'll need a Windows machine with a Shader Model 3.0 graphics card. I'm anticipating some technical issues with this release (it is an alpha after all), so if you run the game and no window appears and the process dies, please do the following: Run the game in administrator mode. In the game installation folder (C:\Program Files (x86)\Parkour Ninja\) open the file "

Back on track

I finished refactoring with components, added a reflection-enabled editor and XML serialization, finally got real PCF shadow filtering, and started experimenting with a somewhat cel-shaded visual style. I've been busy. The refactoring had a lot of positive side effects. Serialization is now relatively easy, as the state of each component is determined by its properties, which are usually simple, easily serializable value types. One interesting side effect of serialization is that object creation is now split into two parts: initialization, and binding.

Refactoring with components

Update: check this article for more in-depth details on Component Binding! I've been refactoring my engine with the component-entity model, and things are turning out quite nicely. The one problem I always had with components was the way inter-component dependencies were handled. In the article I linked (one of the classics on the subject), the author says his components originally referenced each other through a component manager, but eventually they allowed components to store pointers to each other for performance reasons.

Prepping for alpha release

[These posts are now being mirrored on my GameDev.net developer journal. Check out their new revamped site, it's pretty sweet.] I am getting ready for an alpha release soon, very basic, with one tutorial level and a level editor. So looking at installer options for XNA games, this WiX XNA installer appears to be the best choice. It's designed for SharpDevelop, and it creates an installer that checks for all the required libraries and even the required shader model.

Parkour Ninja animations

I'm going to poke my head in here to reassure everyone that the game is making steady progress. The environment now turns transparent when it gets in the way of the camera, and the player has some nifty new moves and mechanics, plus a very shnazzy looking power bar to indicate how much "juice" you have to perform special moves. The latest addition here is the skill roll, which prevents you from slowing down or dying when falling long distances.

December 2010 Tech Demo

I finally got animations working! I'm using a Blender to FBX script, along with this fantastic multi-take FBX importer. Apparently XNA depends on the actual FBX API for importing, and the API changed drastically just before XNA 4 released, so they didn't have time to get multiple takes (animation clips) working in one file. This importer automagically splits out the takes from the FBX file, processes them independently, then combines them into the original model.

Further deets

Okay, it's time to shed some light on this project. First off, my goal is to release on Xbox and, if possible, Steam (if not, I'll be looking at other online stores). I figure these are the two largest, most practical target markets. The release price will be between $1 and $5, with 100% of the proceeds going to charity (more on this later...). There are two main themes I want to nail in this game.

Back at it!

That's right kids. I's back with a new game project. I will post these two tantalizing morsels for you. Let the wild speculation begin! I realize the chill music in the video doesn't exactly match the motif of the above image, or the whole game really, but hey, it's just a tech demo. No need to start murdering people just yet.

Tricksy closures

Do not be fooled by the elegant simplicity of the mighty closure! Behind its shiny dynamic veneer lies a powerful machine capable of destroying your immortal soul. Behold: function GetOutputFunctions() { var outputFunctions = new Array(); for(var i = 0; i < 4; i++) { var x = i * 2; outputFunctions.push(function() { alert(x); }); } return outputFunctions; } var functions = GetOutputFunctions(); for (var i = 0; i < functions.

Phew

Well, I submitted A3P to IndieCade on Friday. It's also currently in QA testing for an online gaming portal (BigPoint, still free of course). I won't say that A3P is done, but I think it's pretty stable. I need to do a bit more work on the connection establishment process (it seems a little fragile), but other than that, there's not much else to do. I also packaged the game into a standalone version available here: Windows (68 Mb) and Debian Linux (77 Mb).

Moar physics entities

Drop pods no longer sit in one place, they now roll around, freely dispersing their monetary goodness among the citizenry. They're quite light too, which means a single grenade can send one flying across the map, with your bots following in hot pursuit. Speaking of maps, Sector X is just about done! It's definitely our most massive map to date, and it has some interesting moments. So far the ring around the top has been great for sniping.

More maps

The main menu now has a global chat room, powered by some simple PHP/MySQL. The tutorial has been updated (it looks a LOT better), and the website received a makeover too! A lot of behind-the-scenes updates have been happening as well... the network code is becoming increasingly bulletproof, and several more physics bugs have been addressed. And now for the fun stuff... more multiplayer maps! The first one is called Gold, it's adapted directly from the gg_halo_gold CS:S map.

Feedback from beta 2

Hey everyone, it's me again. I'm happy to report that Beta 2 turned out pretty well! We got a bit of publicity for the final release, and more importantly, some valuable feedback. It sounds like people had trouble with the browser plugin, so in addition to the browser-based game, I'm also going to release a stand-alone version with a self-contained installer. This also re-opens the possibility of LAN parties in the absence of an internet connection.

Beta 2 is out!

A3P Beta 2 is live, go check it out! This release has a whole slew of new features, some of which have been covered on this blog. To recap: New camera angle and aiming methods. Should be familiar to fans of Gears of War and loads of other third person shooters. New money system (the return of drop pods!) with a whole new UI for purchasing items to boot.

Meshes of navigation

Update 8/23/2011: the source/executable for the navigation mesh .obj exporter is here. Import a mesh, set up the parameters (only simple mode is supported right now), and have it generate the mesh. It should output a .obj file in the directory where it was executed. The AI system has finally received a massive and desperately needed update: support for navigation meshes. That means the bots shouldn't get stuck running into walls all the time, or running back and forth between waypoints like machines.

More stuff!

We are closing in on a new release here... in the mean time a lot of new features have been added! First, and most notably, I'm experimenting with a new camera strategy. If you've played the excellent Just Cause 2, it's very similar. By default your character is off center to the right, with a wide, inaccurate crosshair on the screen. You can right-click to zoom in and increase your accuracy and damage.

Drop pods are back

And they're much more interesting now. Instead of delivering reinforcements, they now act as cash dispensers. So rather than receiving a flat sum every match, you'll have to earn your money by remaining near a drop pod. Currently, the pod doesn't make you wait and then dump all the cash on you in one transaction; the money is deposited in $10 increments every second. We'll see whether that changes or not.

New maps, new weapon, new money system, new game mode!

I've been silent here for a while, but that's just because I've been busy getting some glamorous new features in! Things are really starting to shape up. First things first. Bobpoblo has joined the team as a mapper/tester! He's been working hard on some new maps made in Hammer, textures courtesy of [-B-]. The original maps will likely be remade as well. Unfortunately the content pipeline is a little convoluted: I open the Source map in Crafty, export it to Wavefront OBJ format, and import it into Blender.

New command system and social portal

Quick update just to keep this blog alive. I've made some improvements to the command/AI system. It's now much simpler and easier to tell your units to attack a specific enemy. The closest enemy you're aiming at is highlighted, and you can hit Q or E (depending on which one of your two units you want to command) to order an attack on that enemy. Special abilities are also mapped to Q or E, when tapped twice in quick succession.

Spawn points and more networking

Networking has received yet another performance boost. I discarded Panda3D's network classes in favor of Python's sockets. I also switched to a single-threaded, non-blocking system that performs significantly better and clears up the messy Panda3D threads that were acting very strangely. I also improved the connection process; both the client and server now send packets to each other while connecting, in an attempt to punch through even the most draconian of NAT schemes.

Finally, online multiplayer!

I've updated the browser plugin to finally support full online multiplayer! Go try it! I think the plugin is now stable enough that I am promoting it as the officially recommended method of playing the game. :) Of course, there are still some problems. Namely, in Internet Explorer the mouse control doesn't work. Testing so far has shown Firefox 3 and Chrome (on Windows) handle the game very well. So give it a whirl, and please post any errors or bugs you get, along with your OS and browser!

Update

Not dead... just really busy. Been doing a lot of network debugging and optimization; I added zlib compression to the network packets, which cut down network bandwidth by about a fourth. I also streamlined a few network issues, added a simple network performance logger, and implemented simple client-side interpolation; everything moves much smoother now, even if there is a slight delay. It's basically a fact of life these days in online games; as long as hit detection is still accurate, a small delay is practically unnoticeable.

Gameplay trailer

Finally got sound working in these videos, yay! New features in this video include the aforementioned shadow mapping and reloading, a brand new three player map called Orbit, and heavy modifications to the original Impact level. I really cannot wait to get the multiplayer up and running, and get people playing the beta. Next on my to-do list are a few standard online features: basic match-making, in-game chat, etc. Without further ado:

Reloading, shadow mapping

Thanks to the Panda3D 1.7.0 shader generator supporting shadow mapping, and the awesome new BuildBot service set up on the Panda3D website, A3P now supports basic shadow mapping! Actually, the sun is just implemented as a giant spotlight with a 2048x2048 shadow buffer. Definitely not the most efficient or high-quality method, but certainly the easiest, and the results are acceptable. Also new in SVN is a reloading mechanic. The shotgun, chaingun, and sniper rifle all have to be reloaded, with varying clip sizes and reload times.

Schedule delays

It's time to face the facts. While the game is progressing at an incredible pace, it's not going to be ready by January 9, or even the end of January. So, I guess I failed to meet my deadline. But! I'm not giving up. I'll still be releasing regular updates, and especially once the multiplayer lobby server is set up, things will start getting a lot more polish. My new goal will be to finish the game before school lets out for the summer.

v0.5a released

That "a" stands for "not quite ready yet". This is sort of an intermediate release that focuses mainly on online multiplayer, which is largely functional, but needs more testing. Aside from polish and bug fixes, the only other things I'm going to add are more weapons and special abilities. And maybe a new level. We'll see. This release went much smoother than the last two, as I used Panda3D's built-in packpanda to make the installer.

New name: A3P

Goodbye Stainless, hello A3P. I spent a good chunk of time creating new A3P material and switching everything over to the new name. Unfortunately, SourceForge's UNIX rename feature is down, so I created a new project for web hosting purposes only. The code and file releases are still on the Stainless SourceForge project. Which, to be extra confusing, I renamed as well, but again, I couldn't change the UNIX name.

New gameplay

Sorry for the distinct lack of updates this blog has. A lot is happening right now with Stainless, and most of it's good. :) First off, Stainless is going to have online multiplayer! Woot. Thanks to the fabulous work by the guys over at Panda3D, it may even live in a browser plugin on the SourceForge website. Either way, I came across a problem I never anticipated with online multiplayer: NAT punch-through.

Stainless v0.4

Available on the new website: stainless.sf.net There's a whole bunch of new stuff in v0.4 that I don't have time to talk about. So check out the website to see the new HD trailer.

Replay functionality, new icons

Yes, you can now view the last five games you played as a spectator! All I did was save each network packet that's sent out into a big list, then use Python's pickle module to serialize the list to a file. Each packet has a timestamp, so I just read the packets back in order, checking the timestamps to make sure it reads the packets back at the right speed. Fast forwarding is not implemented, but it would be pretty easy.

November update

This month's release will start to show more of the Real-Time Strategy side of Stainless. One new feature that unfortunately will exclude a section of the target audience is speech recognition. I'm using the MS Speech API, which obviously only works on Windows. Sorry Linux and Mac users. :( Still, it's going to be worth it. Right now the level design and AI are not quite advanced enough to benefit from speech commands, but the potential is there.

Stainless v0.3 beta released!

Along with an HD trailer. Free download here!

Prepping for first release

Less than one week away from release! Looking at the to-do list from last week, I actually haven't worked a lot on the items listed. I've been ironing out a lot of bugs and adding polish. The multiplayer scoring is now working, and you can see everyone's scores on the top of the screen, conveniently color-coded. I killed the ugly black boxes around the scores and added drop shadows instead, and I moved your current balance to the right side of the screen, to avoid confusion.

Production schedule

Yes, I have a schedule/deadline now. I'M SO NERVOUS. :) Here's the plan. And when I say "forum", I am of course referring to the fabulous GameDev.net forums. October build - Release 0.3, Oct 31 - with the following AI droids: shotgun, sniper, shield, cloaker, melee, chaingun. Virtual file system, XML map format, working multiplayer with scoring and simple "game over" condition. No ability to choose units yet. First forum announcement.

More shiny!

Three updates, one in graphics and two in gameplay. Graphics: new water shader! Thanks to Panda3D's new built-in support for user clip planes in the shader generator, the reflections were a piece of cake. It's a very basic shader that simply deforms the render buffer and the reflected render buffer, then blends the results 50-50. No fresnel, no lighting, nothing. It works, though. Using the distortion shader from my last post, I added a shield droid that puts little shields around team entities in its vicinity.

Panda3D distortion sample

For any Panda3D users out there, this is an improved version of the frame-buffer distortion sample currently shipping with Panda3D 1.6.2. Whereas the original sample just samples a wave texture to offset the frame-buffer sample location, the shader in this version actually uses normals from the Egg model. It also gives a slight tint to the object. You can easily adjust the color and intensity of the tint at the top of the "

New artwork

Yeah, I'm back to art now. I am ashamed. But I'm starting to get the hang of this Blender stuff. Check it out: And here it is in-game. Don't worry, I fixed the clamped textures on the bottom after I took this screenshot. And here's the new map, along with the new and improved springboard/booster thing model:

And now for something completely different...

I actually planned a full-fledged single-player campaign for Stainless, before I came to my senses and downgraded it to a much simpler multiplayer game. However, I'm still considering a short (2-4 hours) campaign. What I have in mind is similar to Valve's strategy with Left 4 Dead: a short, highly replayable campaign designed for 2-4 players. With one catch: the players are fighting against each other. With my limited marketing and branding skills, I have dubbed my idea an "

Network system description

As promised. :) First, a small disclaimer. This network system is designed for a very specific task: handling networked physics/gameplay over a LAN network. The structure described here might be useful in other scenarios, but the actual Python code is certainly not fit for much else. The system follows a modified Model-View-Controller pattern that focuses on two main types of objects: Entities and Controllers. The "View" part is split between the Entity and Controller.

Perfunctory postage

Wow, so many updates to cover. I've been without internet for awhile, so... deal with it. :) Let's start with a list of new improvements: Networked gameplay is now fully functional. Weapons, grenades, springboards that propel players around the map, it's all there. I'll make a bigger post one of these days that describes the whole system in more detail. It was quite educational for me, and I'll still be modifying it for awhile.

Networking and better particles

Network code is working reasonably well now. The server generates a unique MD5 hash (only six characters) for an entity, then broadcasts a packet to the clients instructing them to spawn an entity of the correct type, and assign the same hash as its ID. From then on, the server turns over the reigns to the entity's controller, which can send any information it wants in its own sandboxed data packet.

Done with art for a while

I've spent way too much time fooling with the Blender-Panda3D content pipeline, so I'm moving back to working on gameplay and coding. That being said, the art was fun while it lasted. Here's a sample of the results: All art in this screenshot was created by me. The arena geometry enclosing the map was created by extruding individual faces of an icosphere. The texture maps were drawn in the excellent Inkscape, then touched up in the lightweight-but-useful Paint.

First major update

Mmm. Been a while, hasn't it. Latest and greatest feature list: Nifty particle effects for bullet impacts Decent AI pathfinding Grenades don't go through walls any more :D New test map with spiffy baked lighting courtesy of Blender Current project: revamping the orbital dock model seen on the front page screenshot. First up: my first shot at a rusty grungy metal texture. Made from scratch in Photoshop in about a half hour with four layers of noise, airbrushing, blurring, burning, and dodging.