Show HN: 90s.dev – Game maker that runs on the web

164 90s_dev 63 5/20/2025, 2:58:03 PM 90s.dev ↗

Comments (63)

MrGilbert · 24m ago
I love what you did there! It's an awesome project. I directly traveled back to my childhood. While I love pico8, I think it's a decade too early for me. I grew up with desktop and gui. This feels like buying a CD again.
90s_dev · 13m ago
You might also be interested in Picotron[1], made by the same guy who made Pico8. It's basically a desktop OS with the same basic design as Pico8 but with slightly looser restrictions. I've never really tried it, only looked at his gifs once a long time ago, but I think he and I had the same basic idea: make a platform that you could make pico8 in. We just went different routes.

[1] https://www.lexaloffle.com/picotron.php

90s_dev · 5m ago
It just occurred to me:

Pico8 is to Picotron, as Tic80 is to 90s.dev

or

Pico8 is to Tic80, as Picotron is to 90s.dev

90s_dev · 4h ago
Hi, author here.

Thank you everyone for the feedback. It's clear that I launched this far too soon.

I'll work on the pain points you all noted, and come back in a few months.

9dev · 1h ago
Absolutely not too soon! This is a great project; it's so amazingly, ridiculously overengineered, in the best way possible! The most beautiful bike shed I have ever seen. You even implemented your own reactivity system.

I love it.

90s_dev · 1h ago
Ha, thanks! Yeah the reactivity system was born out of trying to get stuff done quickly. I was tired of manually setting variables so I made it easy to "chain" and "adapt" them and stuff. Same thing with the (hacky?) auto-layout system. Shortcuts to get stuff done quick!
electroly · 4h ago
It's just right for a Show HN. I was able to find the Hello World tour and grasp what's going on here, from previous PICO-8 and React experience. Looks pretty cool, and I think 16:9 is a good pick. PICO-8 being square is awkward.
90s_dev · 3h ago
Thank you to you and the other replies. You're very encouraging. I'll keep iterating, making it more usable and its usage more clear. Maybe I can at least finish at least a few tasks while it's on HN's front page(!!!) based on everyone's feedback. Going to work on finishing the paint app right now, hopefully done within an hour.
dapperdrake · 4h ago
Thank you for launching early.

Definitely launch often.

10,000 iterations. One down. 9,999 more to go.

worthless-trash · 4h ago
No sir, you didnt launch too soon. You're doing great.
gtoast · 1h ago
I'm stuck on the first step of the "Getting Started" guide.

1. I've downloaded helloworld.zip to my local computer, I think. 2. I open the filer.app.js by clicking the link on the webpage. This open a 90s.dev instance right on the page. 3. Then i'm supposed to mount helloworld/app as app and click it, so i click the mount button, it asks for the drive name, hi put in helloworld/app and click mount but nothing happens.

I must be missing how you're supposed to get helloworld.zip into the 90s.dev instance... how do you upload it into the instance?

90s_dev · 59m ago
Thanks for the feedback.

You're likely using Firefox, right? This feature relies on showDirectoryPicker which Firefox doesn't support. You'd have to use Chrome for the getting started guide.

Also, the drive name shouldn't have a path. Name it something like "foo". I'll udpate the guide to reflect this. Then foo/helloworld.app.js will point to /some/local/path/helloworld.app.js, as long as you mounted "foo" to point to the directory at "/some/local/path"

kleiba · 41m ago
Boo for "Chrome only"!

Could you find a work-around to support firefox as well?

90s_dev · 10m ago
I took great pains to support Firefox, mostly in my service worker.

Unfortunately when it comes to mounting drives for faster local development, there's nothing I can do until FF supports `showDirectoryPicker`

However, you could just load up a local file server in your local directory (python -m http.server 8080) and import your file directly:

  import 'http://localhost:8080/index.js'
Then put that one line of code inside usr/myapp.app.js and click it in filer[1]

You'll have to use filer to create the file and edit it by right-clicking, then type it in and ctrl-s to save or use the top-left menu button.

I'll add all of this to the website under some "Using Firefox" page or something, for people who can't stand Chrome.

[1] https://90s.dev/os/#sys/apps/filer.app.js@usr/

winslow · 3h ago
Does the paint app work for anyone? https://90s.dev/os/#sys/apps/paint.app.js

I tried in both Firefox and Chrome on Linux and picking colors and clicking I can't draw anything. No logs in the console that alert something is wrong.

On a different note I think you've captured the 90s really well. I had a moment of realization that the 90s really were like this. On first look I was thinking this was more 70s/80s terminals. Looking forward to seeing where you take this.

90s_dev · 3h ago
Oh, no, sorry for the confusion. The color picker is as far as I got with that app, it's relatively new. I can probably get it fully working within an hour though.

Also thanks, that's exactly what I was going for! I wanted to capture the fun and excitement and raw power of creating GUI apps in the 90s (but without all the inconveniences). Hence the name 90s.dev

90s_dev · 3h ago
Working on paint app[1] now:

- [x] Add canvas with semi-transparent background

- [x] Make canvas resizable by dragging corner (min 1x1)

- [x] Show grid on canvas if grid button is checked

- [x] Make zoom adjustable by clicking and dragging zoom number up/down

- [x] Show selected color as square over canvas during mouse move

- [x] Allow click/drag to change square colors

- [x] Right-click/drag to erase squares

- [x] Support loading/saving bitmap

Hopefully I can finish it while this comment is editable! :D

As features are added, you will see them in the source code. Either:

1. Click the top-left button and click View Source

2. Download helloworld.zip from Downoad SDK and view /fs/sys/apps/paint.app.js

3. Open https://90s.dev/os/fs/sys/apps/paint.app.js in an incognito window

These all show the same live copy of the source for the paint app. The reason for the incognito window is because the service worker compiles TSX to JS at runtime.

[1] https://90s.dev/os/#sys/apps/paint.app.js

[edit] Ha, I did it! I got all the features working before the edit button went away! But it was about 2 hours, not 1. As a bonus I'll try to work on undo/redo.

sureglymop · 2h ago
Hey don't stress yourself out okay :) This is so cool, cooler than 90% of stuff I see usually see in these posts.
90s_dev · 2h ago
Thanks, though I'm not stressed. It's an exciting and fun challenge to see how much I can get done with my fancy GUI API before the edit button goes away :)
electroly · 3h ago
I'm not sure it's implemented yet. If you click the "hash" button in the upper-left of the window, you can click "View Source". From there you can see it's just a mocked up UI, the scroll area just draws pinstripes.
jszymborski · 3h ago
Not working for me either.
duxup · 5h ago
I can't say I fully understand what this is / the capabilities, but man I love the aesthetic.

It's interesting how an aesthetic can make an emotional impact and draw a lot more interest.

90s_dev · 4h ago
I think I figured out how to explain it:

I basically wanted to make a much more usable pico8 for game prototyping. Hence the 320x180 design, and this prototype: https://90s.dev/v1/ But I also wanted the full convenience of VS Code, including full type checking and autocompletion support for TypeScript. So I designed it to be a platform that can be used to make and publish the things that pico8's tabs contain.

Now I see that I released this much too soon.

fidotron · 4h ago
I like the aesthetic, but 16:9 and 90s computing together is just wrong.

The back breaking not quite square trinitron monsters were the best.

90s_dev · 4h ago
I chose 320 x 180 because of Animal Well. In fact, the whole app was originally conceived as a way for me to make an Animal Well style game, but more conveniently than using Pico8 (Billy Basso implied once that he used Pico8 to prototype Animal Well before moving to C++). I still think 320 x 180 is the right size for both games and game makers.

For example, here's a very early (mostly broken) prototype of 90s.dev

https://90s.dev/v1/

Because of 320x180, it can fit the code editor and the mapmaker or spritemaker on the screen at once, and each tab is big enough to be usable.

90s_dev · 5h ago
Thanks!

Explaining stuff is so hard! In fact, this entire article is just me trying to explain what this is in the shortest way possible.

Maybe the shortest version is: 90s.dev is an API around a 320x180 web canvas, designed specifically for making games and game maker tools, with sharing capabilities built-in, and an innovative GUI for making game maker tools quickly and easily.

No, that's still too vague. I give up.

dr_kiszonka · 4h ago
I would put your text under "Welcome to 90s.dev." If possible, I would further simplify it. I took a stab at it below but I am no marketer (or a game maker),

90s.dev simplifies making games and tooling for game creators via:

- an expressive API around a 320×180 web canvas,

- built-in sharing capabilities,

- an innovative GUI.

Each bullet would link to a relevant part of the documentation. I think you also need a page with examples.

90s_dev · 4h ago
Thanks, I'll definitely consider using that in the next launch.
dflock · 4h ago
Show examples of things built with it?
90s_dev · 4h ago
So far, only the built-in apps are made with it.

You can click them on the desktop-thing when you open the app.

So far the only finished app is fontmaker: https://90s.dev/os/#sys/apps/fontmaker.app.js

Their source code for all built-in apps are in https://90s.dev/os/helloworld.zip (found on https://90s.dev/getting-started/download-sdk.html)

johnisgood · 3h ago
Is 320x180 generally enough for anything interesting?
90s_dev · 3h ago
Animal Well uses 320 x 180

https://en.wikipedia.org/wiki/Animal_Well

(In fact I partly made this app so I could make an Animal Well clone.)

johnisgood · 3h ago
I'll check it out.

Would it technically be possible, without too much difficulty, to increase 320 x 180? Just wondering!

90s_dev · 3h ago
Technically it is possible right now. If you create usr/config.jsln (sample file is in sys/default/) and set its size, the screen automatically resizes to it.

I didn't document this because I'm not sure it's the right decision. Allowing screen resize does make it more flexible, but also leads to decision paralysis for most users, who 320 x 180 is probably perfectly sufficient for.

That was one of the genius moves of pico8, which tic80 failed to capture: offering the perfect set of orthogonal parameters for you, so you can just make stuff.

johnisgood · 3h ago
Oh, that is interesting. I think it could be worthwhile to document it for "advanced" or "power" users / developers perhaps, it is good to know that there is no such limitation, as I assumed there would be, meaning it is more flexible than I thought it to be!
inanutshellus · 2h ago
You can't both honor a constraint and give an out for it.

Remember OG twitter and someone complained about the 140 character limit. Imagine the reply was "ok fine we'll let you use more than 128 characters, but you have to click an 'advanced' tab." instead of the "be clever" retort we really got from Jack Dorsey. Immediately there'd be no constraint at all, just an annoying step where you had to click an annoying checkbox.

Point being - if the design is intended to be constrained, then it's perfectly reasonable to own that.

johnisgood · 2h ago
I think your example is different, because we are talking about something that would be only my code, should it not be up to me? And even if it was not feasible right now, someone else would write the code to make it possible, for their own project. Twitter is not your product, you are only using it. And it is also possible to do it, so why not document it? That makes no sense. That is akin to security through obscurity.

Also he said "but also leads to decision paralysis for most users", but it does not have to be the case. Default can be whatever you want.

90s_dev · 1h ago
I think you're both right. It's tricky to know when to make something a default and when to make it a constant. Especially when it comes to users, who cannot all be pleased.
johnisgood · 1h ago
I think it would just kill flexibility, making it the default makes more sense to me, and you should leave it up to the developers using your product, but it is entirely up to you, of course. If I were to turn this into a constant, I would document it at the very least in the git commit message.
danielvaughn · 4h ago
It really is. It’s almost harder than building the thing. Every time I try explaining my side project, I end up just saying “you know…it’s easier if I just show you”
90s_dev · 2h ago
Yep, that's why I decided to make the pages able to have interactive demos. Though only the hello world tour and the refs guide use it so far.
roskelld · 2h ago
Trying to load it on Firefox (Floorp Browser variant 11.26.0) and the examples get stuck on the `Loading` screen. Moving my mouse over it draws the cursor and leaves it imprinted on screen so you get that permanent trail effect.

In the console I see:

  Failed to load ‘https://90s.dev/os/fs/run?  code=H4sIAAAAAAAACk2QMW%2BDMBCFd%2F%2BKa4QEKAiiKlMVs1Rqlw4dmy0GjsSNsRE2TVKL%2F16DSYq3d3ef797jTas6A6zlCVgIEnhFabBL4L1TfbtP4IMVKGb5BQPUnWogzJTOHJN%2B65AQdmF8%2BiJtOxR9hfqNS65PWBFSKqkNlKqXBigE0SaeS1yWrhDFQHPfTn%2BY6HG9vjMtkyjcyP%2Fv%2BqbThp3xc%2BxEFiRr8AVWJxRCwUV1olrBkBCAnTcBmv8itXc0GOUABSvPR%2BdGVtRurtvp1fWQO86R3jYcWUvtdi668pQCGLwaGi72PYWQPWbmiCb0%2BYG6RtEboyRocxNIQ90XDTchsNJwJal1QQx5KXh5hgZ3mR9e0IvV1gfFKtaaSI7JHSYQKwisHMDwBvUhHhZHZf6q2Z1X%2B1HtMh9STmJCpqzTWpW99uHGfz0j7XEYAgAA’. A ServiceWorker passed a promise to FetchEvent.respondWith() that rejected with ‘TypeError: Array(...).keys().map is not a function’.

Seems to work fine in Chrome though.
90s_dev · 1h ago
Thanks for letting me know. Hmm, I don't know what Floorp is doing differently. I'd need more of a stacktrace. It works in regular Firefox though. Feel free to paste a stacktrace and/or stacktrace screenshot on the issues page and I'll take a look.
nico · 4h ago
Looks very cool, just kinda hard getting started

Maybe you could have a little walkthrough of how to build a mini game with it?

90s_dev · 4h ago
Thanks.

The current method of building a game is the same as the walkthrough for building an app[1], except you make a custom view and override its draw method. For higher performance, you can create an OffscreenCanvas and draw into it however you want. There's no API to wrap WebGL2 more conveniently than this yet.

I definitely should and will wirte a guide that takes you from nothing to a full fledged game. But right now, the guides are all geared towards making apps, since before we can make games, we need to make gamemaker tools, like spritemakers and mapmakers.

[1] https://90s.dev/getting-started/hello-world.html

danielvaughn · 4h ago
Love the idea. Ever since I played Dreams on PS4, I’ve been curious about collaborative game development interfaces.
90s_dev · 4h ago
Collaboration has always been one of my favorite things. Shortly after starting this project, the focus began to center around making sure users could create first-class apps and libraries and easily find and use them in their own creations. Much of the API evolved around supporting this idea.
eranation · 4h ago
Love it, and congrats on shipping! I might be missing something but your pitch would be a 10x better launch if I could find some basic demo games developed with the engine, unless I just didn't look in the right place. Looking forward to the next update!
90s_dev · 4h ago
I haven't made any games with it yet. I barely finished any of the game making tools. The platform itself is relatively stable, which is what I spent so much time on. And the hope was that the community would help make the game making tools and the games. But maybe you're right, maybe I have to finish some game maker tools, finish some games, and finish some tutorials to make game maker tools and games, and then relaunch in a few months.
wonger_ · 4h ago
Congrats on shipping!

Based on https://90s.dev/getting-started/hello-world.html, it seems like JSX meets pico8. Is that a decent description?

90s_dev · 4h ago
Thanks! Well, kind of. The JSX is mostly for making the apps that comprise gamemaker components, like pico8's spritemaker and mapmaker tabs. Once those apps are made, you can use them to make game assets. But those apps run in the same canvas that games would run in. A mapmaker and a game would use the same GUI for drawing into the canvas. But a game would probably create a single View and override its draw method to draw most of the game, though it could use JSX to build up the views that comprise game panels like Minecraft's inventory views.
makapuf · 4h ago
Nice, does it work on Firefox?
90s_dev · 4h ago
I took great pains to make sure it does. The one thing that Firefox doesn't support is mounting a local drive so you can develop your app, library, or game more quickly, which needs https://developer.mozilla.org/en-US/docs/Web/API/Window/show...
Thoreandan · 3h ago
Mentioning the licensing up front would be nice.
90s_dev · 2h ago
It's basically MIT. I used to have it injected at the top of the source files. I forgot why I took it out.

[edit] Just added MIT licenses to the top of all the files.

rubabu · 4h ago
Do you have a video walkthrough of how this works?
90s_dev · 3h ago
I tried to make it even more interactive than that. If you click any of the links on this site that start with `/os/#` then it will open (or close) an iframe under it that actually launches the app you're linking to. There's also an interactive demo on the hello world page: https://90s.dev/getting-started/hello-world.html
Sayyidalijufri · 4h ago
I think it little bit hard to start getting started
90s_dev · 3h ago
You're right. I definitely need to put more work into making very full tutorials for this.
sneak · 4h ago
Why limit it to Microsoft services (github and npm)? Why not let it import things from a URL?

Looking forward to your WC2 clone!

bpshaver · 3h ago
Not that you're asking, but https://www.littlewargame.com/ is a good WC1/WC2 clone with a lot of good QoL features included.
90s_dev · 8m ago
Man I wish I was as good at pixel art as those people apparently are!

That's part of why I made my app into a platform where you can build apps but also share apps, libraries, and game assets. I can't make a game all on my own! I'm hoping people make and share spritesheets with this, after someone makes a spritemaker app of course. I'll keep working on my basic one.

90s_dev · 3h ago
Thanks!

Actually I am planning on shifting it towards importing 'https://' URLs directly.

Honestly, the main difficulty I have is keeping full TypeScript support of remote modules. It's actually easier to do this if I import https:// modules directly, though it's not as convenient as it could be[1].

But I'm also trying to figure out whether I should continue to compile TSX to JS in the service worker[2], which requires no special dev-time setup and allows publishing raw .tsx files anywhere on the net such as github, or require users to compile TSX -> JS ahead of time, which would require a build step.

On top of that, I'm considering going further and making it so packages can import bare-specifiers like `import "somelib"` and publish a plugin to compile this into an https:// import specifier.

[1] https://stackoverflow.com/questions/79628025/is-there-a-way-...

[2] I currently use a service worker to map imports like `/os/fs/{ghb,npm}/...` to `jsdelivr.net/{gh,npm}/...` and compile them and return with the right content-type.