Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Little Procedural Pixel Worlds (jason.today)
227 points by jasonjmcghee 33 days ago | hide | past | favorite | 61 comments
Took a break from the falling sand simulation blog posts this week to work on another small project. It's a little pixel world generator- each time you visit, you'll see a new little world. I really like this stuff and had a blast building it yesterday!

Now I regret “being productive” on my day off instead of playing Dwarf Fortress.

This looks lovely, well done!

Agreed. Came to say it looks like Dwarf Fortress.

Thank you!

this x100

I like it but it would be more interesting for me if you provided some web page with the documentation of that.

I am more interesting in the explanation of your code that the code itself.

Did you have a look at the source for the page?

This is a real, self-contained HTML page as intended by the old ones.

Nice one, I like the coloring, it'd be nice if it was dynamic or things could live on it, maybe next step? I have a few random for fun projects lying around:

map gen and hydrology project hydrosim:


pet map gen and having "people" living on it:


This is really cool =)...

Do you mind if I dig into the code and figure out how it works?

I'm really finding the market that you've got going interesting, how in-depth is it?

I've got a thing[0] I've been prototyping which does a market simulation that I'm working on and I'd be curious how far you've gone down that rabbit hole? =)...

- [0]: https://folcon.itch.io/fruit-economy

Supply/Demand was pretty simple on the individual level, just had to aggregate it: https://github.com/Aperocky/prehistoric-simulation/tree/mast...

Sure, but how that translates to a price is an interesting question.

The simple model consist of buy and sell orders, buys come with a max price, sell comes with a min price, both come with quantities.

Just have to meet in the middle by dynamically accumulating orders by quantity from both sides and after the prices met, set that as the actual sell price and discard the rest of the order as not filled.

Hmm, ok, really similar to how an order book does it I think?

Pretty different from my approach, so that's worth trying, thanks!

Hydrosim reminds me of the map generation phase of Wilderness.


Really cool stuff. I kept refreshing and it took me back to the days of all those ZZT games but this evokes much more geography. Crazy what you can do with ASCII characters and 256 colors.

And beyond, as demonstrated by MegaZeux, the spiritual successor to ZZT

ZZT!!! one of my first coding experiences!

I've been playing around with something similar recently and I'd encourage you to look into doing this with pure webgl rather than p5.js. It's surprisingly simple (this would just be a `gl.drawArrays(gl.POINTS,...)` call it with some buffer setup and texture `texelFetch` reading) and freeing and empowering to work from the groud up without frameworks. It's also really nice to offload player offset and zoom to the gpu/shaders (it handles it really smoothly and with basically more straightforward than you'd have to do to only draw things that's on the screen with canvas rendering).

Great idea. This would be dramatically lighter weight in terms of client download and more performant. I believe color variation logic could also be offloaded to a fragment shader.

I had a lot of fun drawing instantly without a library, but p5js has so many great things that are easy to forget.

Between noise, color conversions, prebuilt draw loop, event handling and working with images…

It’s not so easy to give it up for quick projects.

Suddenly 10 minutes in p5js is an hour or very difficult without a replacement library (noise) and focusing on boilerplate instead of the interesting bits

I totally get this argument. The only counter argument I'd put forward is that once you've set up that boilerplace once (which you've now figured out), abstracting that into a little library file of your own that you understand isn't too much work (and easy to extend in the future). Another argument is that learning raw webgl and getting comfortable with it (which repeated boilerplate setup and general comfort with all the API calls creates with long term use) is likely learning that will transfer over to future projects more than mastery of p5 in particular would.

I'm mostly saying this as if talking to an earlier version of myself since I spent a lot of time learning threejs when I in hindsight now realize doing it with raw webgl (while building up a little boilerplate abstraction library and generally gaining comfort with the API) might have been a better use of time (especially long term). Kinda depends on what you overall goals are though too (and how eager you are to make the idea you have come into reality) etc etc.

Very cool! I love the colour scheme.

Refreshing the page for more worlds reminded me - at some point someone recommended this[1] Chrome extension to me and it's been neat to have a new satellite view of earth show up every time I open a new tab

[1] https://chrome.google.com/webstore/detail/earth-view-from-go...

I would love a firefox & chrome extension that would generate a tinyworld on every new tab.

Really cool, I did something similar for a university project where I had to implement a Minecraft clone. I don’t remember all the details, but I used multiple, differently scaled Perlin noise “textures”, a 2D one was responsible for the surface terrain (which determined the type of the upper n percentage of blocks there), another 2D managed the height at each block column (with some interaction with the terrain texture’s value?), and a 3D one was responsible for caves under the surface. It was my first try at anything similar and a surprisingly easy code generated surprisingly good results.

Love it. Ultima III !

Makes me think of Temple of Apshai and similar RPGs from the early PC and Commodore eras.

("Oh, man, my hit points are like, inexcusable in this dungeon, man. I need to find some elixors or something.")

It should date me fairly well to know that I'm familiar with Temple of Apshai, but only because of the other reference. "Man... I throwed up all over this maze."

Been working on a similar thing recently, but this looks fantastic

It looks like you're using some kind of perlin noise, one idea I had (probably been done a million times before) is rather than using the "height" of the noise to decide on a tile, you could have it decide on a biome, which itself has a list of tile types with a weighted random choice of which one it picks; so you're forest areas can still be populated with grass for example, but tree's are more common.

Is it open source? I want to add clouds and birds and weather and time!

[edit] Also I'm getting a lot of "out of bounds" errors when I resize my window.[/edit]

The source code is all there and not obfuscated. You can just download and edit it!

I'm probably going to continue working on it as a personal creative project, so I'm not planning on taking PRs- I hope that's ok!

Maybe I should make a community fork?

If possible could you include a license? I don't like touching code without one, as sharing modifications and/or derivatives is a potential copyright violation.

Here it is - the community repo: https://github.com/jasonjmcghee/little-worlds

I will make a community repo with a license!

Regarding the out of bounds. Indeed. I should fix that- middle of the work day / week now though!

Love this! Are you using Simplex noise maps for altitude, temperature, and humidity? What's the process like?

Nothing so creative / complex! You can check out the source code, I didn't obfuscate it. It's just hand-picked thresholds for perlin noise, leveraging the built in noise function in p5.js

Really great use of tiles and colours to make a great looking effect :)...

Nice work!

Are you familiar with the procedurally generated worlds in Dwarf Fortress (they have some similarity to your project)?

I haven't played it before, but from my understanding, it's an incredibly complex simulation.

This is much simpler! Just hand-picked thresholds of some parameterized perlin noise.

Definitely has a Dwarf Fortress feel to it, but I think it's mostly the colors/"ASCII¹ art" feel.

Almost like a pristine world, still unsullied by the various races & evils that inhabit a usual DF map. Peaceful.

¹not really ASCII, ofc.

As an aside would it take a lot more code if this was made with Phaser?

Just wondering what's the easiest way to do something fun like this (procedural generation with tiles, but also basic rogue gameplay perhaps).

As others have already said, I’m getting some Dwarf Fortress vibes from this.

I found this at a time when I was feeling rather blue. It was fun to come up with stories for each of the maps that I generated. Kept my mind off of things. Thank you.

Nice, but every world is a swamp for me. So much water :)

I'm always surprised how charming this kind of thing is. Inspired to do something like this too.

It would be nice to give an option to download an image of this page in required dimensions. I would really love to have these as my wallpaper.

I got a desktop-sized image by putting the browser in full-screen mode and taking a screen capture via the OS.

Love it, procedural world generation is a ton of fun

Immediately makes me miss my old MUDs.

This reminds me of the character graphics you would get on Commodore computers in the 80's

Yup the colors and look are not unlike Ultima III / Ultima IV on the C64.

Let me click on the doors and chests to toggle the open and close.

love it , inspiring , I think it can be done just with css also :)

borked on safari

Interesting! Could you provide some more info? Seems to work on Safari on iOS and Mac for me.

macOS Catalina, Version 13.1.1 on Macbook

I appreciate that! I should have been more specific- I was curious about the error (in the console) you encountered or how exactly it was "borked"

It also doesn’t work on iPad safari version 13. I’m not at my laptop now, but I’ll update you on the error message later.

[Error] SyntaxError: Unexpected token '='. Expected an opening '(' before a method's parameter list. (anonymous function) (little-worlds:94)

This is what I get on my laptop. Probably don't have to worry too much, I'm generally a hold out when it comes to updating OS versions, so things that expect newer features might not work for me

Thanks for the follow-up. I think Safari 13 doesn't support static vars on classes. I'm not using a bundler or anything. I'll think about how I should approach this in the future.

It is working on Safari 14 on iPad.

Not trying to contradict TheRealNGenius, just hoping to put some bounds on what works and what doesn’t. Perhaps there was a fix in Safari 14 that allows this but was broken in 13. I don’t have access to an older Safari to test against.

I'm seeing it fine on Safari 15.4


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact