I found a pinball machine sitting disassembled on the floor of a leaky shed and brought it home to tinker with. The mechanisms and electronics inside were all rusted solid, as was most of the metal on the outside. The backglass had lost half its paint, and one entire side of the machine was covered in mold.
I'd originally planned to disassemble the machine for parts, but after I got the glass off I found that the playfield itself was in amazing condition. With the glass to protect it and no light, it had survived unscathed, and I couldn't bring myself to tear it up. Instead, I decided to teach myself some electrical engineering and wire it all up to an Arduino.
I managed to clean off the mold and dirt using a combination of extremely toxic solutions. The door and plunger needed to be sand-blasted and repainted. Luckily, the rails along the edges were stainless steel, so they only needed a quick cleaning.
If you've got any questions, feel free to email or tweet me; I'll be happy to elaborate
- "On the importance of Magical Girl Heroines & Weaponized Femininity"
- "You, Too, Can Be a Monster"
- "Techno-Culturally Faking It"
- "PS Vita Is Dead; Long Live PS Vita"
- "The hidden dangers of legal highs"
- "Notes on Tomb Raider"
- "Spirits by the Numbers"
Sales data for Spirits
- "Let's Play: the first section of Anomalous Materials from Half-Life 1"
- "Soylent Month Three"
I'm amazed how much they can figure out about nutrition
- "Cities & The Dead"
Interesting interpretation of capitalism
- "Our Immiscible Future"
on formalism vs zinesters
- "Getting the development / PR balance right">
- "Love or Money?"
- "Fiction Denial"
- "Steven Soderbergh’s State Of Cinema Talk"
Fascinating both for the parallels to game development and for more general insights
- "Terry Pratchett’s Discworld Might Be The Highest Form of Literature on the Planet"
An exaggeration, of course, but Pratchett is the only time I've seen comedy not get in the way
- "Zooming In"
More pretty paperrendering
- "Only one of Infinite Endings"
- "He Doesn’t Row: Player Interaction in Bioshock Infinite"
- "Why Is "Bioshock Infinite" A First-Person Shooter"
- "Richard Cobbett on Bioshock 2"
- "BioShock Infinite: Now Is The Best Time"
- "Broken World: the Failure of Columbia"
- "There's Subtlety, Then There's Cowardice"
- "BioShock Infinite’s first moments, and why game openings are so important"
- "Nobody at the tower"
- "The American Dream(s)"
- "On Bioshock Infinite"
- "Cara Loft : Tomb Raider Concept Raiding"
a bit of info on the development process
- "From Doom to Dishonored, considering the firstperson shooter's various waveforms"
I miss 100pt based health...
- "No One Knows About Your Game"
A sobering reminder
- "Bloggingheads With 'The Week's Scott Meslow : 'Game of Thrones' As TV Novel, And 'Mad Men' Season Six"
I've always wondered about the mechanics of multiple protagonists in video games
- "A Letter to Leigh"
There was a big fuss about this letter, but reading responses to it felt like we must have read a different letter. As it is, it contains a few interesting observations throughout its rambling length
- "The Jellyfish Entrepreneur"
- "If you make PCs and you’re not Lenovo, you might be in trouble"
It's not the market, it's you
- "Talking is Harmful"
SPEC OPS SPEC OPS SPEC OPS
- "Android piracy still sucks"
A pirated copy is still a lost sale, it just isn't costing you money
- "Bullseye from 1,000 yards: Shooting the $17,000 Linux-powered rifle"
It's only a matter of time until you don't need to aim
- "Plastic Soul: One man's quest to build an AI that can create games"
- "We Are One: JRPGs, the Group Journey, and the Mechanics of Cooperation"
- "Identifying the “Problem” with Female Protagonists"
- "Light and shadow"
More interesting information on rendering paper
- "Mansplainer, For Men: Why Don’t Women Like It When You Tell Them They’re Hot, In Public?"
- "Mobile Hardware Stats (and More)"
Mobile is growing
- "This Isn’t the Article I Wanted to Write About Tomb Raider"
- "Brindle on Mechanics"
- Heuristics Ho!
A quick observation on psychology.
- A Third Option
- No Self-Respecting Woman Would Go Out Without Make Up
Not sure what to think if this one. It had a lot of interesting thoughts with a perspective I haven't seen before, which is always good, but there were a few things that left me scratching my head...
- Where the Heart Is: The Use of Home in Video Games
Although the article doesn't touch on it, I've always liked/wished for scenes where the protagonist visits their home again part way through their journey. Assuming it wasn't destroyed, which is a depressingly common trope.
- To Swell the Ranks
Thoughts on Sony and indies
- How To Make Paper
A very interesting technical read on rendering paper. Things like this make me happy simply because I'm reminded that people actually care about this sort of thing to such an extent.
- personality hunger and the regulation of consumptive choice
Many interesting observations on consumerism
- Storms and Teacups
I'm not sure what they're actually talking about, but it has many interesting observations on the gender divide
- Who's buying all these niche simulation games, anyway?
You know you've been wondering. A few sobering tidbits about the problems even niche players are facing as well.
- "You sleep rather soundly for a murderer": on murder systems and destabilizing virtual societies.
Murder has lost its impact.
- I have been a writer for two years., I interviewed Nolan North on a prepaid credit phone for 12 minutes
Always good to get another perspective
- Relax, don't do it: pulling the trigger in Spec Ops: The Line
- Concerning Garriott, Game Designers, and Corporate Overlords
- A Uniform Rebellion
On indie as a genre
- Apathy and refunds are more dangerous than piracy.
Or, the problem with stocks
- RPGs: Is Old-School the New School?
- Editorial: Let’s Not Pre-Order Games Any More, Eh?
This should really be obvious...
- This Is Actually Happening
- Esther and Stanley and Fate
I got a hold of an old EM Stock Car pinball machine a few weeks ago with the hopes of repairing it, but my first attempt ended in failure. The machine had been sitting in a damp, moldy garage against a wall, under a leaky window for at least twenty years, and it was beyond repair. About a third of the inside was covered in mold, all the moving parts were stuck, all the metal was rusted, and the back glass was damaged beyond repair.
So instead I realized that this would be a good way to use an Arduino. I could just plug one into all the inputs and outputs of the machine and then program it to react in the same way all those complicated and broken electronics would have. I ordered an Arduino Mega, which has 54 I/O ports, and then got to work investigating how complicated it would be to interface it with the pinball machine.
Some quick testing revealed that all the moving parts of the pinball machine ran off 25V AC, which posed my first problem, as the Arduino runs off 5V DC. Asking about how to fix this online wasn't much help; the experts couldn't even agree on whether an AC coil would work with DC. Being the pragmatic and cautious individual that I am, I of course took the rational route, and hooked two old car batteries up (12V DC each x2=24V DC) to a solenoid to see if it would work. (It did). Of course, this still left the big problem, which is that even if the coils would work off DC, they still needed 25V.
The answer, of course, was to use a transistor, or a MOSFET to be precise (I still haven't figured out the difference), to switch the high power current with a low power current from the Arduino. Three burned out husks of transistors later, I'd figured out how they worked, and rigged up this insane hodgepodge of circuitry to control the eight solenoids in the machine.
After an arduous day soldering wires to all the components and hooking them up, I now have control of all the moving parts of the machine from my Arduino.
Tomorrow, I get to start working on wiring all the rollovers to the Arduino so it can begin actually scoring points
Posted Saturday, March 23, 2013
at 09:42 PM
When you notice a character doing something that seems out of character, do you:
- Wonder what could be making them act strangely or
- Think "that's bad writing; they wouldn't do that..."
Posted Sunday, June 03, 2012
at 04:41 PM
Tags: Blog Post,
After I added shadows, the next thing I wanted to implement was some editing tools. This turned out to actually be fairly simple, the only complicated was determining which object the mouse was clicking on, which is commonly referred to as picking. The simple way to do object picking is just to render all the objects a different color off-screen, and see what color is under the cursor. Nice and simple, and as a bonus it will work with anything you want to draw. No complicated math needed.
However, since I'm using custom shaders for all my drawing (not to mention having some real complex drawing code to begin with), adding more shaders to render per-object colors, rearranging my code so that I can easily do one off renderings with custom shaders, and keeping yet another shader up to date whenever I change something in another one didn't sound very fun. Instead, I went for Option B: math
Selecting an object using math boils down to making a line from where the camera is outwards for a few thousand feet (I chose 10km, because why not) and seeing which objects it intersects. Luckily, most of the complicated math for seeing which objects the line touches are handled by the physics engine (it even has a special function designed for it!). The trouble is always in the part you overlook, and in this case that was actually calculating the position of the line! I was lucky enough to stumble on some example code that calculated the end point of the line for you, through some complex trigonometry and interpolation, and so I spent about an hour trying to get it working in my engine, to no avail.
Then I remembered one one of my basic rules of programming: never steal code when you don't understand what it's doing. If you're lucky, the code will 'just work' and you'll have some cool new effect in your particle engine without any work on your own part, at least until you need to change something. God help you then. Good luck trying to decipher all that code months later, when whatever bits of understanding you had before are long gone.
So I went back and sat there for a second, and ten minutes later I had some custom code using a completely different math working perfectly. Just put a point at the mouse coordinates, and one unit into the screen, rotate it like the camera is, and then scale it by 10km! Five lines of code which will work with any setup the renderer could use instead of 40 lines that would break if I changed the field of view. From there it was a simple matter to code up a select and move tool and hook them to some fancy buttons (which took longer to whip up in Photoshop than coding the tools themselves did), and now I can pick up stuff and put it in other places.
Remember way back at the top of this post, where I wrote "Physics and Selection," never guessing that in the end I'd write about selection before physics? Well when I said I was lucky that my physics engine (Bullet Physics) already had a function to test the line against the object, I sorta lied. I actually added the physics engine so I wouldn't have to deal with writing that single function myself. A bit overkill, but like anytime I do stuff the right way instead of the simple way, I'm always glad I did later down the line. As it was, adding physics to the engine was much easier than anticipated, thanks to the severe abstraction I placed on every aspect of development. All I had to do was read out the position of each object and plug it into my code for handling positions (which can also handle positions with quaternions, euler angles, and even ones that orbit another object), and then I was done, no changes to any preexisting code required.
I whipped up a 'quick' (quick meaning it somehow took three hours) command line program that will make a list of all of a twitterer's followers, and compare it to the list from the last time you ran the program to find if anyone unfollowed them.
To use it, just run it from the command line and pass the name of any twitterer
Originally posted on the TIGSource ForumsNo random battles. Battles only take place when they'd actually take place (i.e. no just putting in scripted enemies for battling). However there are people you don't have to fight or you only have to fight if you want. For example if there's a guard blocking a door you could go normal RPG route of finding another way in or you could just attack him + suffer the consequences.
No grinding. Weapons don't have arbitrary "attack strengths," they actually work with other weapons reasonably. Enemies are all adjusted based on your level, but an enemy that is supposed to be tough/impossible would still be much higher level than you
Characters still have stats, like strength, agility, etc, which effect which weapons are best for them, and their ability to block, etc. Dodging/blocking very important, you cant take a ton of hits like in Final Fantasy or something. Game is turn based, but not overly strategical.
Characters have various actions they can perform, such as move, attack, use item, magic, dodge, etc, each with an cost. Each turn you get a set number of points to spend on as many actions as you want/can afford. The amount of points you get can be leveled up. You also can level up your ability to get 'roll over' action points from the last turn by not using points.
Not grid based, and when you move, you don't select a destination, you actually get to control character normally for a certain number of steps.
Characters, even melee, don't have to be within arms reach of enemy to attack. (ie up to maybe 20 feet away you could attack) You get critical inside arms reach though. Attack strength falls off with distance, except for ranged attacks obviously. Similarly arrow attack strength would fall off without line of sight, etc.
Many spells have area affect, including healing. There is a second class of spells that only affect you or your enemies, so your bruisers can get in close at the expense of more costly/weaker magic. If you have multiple characters close enough, their stats will increase slightly. Healing magics have greater effect the farther you are from enemies.
Elemental magic is strengthened/weakened by environment. Life magic is more effective in a forest than a desert, etc. On a smaller scale, water magic would be more powerful if mage stands on edge of stream, earth magic is more powerful if they stand on a boulder, etc. Also works in reverse for targets.
Skills are all leveled separately, through performing the associated actions, not from assigning points to them when you "level up." Your multiple action skill is leveled up by performing the same action for every opportunity on a turn, strength is gained from using heavy weapons, etc.
Your ability to dodge/block is based on your agility/dexterity, combined with the direction you're looking compared to your enemy, as well as choosing 'dodge' as an action on the previous turn.
You can enter combat mode at any time, by drawing your weapons, which would immediately put possible enemies on alert if they saw you. To run from a battle, you just need to get all your characters together far enough from your enemies.
It took a few days, but I finally ironed the kinks out of my omni-directional shadows that used cube maps instead of six separate lights. In the end, they only seem to be faster when I use a depth cube map, which is only available on newer graphics cards, instead of packing the depth into an RGBA texture. This seems sort of weird, but I think it's a case of mythical stuff happening within the graphics driver I have no control over. Anyway, since I can just switch between the two methods at will, I can easily choose whichever is faster at run time.
All my shadows up to this point have been from a 'spotlight', because the shadows are made by taking a picture from the light's view, and pictures are obviously squares, not 360 degree pictures. The way most people get around this is by using a cube map, where they take six pictures, put one on each side of a cube, and then use that to check against instead of a single picture to see if a pixel is in shadow.
I've never used a cube map before, but before I started I had the idea of just putting six one-directional lights in the same place, pointing in different directions, which would act the same as one cube mapped light. It seems to work pretty well, once you get rid of the lines where two lights overlap. Of course, its doing a lot more work than having a single light, so I still need to implement cube mapped lights. However, it's nice to know that I could, for instance, use this method to easily make a glowing pole, or other weirdly shaped light without making any new lighting code.
- Made ShadowMappedDirectioinalLight use frustum culling.
- Added animation support to the S3D format.
- Added S3D save/load testing code.
- Added plane based frustum culling.
- Made Model and Font correctly calculate radius.
I fixed shadows of moving objects, and also fixed lighting on animated objects. Before, the normals werent updated with the object's movements, so even if it turned around the lighting wouldnt change.
- Fixed repeated usage bug in ArrayProxy.
- Made lights bind Shaders instead of Renderers.
- Added doubleSided flag to Material.
- Re-enabled blending.
- Fixed bug with left edge of shadow maps.
Shadows are working much better now. First, I realized that the fronts of most of the objects were also in shadow somehow, and that lead me on a giant chase before I finally found another problem in my bias matrix. Then, I had some corruption problems on the bottom and left of the screen. Turns out my code for checking if a point was outside the light was checking like this:if(abs(coordinate)>1)
but the left and bottom side are at 0, not -1! That fixed a ton more errors. That weird circular shape was caused by a sphere I was using to show where the light was. Somehow it was so close instead of just blocking everything out it made that circle. Last, I made use of hardware accelerated shadow comparisons using a GLSL command called sampler2DShadow, which does the distance check automatically, as well as performing basic Percentage Closer Filtering, which is a cheap technique for making the shadow edges look a bit better. Im assuming that having a command for that means that theyve got special hardware to do the check, so Im hoping Ill get a speed up from that. Which leads to my last (and ongoing) problem. As you can see in the image, the text is all messed up, and Im still trying to figure out why
- Switched shadow mapping to use shadow2D (hw compare+PCF) instead of manual compare.
- Havent checked speed yet.
- BUG: Text still now working again.
- BUG: May be some weird artifacts on right side of shadow.
After a lot of finicking I got at least semi-normal shadow mapping working. It took a few days, and there were LOTS of problems on the way:
- Storage Problems: Shadow mapping involves taking a picture of the scene from the light, and comparing it with your normal view to check if the light can 'see' what youre processing. If the light can 'see' something, then it must not be shadowed! The thing is, you have to have a REALLY exact picture, or youll get all kinds of false positives and negatives. Much of my time was spent trying to verify that the different storage methods I tried were actually getting the picture through to the second stage. Once I verified that the images was getting through, everything moved much faster.
- Engine Bugs: Up until this point when I rendered the scene, I made a list of all the objects in it and then drew each one, removing it afterwards. Since you need to get a view of the scene from the light as well as the camera, I couldnt remove the objects until I was completely done. It turns out that each time you draw an object some of its data gets changed, so when you start drawing everything twice, youre going to run into problems. This was exasterabated further since I couldnt see what was getting drawn the first pass.
- Math Problems: You need to do some complex matrix math to compare the light's picture and the camera's, which I stupidly copied from another website without understanding it first. Even after I decided it must be the problem, and figured out what it was doing, I still had problems, since I hadnt redone the 'bias matrix' once I understood everything. It was just "copy these numbers that never change." Once I took a closer look, it seems that they were displaying the matrices on the website upsidedown! Once I flipped them it worked fine
Now Ive got the basics, which is supposed to be the easy problem, I can get on to trying to make it look good. If you look at the picture, you can see two of the problems: the far side of the shadow looks ridged, which I think is just because my shadow map isnt high enough resolution. An easy enough fix! Second, the bottom of the Y is shadowed. This is going to be the hardest problem. When you do your shadow comparison, youve got a constant 'wiggle' number that slightly shifts the results. If you shift it once way, shadows near the object thats casting them will disappear. If you go the other way, the front sides of the objects closest to the light will become shadowed. You can see this on the Y. The closest part (the bottom) is getting shadowed when it shouldnt be. I think to solve this Im going to need to somehow store my numbers with a higher precision, but Im not sure how to do this yet. Third, and most importantly, MY LIGHTS NOT SUPPOSED TO BE CIRCULAR! See how its casting a circular patch of light? Yeah thats supposed to be rectangular. I have no idea whatsoever why thats happening, and its really confusing me. Now that the shadows actually work, Im going to have to do lots of research into these (hopefully common) issues, and make the shadows have soft edges, like in real life