
It has, apparently, been 25 years since I uploaded the original Mini-Putt Flash game to newgrounds. I guess that makes this as good a time as any to write up a post mortem on the game series I am probably best known for.
I decided to split it into 2 parts. Part one is more of the story of the Mini-Putt franchise, which is probably more interesting to the average reader, and part two will be more of a technical post-mortem going over some of the tricks and strategies I used.
So, without further ado...
Part 1 - To Newgrounds AND BEYOND!
The year is 2001. Linkin' Park dropped "In the End", The Mummy returned, Xena, Warrior Princess, was hanging up her leather corset and the XFL was about to change football forever.
Me? I was just starting to fly as a freelancer after leaving a web development company where I worked as a director for a few years prior. The world was my oyster and nothing was going to slow my momentum. I was going to be as big as Pets.com!
I had a good batch of clients that mostly wanted boring, static web pages, but I was also getting really good at this hot new Macromedia Flash thing all the kids were raving about. I had already made a good batch of stupid point-and-click type games, and was really itching to start exploring what this new ActionScript feature could do.
Lucky for me, elance.com (the website I used to find a lot of my gigs) had an ad looking specifically for Flash game devs to help build games for a big money startup called Whoopie Games.
They were offering good money to make a batch of games, including tennis, a slot machine, blackjack, a racing game and, SPOILER ALERT, miniature golf!
Their original plan was to build some kind of back end community and integrate the games into a forum or chat to make them feel more like an old-school arcade where people could hang out and socialize while enjoying some simple games.
The whole company was very much in its infancy, but the little team was pretty tight. The lead server-side developer was cool as hell and we really hit it off. I bounced most of the WIP versions of these games off of him, and he was really excited that someone could just make this shit in a few weeks. Then he told me I should look at recreating his favorite game from the old Apple II; Taipan.
I found an emulator and gave it a play for maybe an hour before I kinda figured out the systems. It was a simple text-based, trading game, set around 19th century China.
The game loop was mainly just learning where things cost the least money and where you could sell the for the most profit. Occasionally there were pirate attacks where you could fight or flee, with the odds of success being based on how many cannons you bought or what ships you had.
It was a neat game, but not exactly my jam. Still, the idea was fun so I made a version with more of a sci-fi flare called Taipan 3000.
Now, this is a post-mortem for the Mini-Putt games, so I'm not gonna go to much more into the Taipan game, but it IS important because I submitted it to Newgrounds and it ended up really resonating with Tom and Wade, neither of whom I had any real relationship with yet.
They liked it so much, they put it on the front page of Newgrounds, which wasn't something they had done before. It was a huge deal to me, both in getting so much unexpected recognition, and starting up a friendship that's still going 25 years later. This was pretty much the exact moment I became a Newgrounds lifer.
Fast forward a few weeks, and the founder of the company goes silent. We just figured he was busy shaking hands and making deals. But it turns out the project was not working out, and all of this work I had done wasn't going to be used, or paid for. I spent nearly 2 months building all of these games and wasn't going to see a single dime because there was no development contract, the deal was going to be payment on final delivery.
The good news was, there was no development contract, so I owned all of that work still. Most of those games weren't that great, but I was REALLY proud of how the Mini-Putt game came out. I figured out a LOT of tricks to pull it off and decided that was the next game I was going to put on Newgrounds.
At first this was another huge win for me. It got frontpaged right away, the community was having a great time playing it, other devs were connecting with me asking how I did certain things, and life was just good.
Where it stopped being as cool was when the game started getting millions of plays, and shown on TV and posted on popular gaming sites..... THROUGH STOLEN COPIES.
You see, the idea if a game going viral wasn't something we really ever thought about back in the day. Having made the original version for Whoopie, there was no branding in it. No credits page. Nothing linking the game to myself or even Newgrounds as the original intended host for the game.
My hate for sites like Ebaums World knew no bounds. These fucks were just taking our hard work and slapping it on their sites with zero attribution, and raking in assloads of views and ad revenue.
Not all of the piracy was bad. I did think it was cool to learn a bunch of colleges were passing copies around and having tournaments on their LANs and shit like that, but it was rough realizing nobody would ever know it was me who made that game they all loved.
To this day, I have never had ANYTHING I have done get that much attention.
I did eventually wise up and update the Newgrounds version of the game with my Psycho Goldfish branding, but by that point, the viral copy was the version that kept spreading around.
So, I figured the next logical thing to do was make a sequel, that had the proper attribution added in, and a few features that would hopefully drive traffic from any stolen copies back to my personal website. A strategy I would keep using in more and more games, that eventually paid off when my site got popular enough that I could live on ad revenue. Six months after the first game released, Mini-Putt 2 hit Newgrounds.
The sequel never got quite as big as the original, but it was still pretty successful. It used a completely new engine that came with some tradeoffs, like having to limit the max speed the ball could move, but played the same way for the most part. People hated that I limited how hard you could shoot the ball (I added a dumb 'death ball' option you could toggle that removed that, but always played an animation of you killing someone instead of actually hitting the in-game ball lol). There were also a lot of people that hated the music for various reasons.
The one thing that people loved was the tournaments. The original version of Mini-Putt 2 had leaderboards I hosted on my web site that got reset every week. There was one dedicated to the Newgrounds copy of the game, and one for any other copies floating around. The leaderboard would load into the game if it was on my site or NG, but anyone else would be sent to a web version on my personal server (thus funneling traffic from stolen game sites, to where I could leverage it).
Mini-Putt 2 had a few different iterations, including an EXE version that had 2-player P2P multiplayer. This was the first time I ever played with making a multiplayer game, and most people thought it was a blast, there wasn't really anything out there for sharing downloadable games. We were still a few years away from Steam, and itch.io was a decade away. Anywhere you could find exe-based games was guaranteed to give you a virus.
I felt like if I made just ONE MORE sequel, I could get it just right. That said, I also didn't just want to be the "Mini-Putt guy". At the time, I had very little respect for devs who just made the same thing over and over. I also had assloads of other cool game ideas I wanted to explore, so it would take another 2.5 years before I'd come back to the franchise.
In 2005, Flash had really grown as a development tool, with better ActionScript support, and my skills as a programmer had also gotten far better. It was time to go back to the well and make a new Mini-Putt. But this time, I was going to balance all the issues part 2 had, and break free of some of the limitations the older 2 engines both had (largely having to use only rectangular shapes).
Mini-Putt 3 was a very ambitious game for me. It required an engine that could do proper collisions on geometric curves, creating multiple courses to play and providing a local multiplayer experience so people could play with their friends on the same screen. (I would have loved to make it online multiplayer, but the tech I played with on the Mini-Putt 2 EXE was so limited, and people always had trouble with firewalls, that I just didn't think it was worth the effort.) It also had a ton more effort put into the art side.
The game was originally supposed to have 4 courses. A classic mini-golf, a dinosaur theme, a castle theme, and a sci-fi theme.
I built the classic course as a re-imagined version of the original Mini-Putt. The holes are in a different order, but are largely the same setup. That went quite smooth development-wise. This time around, I opted to skip adding music, after all the complaints from Mini-Putt 2.
Then the dinosaur theme is where I got really ambitious. All the new capabilities of the engine got put into play here, and I spent hours and hours and hours hand drawing the course art with a mouse. I was really proud of how it came out and thought it would be a cool idea to release it with the two existing courses and add the other two later on.
Well, you know how it is. You get a game up, and your brain is already thinking about the next cool thing you could make instead of finishing your goals for the last project. So, the castle course never came to be, and the sci-fi theme would wait until the next entry in the series.
I got a ton of positive feedback on this game, and people were constantly sharing screenshots of their best scores over IRC chats. It felt like it could have been a really big community game if only it DID have true online multiplayer.
I sat on that for almost a year before I decided I was going to find a way to actually do it in a web based game, without having to wrap it in an EXE or deal with firewalls or any of those other hurdles.
Of course, I was not much of a server-side developer at the time, and open socket technology wasn't quite as easy to get into as it is today. Thankfully a friend of mine knew a guy who was a backend genius. A guy who I would also become good friends with, and would go on to have a major role here at NG, @brentheman.
We got together and went all in on figuring out how to make a multiplayer Flash game. We came up with a bunch of tricks to minify packet sizes, prevent cheating to a degree, and ultimately threw together a really cool server platform. Having that tool available, we created Mini-Putt Online. Once again, I wanted to push what kind or courses I could make, so this engine used shape based collision so I could literally freehand draw all the walls in any shape and they would just work.
Unlike Mini-Putt 3 where I had to build the courses using a bunch of interconnected shapes with their own collision rules, I could just DRAW the courses in this one. That meant I could bang them out pretty quick.
My original goal was to make another classic course (but do all original hole designs this time), and bring in the castle and sci-fi maps I never got around to in Mini-Putt 3.
I had the classic and sci-fi themes done pretty quickly since they largely just used simple vector art shapes (unlike all the freehand the old dinosaur course needed) and we decided to launch the game with those and get any kinks worked out.
The game was a huge hit on NG. I think there were points where we had almost 1000 players on the server at one time, and it largely held up. We never really got beyond the original prototype, so it would occasionally crash from a memory leak we could never quite pin down, but I still think it was the best multiplayer server anyone had in that era of web games.
The game launched in Sept of 2006, so when I was ready to add the 3rd course to it, October was right around the corner, and I thought... why do a castle theme, when I could do a HALLOWEEN THEME!!! So with a few weeks of work, Spooky Putt came to be, with even more ambition by having 2 views of every hole that could flicker off and on to create a strobe light effect.
The server never left that prototype phase though, and we were both getting too busy to really support it properly, not to mention the player count had mostly dropped off and I was still paying to host the back end stuff. So in late 2012, we pulled the plug. Still, 6 years for an online Flash game was a pretty good run, and I'm still proud of what we were able to do with the resources we had at the time.
It always bothered me that Mini-Putt Online was, essentially, lost media. I was still really proud of that game.
Then something interesting happened. Support for the Flash plugin was removed from browsers. Some psychopaths decided to keep Flash running in web browsers and created Ruffle. Then more psychos decided to make NEW Flash games.
Yeah.. I was in that last camp. Getting into making Flash games again, I participated in the first two Flash Forward gane jams. The 2nd year I participated (with the point-and click adventure, Sausage Game), it really resonated with me that Ruffle runs great in the web browser, EVEN ON MOBILE!
This inspired me to look at my older games and see how they handled. The Mini-Putt games were all playable, but not exactly intuitive for the way mobile works.
So, sometime in 2023 I decided to dig through some old hard drives and see if I could find my old source files, and I was able to find Mini-Putt 2 and 3. The spaghetti code in these was a little off-putting, so after looking through it for a while, I kind of gave up on making these into mobile masterpieces. I did clean up the title screens to remove dead features, like the old leaderboards in Mini-putt 2, and I removed the UFO and castle wall that used to be on the Mini-Putt 3 title screen, officially killing the promise of ever getting new courses added to the game.
I was bummed that I couldn't find the original source for Mini-Putt Online, but I thought maybe a decent decompiler could salvage it. I had used a few decompilers back in the day to rescue my work after an FLA file got corrupted, but they would always mangle your code and use weird variable names and shit like that. I found JPEXS and gave that a try, and couldn't believe how close to the original code it was. Everything was how I remembered it. Even most of my comments were in there. And I had actually written clean, organized code in that one!
So, I stripped out all the old network code, converted it to local turn-based code and even updated the controls when it's running on mobile so it would play a little more modernized on a touch device. I even added some songs from my pals @RealMrSnuggles and @Albe to give it just a bit more polish. I created new menus, a new title page, etc etc, and launched it on Newgrounds as Mini-Putt 4: The Lost holes.
This one was not exactly a major hit. It definitely feels a bit dated, despite the updates, and frankly, the enthusiasm for new games on NG isn't what it was back in the day. But I was happy to get some form of the game back online and not have it be completely lost to time.
There's still a part of me that would love to make one more installation in the series. I've had over a decade to think up a lot of fun new things I could do in a new one. Maybe some day....
Anyway, that's the story of the Mini-Putt franchise for the most part. Now for the nerds out there that want to know HOW I actually made these things and how the tech behind them changed with each version, I give you:
Part 2 - What's in the Sausage?
The first Mini-Putt game was built in Flash 4.
This version of Flash used ActionScript 1, which lacked a lot of features we would take for granted later. There was no EnterFrame loop you could leverage, all of the mouse input had to be captured by buttons, and it could only catch key presses, not releases, so you couldn't properly manage those input states.
It also didn't have any complex data types like arrays or objects. If you wanted array type functionality you had to do something like:
animal_0 = "cat"; animal_1 = "dog"; animal_2 = "cow"; total_animals = 2;
You'd then use a for loop with Eval() to iterate it, or something to that effect. I didn't do anything that elegant in this game lol.
I didn't even know how to get widths and heights of MovieClips when I made this (which in hindsight is fucking insane), so every rectangular space that made up the courses used hand coded values, which I had to manually update any time I moved anything.
The way you accessed properties was with the global methods getProperty() and setProperty(), with a string path that pointed to whatever clip you wanted, using a folder-like path structure. So _root in as1 was "/".
You could also use the global call() function to run whatever code was on a specific keyframe.
Each one of the holes had 3 frames. Frame 1 would use getProperty() on the aiming movieclip to get the pointer position. It would define the overall rectangle for the ball drop area using 4 variables: mat_t, mat_b, mat_l & mat_r. Then it would call "/actions:control" to use the common game loop logic, and finally startDrag on the aiming movieclip so it would follow the mouse.
Frame 2 was a simple "gotoAndPlay(1)", and that was the game loop right there.
Frame 3 was labelled 'params' and had all the hand-coded bounds for the different parts of the hole.
The main control loop would call this frame every tick. So this frame would start out with a universal bounding box using the variables wall_b, wall_t, wall_l & wall_r. This defined the box the ball could currently move in. It also had a box defined by hole_t, hole_b, hole_l and hole_r to define where the actual hole was. In this game, the holes were all actually squares.
When starting a hole, this loop would use startDrag to make the ball follow the mouse. If you clicked the button, and the cursor clip was in the hard-coded mat space, it stopped dragging and would go into aim mode.
Aiming would take a series of ring clips and space them away from the ball in the opposite direction of where the mouse was, indicating where the ball would go, and how fast. This would be the standard for aiming in EVERY Mini-Putt game.
So, Frame 1 of the hole would call the main game code, which in turn, called the hole's 'params' frame code. This would then have access to the ball's current position as bx and by. The ball itself was basically just treated as a single pixel.
The param script would check the ball position, and depending on where it was, might update the bounding box values. This was all done with if/else statements. Hole 1, for example, would check the y position of the ball first. If it was within the thinner middle space, it just updated the left and right bounds. If it was above that, it would then check the x position, and if that was left or right of the thinner area it would update the bottom bounds. Then one final condition for when the ball was below the thin space that might change the top bounds.
The physics were pretty basic in the main control code. If the ball moved beyond one of the wall bounds, It would move the ball to that boundary wall and just invert the x or y direction of the travel speed based on what edge it hit.
There are some rectangles that, if you are on them, they would add or remove some value to the x or y speed values of the ball to simulate hills. They worked okay, but if they made the ball's speed fall into the dead zone I used to determine when friction would cause the ball to stop, it would also stop on a hill.
Then I had even smaller, hard coded collision boxes I used for the angled corner bits. These did not use real physics, that was way beyond me. I had a case for each corner type and would simply swap the x and y speeds, and maybe invert one or the other, depending on what corner it was in. So every single little triangle block has its own code too.
I used another variable to flag when a corner block hit was detected. In any loop where there was no corner collision it would get set to "n", and when it detected a collision, it would be set to "y" to prevent the same corner from changing the ball direction.
There were individual, hard coded, hit boxes for the tubes as well. If you landed on one, the ball would be moved off the screen, and it used the global tellTarget() function to have that tube clip to gotoAndPlay frame 1. Each tube clip played a sound effect, and the last frame would update the x/y and movement speed values on the ball so it looked like it just popped out of the tube and resumed rolling.
The windmill had a rectangular area that was hard coded. The animation of the blade spinning would use setProperty on the hole to either have that rectangle open or not. The visual blade itself never actually acted as a boundary, so I made it spin fast enough that it was hard to tell if it should get through or not.
The loop-de-loop had its own set of actions. The ball doing the loop is actually a tweened animation. When you hit the ramp, it moves the real ball away, brings in the loop animation at the same x position, and the game loop tells it what frame to show based on the ball speed. It applied a positive value to the y speed for the first half of the animation. If the ball didn't have the speed to get through that, the animation would essentially play backwards until hitting frame 1, and the ball would be popped back in with its new y speed. Otherwise, a negative value got applied so the ball would speed up again on the second half until it hit the last frame of the animation and the real ball would pop in again at that speed.
That was a pain in the butt to get working right, so I also made sure this ramp only worked in one direction.
And that was about the gist of it.
When I made Mini-Putt 2, I had Flash 5. That meant ActionScript 2.0 baby! Now we had real data structures, proper enterFrame loops, and I knew how to access all the properties of a MovieClip so no more hard-coding bounds.
This time I wanted to be able to build my holes just by copying and pasting wall clips and having those be where collision events would happen. This made course creation go REALLY fast. However there was one major drawback.
In Mini-Putt 1, we always knew if the ball was on the play space on one frame, and moved off in the next frame, no matter how fast it was going. In Mini-Putt 2, if the ball moved more pixels in a single frame than the thickness of a wall, it would just fly out of bounds and break the game.
I knew I could do multiple collision checks in a single frame, but this WAS still 2001, and that could really slow a game down. Instead I opted to just set a limit on how fast the ball could go, so it would never move far enough on a single frame to bypass a wall.
Any of the corner blocks used their movieclip properties for hit detection, but largely still used the same hacky tricks I used in Mini-Putt 1 for the direction changes. Most everything else worked using the same principles as Mini-Putt 1.
After Mini-Putt 1 went viral and I missed a lot of opportunity to capitalize, I also utilized the new loadVars() and postVars() functions to communicate with a PHP script on my personal website. This stored the best scores from either NG or from other versions of the game in a database that got reset every week. It added a layer of social competition that not many other people were doing at the time, and predated any work I did on Newgrounds.io scoreboards by a good 6+ years.
A few people who played early demos of the game really missed being able to hit the ball crazy hard. I couldn't really let them do that, so I also added a dumb setting called "death ball". Now you could hit the ball at an insane speed and be treated with a bad animation of your ball killing someone. It was VERY 2001.
When the game was done, I started playing with a program called Zinc. It could add lots of new functionality to flash files to make cooler desktop apps. It also had a way you could do direct p2p network connectivity, you just needed to know the ip address of whoever you wanted to connect with, and hope they didn't have a firewall. I used that to create a 2-player version of Mini-Putt 2 that could be played online. It was pretty cool, but I didn't have the means to do much with it.
With Mini-Putt 3 I went back to treating the play space as the defacto source of truth for the play bounds, but also supported solid object clips that could be collided with inside those bounds.
I really didn't want to be limited to just rectangles and triangles anymore though, so I incorporated real triangles and circles as collision shapes as well. This used some actual trigonometry for physics.
I ended up with a nice set of building blocks. Rectangles for the simplest areas, and a mix of triangle, circles, half circles and quarter circles I could use for any rounded areas. These could be used as floors or as walls. This wasn't a full physics model like Box2D, but it had everything you needed to make a ball bounce around in primitive shapes.
I would then draw up the course designs, and fill in the spaces with the primitive shapes needed to make them work. Like previous games, I used simple rectangle spaces to define areas with slopes, which would apply some increase or decrease to the ball's movement vector.
One thing I decided to do different was the loop-de-loop and tunnels. The animation trick could have worked here again for the loop de-loop, but I wanted it to keep using the real physics. So visually, I made this loop into a covered tunnel style loop, and used the same trick for that as the tubes now used.
Basically, I added hit boxes that would teleport the ball. This would send the ball to an area simulating the inside of the tubes and loops that was off-screen, with teleport areas at the end of those to bring the ball back to the main area.
In the case of the loop, it teleported to a simple rectangular area where the bottom half was a downward slope, and the top half sloped the other way. This meant if you hit the ball it could actually bounce around in the loop in a more realistic way.
This engine also let me use real radial collision for the holes, so you could get a lot of fun "almost made it" park on the rim situations that a square hitbox made less likely.
The fun part was the addition of local multiplayer. Specifically because I made it possible for your balls to collide with each other, so you could totally mess with your friends by knocking their balls away from the hole.
Mini-Putt Online was a beast. I believe I used Flash 8 for that one.
This time around, I wanted to play with the BitmapData API and use that to make a collision engine where I could just draw freehand shapes and have them just work. This kept treating the floor area as the source of truth for collisions.
I basically used the BitmapData.draw() to store the playable area as a bitmap. I could draw any simple vector blob, and this API did all the conversion work.
I could then check whether the ball was on an empty pixel or not after moving, and determine if it should bounce. If the ball ends up on an empty pixel, I would step it back, at a fixed vector along the same path (something like 3 pixels per step), until it was back on a valid pixel.
From there I would calculate 2 points out from the ball, each 90 degrees away from the line the ball was moving in. I'd then determine if either point was over a solid pixel. If it was I'd step it forward until it reached a max distance, or found an empty pixel. If it was already on an empty pixel, I would step it back until it found a filled one.
These points would form a line I could then use to calculate the new angle of deflection.
I could also use BitmapData.draw to store slopes in any shape. For most of the course I made in this engine, my strategy was similar to Mini-Putt 3. I would draw up the hole design first, and when I was happy with it, I created my bounding area. However, with this engine, that typically just meant copying the floor art and making it into a movieclip. Super quick!
Most of the other gameplay and collision elements worked the same as Mini-Putt 3.
The biggest change was the Online play. Our server was room and message based. We had commands for joining rooms, and sending messages to them. You could also send messages direct to users. It's been a long time, so I've forgotten a lot of how the tech worked, but I know we ultimately settled on a custom version of JSON for the data structures, that also had some minor compression that old ActionScript 2 could actually handle.
The structure, on the client side, was you would load the game, and auto-join a lobby room. Then it would send a command to load a list of available rooms. You could either join one of the listed rooms, or create your own.
New rooms could have a password attached to make private games, and once a game started, rooms could be locked.
When you joined a room, the player that created the room was treated as the host. If they left, the next person took that role.
The room lobby had a simple chat and everyone could choose their ball color. The host player had to start the game. During the gameplay, the current player would put their ball down, and that message got sent to the room, showing your ball on everyone else's game.
When you'd shoot, the ball vector speed would be sent to the room, and it would start moving on everyone else's screen. Any time the ball hit something, the new vector and point of deflection was sent. This kept every game in sync, but sometimes caused the ball to visually jump around. On each player;s screen, the game engine would also apply any collisions so these jumps were usually small.
If 2 balls collided, the player whose turn it was would pass along any vector changes on all moving balls, meaning the current player was always the source of truth for the physics.
There was a text chat you could toggle as well that was pretty simple.
When I converted this into Mini-Putt 4: The Lost Holes, I had to strip out all of the network code, add in local turn handling, and replace all the setup screens just to get it working as a standalone game. Thankfully all of the physics and score tracking code still worked fine. The biggest change was making the aiming phase more intuitive when running on a mobile device.
If anyone is curious, NG passes a FlashVar to ruffle-enabled games called 'browsermode' with the value of 'mobile', which is how I can tell what type of device Mini-Putt 4 is on.
Closing Thoughts
This took me a lot longer to write than I expected. Looking back at all these games, and trying to remember how they even worked was quite a trip. It's a bummer that they've faded out of the Newgrounds zeitgeist as much as they have, but "golf ball" never really wasn't destined to be a popular character. Still, the fact that ANYONE still remembers a 25 year old Flash game is pretty damn cool in my book.
I hope one or two of you enjoyed this post. I tried to sprinkle in some good Flash history, and maybe be a bit motivating to anyone who doesn't feel like they are very good at making things right now. Keep at it, who knows where you'll end up!
How many of you remember playing these back in the day? What was your favorite iteration? What is the GOAT course of the franchise in your opinion?
New players, what are your thoughts on playing these old-ass games for the first time?