從 2017 年實驗到 800 多次提交:開發 Retro Paddle 帶來的啟發
From a 2017 Experiment to 800+ Commits: What Building Retro Paddle Taught Me
作者從 2017 年的 Pong 風格遊戲實驗重新開發,將其擴展為 Retro Paddle,累積超過 800 次提交。遊戲加入超過 20 種增益與減益效果、電腦對手及線上多人遊戲,作者亦以 AI 作為結對編程助手,加快嘗試不同效果。遊戲免費,無須帳戶或安裝,支援桌面和流動裝置。
It started with a simple question: could I still build a decent Pong-style game from scratch?
Back in 2017 I opened a canvas and added two paddles, a ball and a score counter. It was a small experiment to see what I could make, and I put the result on YouTube: the first version from 2017.
In January 2024 I picked it up again. Almost two years, more than 800 commits and quite a few late evenings later, that experiment has grown into something much bigger. It now has more than 20 power-ups and power-downs, weapons, portals, sea mines, a computer opponent, online multiplayer and even its own dependency-free npm package.
I call it Retro Paddle, and you can play it right here:
It's free, needs no account or installation, and works on desktop and mobile. Below is how it grew, and a few things I learned along the way.
1. Plain JavaScript, paper and a set square
The very first version, in 2017, was plain JavaScript on an HTML canvas, without a framework, game engine or physics library. There were no AI coding tools to lean on back then either.
What I remember best from those early days is figuring out how the ball should bounce off the walls. I grabbed a piece of paper and a set square (a triangular ruler), drew the ball's incoming direction, marked the wall and worked out what the outgoing direction should look like. The angle of incidence had to equal the angle of reflection.
It might sound a little old-fashioned, but I really enjoyed working it out that way. I wanted to understand the maths and write the behaviour myself instead of pulling in a physics library, and that code is still the foundation of the game.
2. Turning Pong on its side
The next big decision was also one of the simplest: I didn't want another horizontal Pong game.
A horizontal field is fine on a desktop, but on a smartphone you either rotate your phone or squeeze the game into a narrow strip of screen. So I turned the whole thing 90 degrees.
In Retro Paddle the ball travels from top to bottom. You hold your phone upright, your paddle sits at the bottom, and the full height of the screen is your playing field. On a touchscreen you drag your finger anywhere and the paddle follows, so your thumb never covers the paddle you're trying to watch.
It sounds like a small change, but it shaped almost everything that came after: the layout, the controls, the gameplay and even how the power-ups work.
3. A name change I wish I'd made earlier
The npm package was originally called retro-pong-game.
Then I looked more closely at trademarks and found out that PONG is a registered trademark. I'd rather avoid trouble and give the project its own identity, so with version 7.0.0 everything became Retro Paddle.
The gameplay didn't change at all, but the package name, README, website, documentation and share images all needed updating. That was a surprisingly big job for something that didn't change a single pixel of the game!
If you're building your own take on a classic game, think about the name early. Picking a distinctive name at the start is much easier than changing it after you've built a whole project around it.
4. More than 20 power-ups, and one simple rule
Just hitting a ball back and forth gets repetitive after a while, so I started experimenting with power-ups and power-downs. There are now more than 20 of them, including:
- Split Ball: suddenly you're dealing with multiple balls.
- Gun: pick up a weapon and shoot at your opponent.
- Portals: send the ball through a portal and change its path.
- Safety Net: get another chance when a ball slips past your paddle.
- Remote Steering: keep steering the ball after you hit it.
- Mirror Paddle: a mirrored copy of your paddle guards the other side of the field.
- Lag Spikes: make life a little more difficult for your opponent.
- Phantom Balls: confuse your opponent with fake balls.
One design rule turned out to be really useful while building these: the ball is always moving away from you when an effect starts.
So anything that changes the ball reaches your opponent first. Collecting a Fast Ball is good news for you, because your opponent has less time to react. Collecting a Slow Ball actually helps your opponent.
Once I saw that, designing the colours, icons and visual feedback got much easier, because they could show who benefits from an item as well as what it does.
The core game is still the code I wrote myself, starting in 2017. For the power-ups and power-downs, which I added over the last two years, I used AI as a pair programmer. That made it much faster to try ideas, test different behaviours and keep the ones that made the game more fun. Not every idea made it in, of course. Some sounded great on paper and turned out to be incredibly annoying in an actual match!
5. Making the computer opponent feel human
A computer opponent that always wins isn't much fun, and neither is one that lets you win every match. I wanted something more dynamic without building a complicated AI system.
So the opponent reacts to scoring streaks. Score three times in a row and the computer starts trying harder. If the computer scores three in a row, it eases off a little.
It's a simple mechanic, but matches feel more balanced than with a fixed difficulty level. The computer can still be beaten, and both sides keep a fair chance of winning.
6. Online multiplayer without a traditional game server
Online multiplayer was probably the hardest part of the project. Getting two browsers to talk to each other was manageable. Keeping the game responsive once latency and packet loss came into play took a lot more work.
In the end I went for a fairly lightweight setup.
A Cloudflare Worker as a relay
The Worker knows nothing about the game and runs no gameplay logic. It just forwards messages between two connected browsers. Because the relay doesn't need to understand the messages, I can change the protocol as the game evolves without touching the server.
A loopback test page
This turned out to be one of my most useful tools. It's a separate page with two games running side by side, connected through a fake network where I can set the latency and packet loss.
That lets me simulate a bad connection whenever I want, without two computers or a real online connection. A network bug that might take a whole evening to reproduce in a real match can sometimes show up within seconds there.
My biggest takeaway from multiplayer: build your testing tools early. They save an enormous amount of time later.
7. It's also an npm package
At some point I realised the game could be useful outside my own website, so I moved the game itself into its own npm package.
You can embed Retro Paddle in an existing website without React, Vue or any other framework, and it has no external dependencies.
npm install retro-paddle
To get started, import the package and create a game:
import { PaddleGame } from 'retro-paddle';
const game = new PaddleGame({ isAdmin: true }, '#game');
The isAdmin option turns on a settings panel where you can adjust colours, sizes, speeds and other settings live. When you're happy with the result, you copy the settings as JSON and reuse them.
I deliberately kept online multiplayer out of the package. The network code only lives on my website, so nobody who embeds the game gets networking code they never asked for.
You can try the package and read the setup instructions on the demo page:
8. Years later, and I'm still adding things
Looking back, I'm surprised by how much this project has grown. A small canvas experiment from 2017 became a game with its own mechanics, an online mode, a computer opponent and a reusable npm package.
Along the way I've learned a lot about game development, structuring JavaScript, networking and testing, and about how much small helper tools speed up development.
Maybe the biggest lesson is that you don't need a big idea to start building something interesting. A ball, two paddles and some curiosity can be enough. And a couple of evenings, although in my case it turned out to be quite a few more than that!
Give Retro Paddle a try!
If you've made it this far, I'd love for you to give it a go:
You can play the computer, challenge someone on the same keyboard, or invite a friend to an online match. It's free, there's no signup and it works on your phone too.
Here's a video of Retro Paddle in action:
I'm especially curious about a few things:
- Which power-up do you think is the most unfair?
- How does the game feel on your phone?
- Do you have ideas for power-ups or features that would make it even more fun?
And if you've built a browser game yourself, drop a link in the comments. I'd love to check it out!
Thanks for reading!
來源:DEV Community · dev.to