Hacker News new | past | comments | ask | show | jobs | submit login
Interactive 3D ASCII scenes (yeahpython.github.io)
341 points by aqi 5 months ago | hide | past | web | favorite | 58 comments

About WASD controls and alternative layouts: apparently JS supports key codes.

[1] https://www.w3schools.com/jsref/event_key_keycode.asp [2] https://keycode.info/

Edit: Apparently it is deprecated:

[3] https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEve... [4] https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEve...

Also there doesn't seem to be a way to detect the user's preferred layout before pressing any keys, that would make printing the instructions hard.

The linked article [3] links to KeyboardEvent.code which is not deprecated and still supports physical layout

> Also there doesn't seem to be a way to detect the user's preferred layout before pressing any keys, that would make printing the instructions hard

I am using a programmable keyboard that I’ve set up with a Dvorak-based layout. Here: https://configure.ergodox-ez.com/layouts/ENb6/latest/0

Games defaulting to WASD are fine as long as they allow changing the keybindings in the game.

I prefer that games do not try to detect keyboard layout because they’d probably get it wrong anyway.

Since the movement speed is tied to requestAnimationFrame, the speed of the game changes with the update frequency of the user's monitor. Since all my monitors are at 144Hz this game is ridiculously fast for me.

To clarify, there's nothing wrong with tying your movement to requestAnimationFrame() and it is in fact encouraged, but you must modulate it by the frame delta.

That is only true if you write your own physics. Otherwise, your physics framerate should be fixed, usually at 30FPS. Many physics engines don't support variable timestep, and in the ones that do, it can lead to instability and general weirdness.

Weird statement. All games and game engines I've worked with have used frame deltas to modulate everything from animation and movement to AI and UI's. I've worked on mobile games to AAA games.

Can you link to a physics engine that doesn't support variable timestep?

You definitely use frame deltas when updating things (I mean, how else would you know how much time has passed), but when doing physics, that frame delta is constant for the lifetime of the simulation.

Box2D User Manual > We also don't like the time step to change much. A variable time step produces variable results, which makes it difficult to debug. So don't tie the time step to your frame rate (unless you really, really have to).

https://stackoverflow.com/a/21273467 (Bullet) > maxSubSteps: Should generally stay at one so Bullet interpolates current values on its own. A value of zero implies a variable tick rate, meaning Bullet advances the simulation exactly timeStep seconds instead of interpolating. This feature is buggy and not recommended.

Edit: The archived version of the (404-ing) Bullet Wiki also says "Bullet maintains an internal clock, in order to keep the actual length of ticks constant. This is pivotally important for framerate independence. The third parameter is the size of that internal step."

I don't understand how not writing your own physics engine automatically negates what I said.

If a developer has implemented a third-party physics engine, they should refer to that engine's documentation.

Typically physics engines can't be "modulated by the delta" (which I assume means varying the dt when integrating), you just have to tick the physics world multiple times and keep the roundoff for next time. [0] gives a good example of implementing this kind of thing.

If you implement your own, you can make dt a parameter instead of a constant, but this is more complicated, and can lead to tunnelling when the framerate is too low.

[0]: https://gafferongames.com/post/fix_your_timestep/

Well first it depends on what you mean by typically. Number of total engines in the wild? Or current market share?

But besides, if you are using a fixed physics engine you should not be using rAF. It's not meant for that. Your comment is just a bit tangential.

Bullet, Box2D and PhysX all highly recommend using a fixed timestep, and no, you should definitely be using requestAnimationFrame with a fixed timestep, just like in the fix-your-timestep article. The number of frames to advance the simulation by is still determined by the screen's refresh rate, after all.

That really depends.

Pegging your fixed timestep engine to rAF could have the consequence of dropping frames when you have a large gap between two frames and enough physics frames get called at once that the next rAF window gets missed. If your performance is bounded by the physics simulation, you could potentially trigger a spiral of death and never catch up.

Of course there are ways to mitigate this, but that just further complicates things.

You have the right idea, adding each frame delta to an accumulator and triggering a physics step when reaches the appropriate value, however rAF is not the answer because it can create a potentially infinite frame delta.

It's usually best to not peg your fixed-timestep physics to rAF or at the very least, pause the game entirely when the window isn't focused.

Damn, you're right, it's more complicated than I thought. But what else would you use? setInterval suffers from the same problem, doesn't it?

That's a good question. setInterval definitely also has its strengths and weaknesses, but it does beat rAF() here in that you can guarantee at least one frame will be ran every X milliseconds.

With regards to Javascript physics engines, I'm only versed with Matter.js.

Matter.js's Engine.update() takes a frame delta as an argument and uses Verlet integration [0] to make things work under the hood. You can optionally calculate a correction factor to be applied each frame in order to smooth out calculations with janky framerates, but if you can maintain constant FPS then it's not an issue.

Unfortunately, rAF() once again becomes a pain because of the lack of proper control over FPS capping, so monitors with higher refresh rates have a larger window for variable frame deltas. I'm hopeful that these shortcomings will eventually be addressed in the spec.

[0] https://lonesock.net/article/verlet.html

> Since the movement speed is tied to requestAnimationFrame, the speed of the game changes with the update frequency of the user's monitor. Since all my monitors are at 144Hz this game is ridiculously fast for me.

Damn. I just checked this and you're right: https://developer.mozilla.org/en-US/docs/Web/API/window/requ.... Learned something there so thanks for pointing this out.

I'd always believed that callbacks were locked at 60 fps, although I'm not sure why. Clearly this means all my own games will run at the wrong speed on machines with a higher refresh rate, and will probably appear jerky on displays with a lower rate (assuming such still exist).

I was surprised to learn that many commercial HDR 4K TVs have a 50Hz real refresh rate. Sub 60Hz screens are bountiful and common.

It's also common on a lot of mobile devices as well -- iOS can actually vary the refresh rate on a device from 30Hz (energy-efficient) to 60hz ('standard') upto 120Mhz ("ProMotion") and I'm sure Android probably does this also.

Love it! Just a note, it is not actually 3D, it is an isometric representation of a 2d scene, as same as Monument Valley. Game devs call it 2.5D :)

Why doesn't it count as 3D? I seem to be able to move the character in 3 dimensions. Some parts of the floor are higher than others. What else does 3D mean?

Could you represent this map using just two components for each point? I don't see how.

I believe usually "3D" implies that some change of perspective is possible, e.g. by changing the orientation of the camera.

The libraries that generate(d) such graphics typically only could render such scenes because limiting all edges to the three major axes and discarding perspective (distances on the projection do not get smaller the further the line is from the viewer in the 3D scene) makes it computationally a lot easier to render scenes.

To distinguish them from “true 3D” libraries, a name had to be found. 2.5D seemed fitting.

It seems to be a 3D world, projected onto a 2D screen, just like almost every other '3D' game. I think they're nit-picking because they think of isometric projections as being less "3D" than perspective ones.

The github user gave me hope it would somehow be a python-in-the-browser thing somehow.

But I can quell that disappointment and say how cool and exciting this is (if your target gameplaying public is the kind of people who hang out on HN; those who haven't seen a terminal aren't going to grok the graphic style).

Its years since I've done a game jam like ludum dare, but I hope some of HN get inspired to enter that kind of thing! Good luck and happy coding!

Woke up this morning feeling quite crappy. Then saw this. All faith in humanity (And the internet) has been restored. Thank you! [On a sidenote: How would one go about learning to build this? Any learning resources on understanding all the math and physics behind this?]

This was built through incremental edits from a Python proof-of-concept, which you can see here: https://github.com/yeahpython/ascii-renderer/blob/master/fun... It doesn't have any real physics, but reading through it might help reveal how the rendering works.

For the physics, I'm basically colliding against a grid of tiles, so this might be a helpful tutorial to do the same: https://jonathanwhiting.com/tutorial/collision/

Thank you!

Wish it had mobile touch event support to experience it. Looks interesting

This is something out of my wildest game-dev dreams

Very cool. But feedback in case developer is here: the jumping physics could easily be much smoother and prettier, and the surface feels icy and hard to control.

Mind bogglingly awesome. I was just dreaming about a 3D ASCII engine. But I would have rendered to planes and used billboarding ;)

Why WASD ? A lots of people on the Internet doesn't have a Qwerty keyboard.

And a lots of people don't even use standard keyboard layout, should they be supported as well? Don't be ridiculous, WASD for controls has been used since Quake.

Wait. What do you use for PC games by default in those countries?

Big games already have the right bindings, the others have to be configured. Sometimes it is not possible, and we just pass.

WASD is fine in games if you listen for key codes, but not if you're comparing it to the key character

The keys exactly at the same place, normally it's done automatically by the game.

You just remap whatever keys are in that position. For me on Dvorak that would be ",aoe".

It supports arrow keys?

It's because I just changed the game to support arrow keys :)

What about mobile users?

They can play something else

Oh. Too bad then

what about apple watch users?

Lol. If I can use the buttons on my internet connected toaster to play then it just ain't worth having.

Happened to be using my phone at the time

Great job! I’m amazed.

The game reminds me of Monument Valley [1].

[1] https://www.monumentvalleygame.com/

Now multiplayer this gem à la agar.io/slither.io and maybe pull in a little revenue through ads.

Reminds me of the old C64 game "Realm of Impossibility"


I'm not sure if second level is glitching for me, or if it is supposed to be a 3D representation of a hypercube - traveling in any direction shows more cubes with parts carved out

It's supposed to be like that, just jump into one of the cubes.

Looks cool, but I can’t try it out on mobile. Good job regardless!

Would be better if it supported arrows in addition to WASD for controls: it is literally unplayable internationally.

It does support arrows though. Worked fine for me at least.

This is crazy cool. How do you create the maps ? After all, they are 3 dimensional not flat !

would love to see how this could transform into a rougelike (or a rougelike with the same aesthetics). really cool job! will poke at the source.

Inventory, items, enemies, weapons, towns, crafting, destructible levels (could a voxel based system work in ASCII?), ...

Someone farther up linked to Monument Valley [0], and that has a really pleasant rotating mechanic so that the player can have more than one view of a level / set-piece.

A little wave-collapse [1] function for automated level building.

I suppose I could go on. This does fall into the trap of "why don't we just ... ?" which I don't like. But I also like to dream a little.

Registration is open for Startup School 2019. Classes start July 22nd.

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