I love this. I've been wondering how the picture is drawn with less than one `echo` per pixel, and it's very clever: the game is "not really" 3D, so you can run raytracing just once per column, and then you only need to draw a couple of lines (for sky, grass, and the actual object) -- this is done by outputting the "draw this pixel and move down by one" string to the terminal as many times as necessary using string repetition.
I've been considering working on a voxel render engine (not for Bash, but for another computationally limited environment). This is a treasure, I'm certain I'll find something useful here.
It's unfortunate that stty requires forking. Maybe the next project will be to use bash and rowhammer to call the necessary ioctls to do it without forking.
I had no idea this was possible with Bash. I’ve considered myself proficient with Bash at a pretty advanced level at times and this just blows me away. I don’t have the math chops to understand how it’s implemented, but it’s a pleasure to see.
I never ceases to baffle me how we're still stuck with these mind bogglingly slow shells. Pure madness. I can maybe understand that some apps require all the vt100 weirdness or whatever, but probably 90% of apps just write to stdout and err. Surely we can blit some text to the screen a bit quicker and put the other 10% into some compat mode.
Shells are slow (particularly bash), sure, but I'm not sure how the rest of your comment follows from that. The shell is not involved in interpreting terminal escape sequences in any way, and modern terminals are quite fast - I can render animations in a 350-column terminal and they are as smooth as can be, given the constraints.
Besides, the whole premise of this post is that bash is the wrong language for raycasting, kind of like writing bubblesort in CSS.
>put the other 10% into some compat mode
There is nothing preventing that, just test if the string contains sane characters only and use a fast path for that. The problem is that there is no actual fast path for software text rendering, you still need to process ligatures, etc.
normal arrays in bash are implemented as linked lists. bash stores a pointer to the last accessed element, which turns the most common case of iteration into O(1), but the performance is terrible if you need to jump around
there are also associative arrays which are bucketed hash tables, which are fine for string keys but imho they are hardly ever worth it as a replacement for indexed arrays
She has been brainstorming how to handle texture mapping within the performance constraints of doing it in bash for a week now (long before she actually got this working) and so far we've come up with some hypothetical ideas but she has not tried any of them yet. Maybe tomorrow...
The program from that scene was not some crazy invention for the purpose of having an interesting computer scene. It is a real piece of software for silicon graphics workstations called fsn (File System Navigator).
I love this. I've been wondering how the picture is drawn with less than one `echo` per pixel, and it's very clever: the game is "not really" 3D, so you can run raytracing just once per column, and then you only need to draw a couple of lines (for sky, grass, and the actual object) -- this is done by outputting the "draw this pixel and move down by one" string to the terminal as many times as necessary using string repetition.
I've been considering working on a voxel render engine (not for Bash, but for another computationally limited environment). This is a treasure, I'm certain I'll find something useful here.
The VoxelCanvas.js file (in Javascript, obv.) might be interesting to you as well. Same (raycasting) idea:
https://github.com/EngineersNeedArt/Mooncraft2000
In case you wondered if there is a raycaster written in MS Batch:
https://github.com/nTh0rn/batch-raycaster
That's really cool! The explanation on their blog is great!
Thanks for the hint! That's exactly what I was looking for as I have never looked into raycasting but having an interest in it.
Direct Links:
- https://nthorn.com/articles/batch_raycaster/ (batch variant)
- https://lodev.org/cgtutor/raycasting.html (general intro)
It's unfortunate that stty requires forking. Maybe the next project will be to use bash and rowhammer to call the necessary ioctls to do it without forking.
I had no idea this was possible with Bash. I’ve considered myself proficient with Bash at a pretty advanced level at times and this just blows me away. I don’t have the math chops to understand how it’s implemented, but it’s a pleasure to see.
I never ceases to baffle me how we're still stuck with these mind bogglingly slow shells. Pure madness. I can maybe understand that some apps require all the vt100 weirdness or whatever, but probably 90% of apps just write to stdout and err. Surely we can blit some text to the screen a bit quicker and put the other 10% into some compat mode.
Shells are slow (particularly bash), sure, but I'm not sure how the rest of your comment follows from that. The shell is not involved in interpreting terminal escape sequences in any way, and modern terminals are quite fast - I can render animations in a 350-column terminal and they are as smooth as can be, given the constraints. Besides, the whole premise of this post is that bash is the wrong language for raycasting, kind of like writing bubblesort in CSS.
>put the other 10% into some compat mode
There is nothing preventing that, just test if the string contains sane characters only and use a fast path for that. The problem is that there is no actual fast path for software text rendering, you still need to process ligatures, etc.
And to think, that my own bash scripts spend 300 lines just parsing various command-line options, while instead I could be showing this game... :-P
Only 300 lines of code, impressive! I love this.
"bash is slow."
That's in part why I do not use it for scripting. I do not use it for interactive use either.
Some popular Linux distributions also avoid bash as a scripting shell.
I'd love to see this combined with the author's fork()-less implementation of ps to make a (almost) fork()-free implementation of psDoom.
Seriously though, this is really cool
Of course, we need to give an honorable mention to the `awk` raycaster from 9 years ago.
https://github.com/TheMozg/awk-raycaster/tree/master
Cool Easter egg: https://github.com/TheMozg/awk-raycaster/blob/master/awkaste...
Beautiful. Correct me if I'm wrong, but this looks like a bash version of https://lodev.org/cgtutor/raycasting.html
Edit: ah, just noticed this is in the readme :(
There are https://lodev.org/cgtutor/raycasting2.html and https://lodev.org/cgtutor/raycasting3.html just FYI
yeah i really liked that tutorial
Sadly I can't get this working. It just throws up the view into a file called buffered for whatever reason and exits immediately :(
try `bash game.bash 2>errors` and see the content of that file when the game exits
Very cool! I'm curious when it says "did you know that accessing a random element in an array takes linear time", why that's the case, with bash?
normal arrays in bash are implemented as linked lists. bash stores a pointer to the last accessed element, which turns the most common case of iteration into O(1), but the performance is terrible if you need to jump around
see some basic benchmarks here https://gist.github.com/izabera/16a46ed79c2248349a1fb8384468...
there are also associative arrays which are bucketed hash tables, which are fine for string keys but imho they are hardly ever worth it as a replacement for indexed arrays
Thanks a lot, that's very interesting re. it using linked lists, and nice benchmark!
Wow, that’s an insane challenge. I can’t believe that’s even possible.
I wonder if texture mapping this would look good.
She has been brainstorming how to handle texture mapping within the performance constraints of doing it in bash for a week now (long before she actually got this working) and so far we've come up with some hypothetical ideas but she has not tried any of them yet. Maybe tomorrow...
<3
Imagine a TUI where you need to navigate a literal maze of options
Many CLI programs which take option have already managed to do this (in the text-based adventure game style).
Like this one in Jurassic Park? https://youtu.be/URVS4H7vrdU Funnily enough, the slow rendering is kind of a plot device here.
The program from that scene was not some crazy invention for the purpose of having an interesting computer scene. It is a real piece of software for silicon graphics workstations called fsn (File System Navigator).
There's a x windows remake of it called fsv: https://fsv.sourceforge.net/
And then there's this even cooler UI which takes this whole idea much further called eagle mode: https://eaglemode.sourceforge.net/
psDooM pits you against processes on the system represented as enemies: https://psdoom.sourceforge.net/
That's the kind of "futuristic interface" you'd see in a cyberpunk movie, and it would be incredibly annoying in real life.
[flagged]
Please stop making accounts to break HN's rules with. It will eventually get your main account banned as well.