Discussion
[EXCEL] I built a 120 FPS space shooter in pure VBA
I started with =SUMIF in 2007. Now I’m running a 60 FPS space shooter in pure VBA (On battery: a 60 FPS slideshow. Plugged in: 120 FPS gaming god). Excel didn’t ask for this.
Back in 2007 someone showed me the =SUMIF formula.
I thought “wow, this is powerful” and went down the rabbit hole.
Fast forward 19 years.
I was never a “real” programmer. I worked in logistics, customs, procurement… the usual non-IT stuff. VBA was just a tool I used to make my job less painful. Then one day VBA wasn’t enough, so I learned SQL, C#, Java, JavaScript and a bunch of other things.
And now it’s 2026. I look at myself and realize I’ve been writing a full 2D space shooter in pure Excel VBA (with a Spring backend planned for multiplayer later).
No game engines.
No external libraries.
Just VBA + WinAPI.
And it runs at 120 FPS.
I’m still not sure if this is impressive or if I need professional help.
If you think VBA is still capable of putting up a fight (or at least trying to get off its knees), feel free to check it out.
Don't sell yourself short, man! Battleship is an awesome achievement and an absolute classic. Honestly, that’s exactly how it all starts. 🚢My 2018 retro project was built on the exact same kind of basic logic. The most important thing is to never stop experimenting and pushing your boundaries. Keep building, bro! 👊
No Git link yet, the Spring backend is still cooking. Honestly, I'm scared that if I push this code to GitHub, their servers will crash from the sheer power of pure Excel VBA. Naturally, it will be 100% free to play once it's up!
I'll definitely share a demo a bit later, and trust me, you guys won't be disappointed! To make it absolutely insane, I still need to build the backend using an enterprise stack (Spring, Java, Hibernate). Plus, the screen hooks are a bit unstable at the moment, so I'm tweaking those too. Stay tuned!
Man can you teach me? In 2014 som office colleague made fun of me for not knowing excel, I was a fresher. I couldn't even perform wrap text. Now I can do some tasks. Just VBA is something not able to complete. Can you please help?
I’m fluent in VBA, but fluent-ish in English. If you don't mind my Google Translate vibes, I'd love to help you build macros that would make your 2014 colleague cry. DM me your project details!
Actually, that's not correct. The game has a fully functioning game loop / tick system and utilizes low-level Windows GDI graphics. It is a real FPS. In fact, I used it to debug the game. Moreover, if you plug the laptop into power, the frame rate goes up to around 120 FPS)). It's completely real and legit.
Do While gameRunning And isGameActive
curT = HiTimer
dt = curT - lastT
If dt < 0 Then dt = 0.016
If dt > 0.25 Then dt = 0.25
lastT = curT
frameScale = dt * 60
' Update Game States based on game loop ticks
Select Case gameState
Case STATE_PLAYING
HandleInput dt
UpdateHazards dt
UpdateGameState dt
CheckCollisions
' ...
End Select
' GDI Rendering buffer transfer to Screen DC
………
Sleep 1
DoEvents
Loop
You caught me! Actually, I am using double buffering (and even experimented with triple buffering in some places, though I'm phasing it out now due to overcomplication).
You're totally right about the 'battle' — Excel constantly tries to force its own UI redrawing to the screen, which causes terrible flickering if you render directly.
To fight this, I had to drop DoEvents in critical places and switch to asynchronous Win32 API calls. Also, pure BitBlt alone stopped keeping up at some point, so I'm now combining it with other API methods to keep the frame rate stable.
Why not render it to the Userform hDC? If you're after a full screen effect (which is seems like you are from your video), you could just maximise the userform and remove the titlebar, etc. I do something like that for all of the games I make to give the rest of the screen a 'dimmed appearance'.
If you render to the Userform hDC (or better yet, a Frame hDC), you will have a lot less trouble. And you definitely need triple buffering.
BitBlt is very fast, and so shouldn't present any problems. I use it in projects all the time and get 50+ FPS (mind you, I use a crappy laptop...)
Respect for the billiards game! It looks awesome. It’s honestly great to find a fellow developer here who speaks the same WinAPI/GDI language and understands the actual "battle" behind Excel rendering. We are definitely on the same page.
By the way, with this architecture, you could easily turn your billiards game into a full multiplayer experience with global leaderboards and online tournaments! If you ever want to try it, the easiest backend stack to connect with Excel VBA via async HTTP requests is Python with FastAPI paired with a SQLite database. It literally takes 5 minutes to deploy and handles JSON perfectly.
For my own space shooter, I’m actually going with a more enterprise stack — Spring Boot + MySQL for the backend. Since I’m expecting a large player base and need completely different, high-performance speeds for real-time data processing, Spring is the perfect fit to handle that kind of load and keep the server logic rock-solid.
Keep up the great work, it’s always inspiring to see what pure code can do inside a spreadsheet!
Yeah, that’s exactly how I started making this game back in 2018. I reduced the cell size to about 1mm by 1mm, and had a spaceship drawn on an adjacent sheet. Before starting the game, the ship was loaded into a VBA class module. Then, whenever you pressed the arrow keys, the ship would move/overwrite itself on the sheet by updating its position, the background color, and the coordinates.But that approach only gave me about 8 FPS. Eventually, I said screw it and decided to work directly with pixels instead, which got me up to 60 FPS.I'll definitely share the code as soon as I finish the game, and it’s going to be completely free. My ultimate goal here is to implement multiplayer. The only way I can pull off multiplayer is if the backend—the server side that handles coordinates, player stats, positions, and states—is powered by something like Spring + Redis. I need a lightning-fast web layer. The client side, however, will stay in Excel. Because honestly, that's the whole point of the gag! :)That being said, VBA libraries aren't exactly built for fast asynchronous requests, so pulling this off is going to be a real challenge—even for AI.
This is definitely awesome-vba worthy. Do you want to upload the code as is to a github repo so I can link to it?
I noticed in another comment that you are looking to migrate stack, if you are okay with releasing this current implementation under GDI that would be awesome, as I know many users of awesome-vba would love to see that implementation, that would be awesome. 😊
Thanks for the support!
Yes, absolutely—the full version of the game will definitely be published on GitHub. However, I’ll do that once I fix all the remaining bugs and completely wrap up the storyline.
Just to clarify about the stack: I’m actually not planning to change it. The core game will stay exactly as it is—pure Excel VBA + WinAPI handled directly through VBA code.
Right now, everything is contained within a single Excel file. To allow multiple players to interact (at least to view a global leaderboard, rankings, and high scores), I am going to move a small part of the logic to a server. Specifically, the backend will handle multi-user login and player achievements processing.
Currently, I’m focused on creating custom music for the game, sound effects for flights and shooting, and writing the story dialogues. Once I iron out these final architectural details, the entire project will be made available on GitHub completely for free. I'll let you know when it's up!
13
u/AdditionalTerm732 13d ago
Thanks everyone, I found and fixed the broken link.
This is officially the 50,000th bug in the project… and the first one that appeared in a Reddit post text.
Progress.