
Show HN: 3D shooter in your terminal using raycasting in Awk - TheMozg
https://github.com/TheMozg/awk-raycaster
======
__jal
General greatness aside, I have to say that's the best quality awk code I've
seen. Too many people treat writing awk like picking up after your dog -
something to get done quickly, when you have to. Which leads to write-only
line noise code, which leads to people treating awk like picking up...

~~~
Stratoscope
I used to write a fair amount of AWK code back in the day. It was great for
one-liners, but I wrote some more elaborate programs in it too. I treated it
seriously, like a real programming language, and it served me well.

My favorite AWK program was probably my LaserJet II code listing program from
1991. I wrote this out of frustration with the terrible default listings I got
when I printed source code. The AWK code did a "two-up" printout of source
code: two pages of code per page of paper in landscape mode. It used a nice
font and drew graphic boxes around the pages. I was in the habit of using
separator lines like this in my code:

//\-------------------------------------

So the program found these and changed them to graphic line separators. It
also avoided splitting a function onto two pages if it could - it would leave
whitespace at the bottom of a page instead, filled in with a faint dot
pattern.

Somewhere I have a printout I made with this program; I was hoping to find it
and scan it in to show what it looked like. I know it's here somewhere, but in
the meantime the source code will have to do:

[https://github.com/geary/awk/blob/master/LJPII.AWK](https://github.com/geary/awk/blob/master/LJPII.AWK)

Of course, these days I hardly ever print out any code. But back then we
printed _everything_.

~~~
david-given
Years ago I wrote a compiler (for bytecode) in awk. Ummm...
[http://cowlark.com/mercat](http://cowlark.com/mercat), although you'll need
to wade through zip files to get at the source. It was 1.6kloc for a fully
typed algolish language producing stack-based bytecode.

awk's a lovely little language, and deserves to be better known than it is.
Its two big failings are local variable syntax and absence of structured
types... and the standard library's a bit mad in places (gsub, sigh). But it's
expressive and concise _and_ still readable, and meets its core competency of
doing easy text processing beautifully.

The most recent thing I wrote in it was this:

[https://github.com/EtchedPixels/FUZIX/blob/master/Applicatio...](https://github.com/EtchedPixels/FUZIX/blob/master/Applications/util/fforth.c)

That's a C file which is also an executable shell script which contains an
embedded awk script. The whole thing's a Forth interpreter. Running the file
uses the awk script to compile a Forth subset into bytecode and patch the
source file with the new bytecode, which allows me to keep the whole thing in
a single source file. It's not what I'd call good awk, but it's incredibly
_effective_ awk...

~~~
Stratoscope
That is brilliant!

So the embedded FORTH compiler written in AWK reads the FORTH code in a
comment like this:

    
    
      //@C SPACES
      // \ n --
      //   BEGIN
      //     DUP 0>
      //   WHILE
      //     SPACE 1-
      //   REPEAT
      //   DROP
    

and compiles it into C code like this (reformatted here to help illustrate):

    
    
      COM(
          spaces_word, codeword, "SPACES", &space_word,
              (void*)&dup_word, (void*)&more0_word,
          (void*)&branch0_word, (void*)(&spaces_word.payload[0] + 8),
              (void*)&space_word, (void*)&sub_one_word,
          (void*)&branch_word, (void*)(&spaces_word.payload[0] + 0),
          (void*)&drop_word,
          (void*)&exit_word
      )

~~~
david-given
Yup! COM() is a varargs macro that actually assembles the data in memory ---
the actual word layout is not the traditional one Forth uses (to make it C
friendly). But the end result is a linked list of Forth words in exactly the
same format that user words have, which the user dictionary extends.

It all means that the C source can just be compiled in a single step --- gcc
-o fforth fforth.c --- without needing a precompilation stage, which makes it
vastly easier to manage.

It's even portable!

------
pacomerh
This could actually be used to build a file explorer, not sure for what, but
it would be fun to explore directories this way.

~~~
andrewflnr
"It's an AWK system. I know this."

------
qwertyuiop924
Like a sculpture made out of snot,you can applaud the elegance of the
sculpture, and the elegance of the construction, but you have to wonder about
the building material...

~~~
ricksplat
Ah but awk is great! It's parsimony when processing structured text files is
hard to beat. Such a pity the next step on from it is perl. Perl is snot
certainly.

~~~
qwertyuiop924
No, the next step from awk is ruby :-D.

Anyways, I was talking about how this thing totally misappropriated awk, not
awk itself.

~~~
ricksplat
In all seriousness, Ruby is Awk's grandchild borne of a virtuous union between
Perl and Python.

After looking at the code I'd agree that it's not really idiomatic Awk. But
come on, snot? I would've said a humble yet more dignified medium, such as
match-sticks.

~~~
qwertyuiop924
But I'd say that ideologically, ruby is far closer to awk than perl is. And
yeah, matchsticks would have been better. I do actually LIKE awk, and will
defend it from anybody who says that it is useless or badly designed.

This is your father's awk. An elegant weapon for a more... civilized age. :-)

------
dTal
Man, that AWK looks a helluva lot like Javascript.

~~~
minimax
As in Javascript, awk represents all numeric values using double precision
floating point. I have always thought that was a strange (but not necessarily
bad) choice for a language that is basically all about text processing. I
guess it works out pretty well if you need to do 3D graphics math.

There is a bit of cheating going on here though. Awk doesn't support true
multidimensional arrays. They are depending on a Gawk extension for that bit
of functionality.

~~~
TheMozg
Actually I tried to do without true multidimensional arrays, but deleting and
sorting elements would be a pain.

------
mcculley
This is beautiful.

I'm reminded of an administration tool I wrote using AWK and ANSI command
sequences. It was the most powerful programming language available on the
machines available to me for that project. It worked great, but in the end
meant that I had to fly back out to that site every time it needed maintenance
or new features as nobody else there knew AWK.

~~~
i336_
Depending on whether the flights were stressful or a nice step away from home
turf, that might be considered a feature, not a bug. It was a nice bit of job
security, in any case.

I also hesitate to say that the site in question deserved to pay for the
tickets, since AWK is reasonably easy to learn, even in the case of 4- or
5-digit-SLOC applications.

But if AWK was the most capable system available, that's saying a bit... :p

~~~
mcculley
While the job security was nice, I considered it a personal failure as I had
made a choice that resulted in less flexibility for personnel allocation for
my organization.

The site in question was isolated from the Internet for security reasons. This
was ~1994 and I would have had to submit significant paperwork to get
permission to use one of the phone lines for a modem.

As I remember it, the site had a hodgepodge of SCO Unix, SunOS, IRIX, and
Linux systems. SCO Unix was the least equipped of them. Configuration
management had them all stuck at an old version. Perl wasn't even installed on
all of the systems. I remember feeling that AWK was a good choice because,
being interpreted, it allowed for fast development. Another obvious option
would have been C with X for the GUI, but that would have taken much longer to
implement.

~~~
i336_
> While the job security was nice, I considered it a personal failure as I had
> made a choice that resulted in less flexibility for personnel allocation for
> my organization.

Good way to put it, and point conceded (and filed away for future reference in
my own life).

> The site in question was isolated from the Internet for security reasons.
> This was ~1994 and I would have had to submit significant paperwork to get
> permission to use one of the phone lines for a modem.

I figured as much. Usually flying someone out only happens when the core
infrastructure is out (and the tiny DSL emergency modem failed _as well_ ),
when something's being so annoying/intermittent it has to be poked onsite, or
when something's airgapped.

> As I remember it, the site had a hodgepodge of SCO Unix, SunOS, IRIX, and
> Linux systems. SCO Unix was the least equipped of them. Configuration
> management had them all stuck at an old version. Perl wasn't even installed
> on all of the systems.

Ouch, wow. (I'm not sure whether to be more impressed that Linux made an
appearance at all only 3 years after entering existence, or that it was
apparently stable enough at that point to not be laughed out of the building.)

> I remember feeling that AWK was a good choice because, being interpreted, it
> allowed for fast development.

A problem that's still a toss-up for many people :) hah. I'm not even sure
what to use half the time...

> Another obvious option would have been C with X for the GUI, but that would
> have taken much longer to implement.

Ah, the joys of Xlib. I've poked it briefly but not too much, although I can
resonate with the "much longer to implement" part... heh

~~~
mcculley
> I'm not sure whether to be more impressed that Linux made an appearance at
> all only 3 years after entering existence, or that it was apparently stable
> enough at that point to not be laughed out of the building.

I was young and so was Linux. I was the only available Linux guy at that time
in that organization. The site was running some experiments for military
training simulators, so it wasn't uncommon to use technology that wasn't yet
mainstream. If I remember correctly, it was just being used to translate some
data from one system and inject it into another.

------
n0us
It's amazing what you can do in so few lines of code. If you have the time you
ought to do a tutorial on how to make this sort of game, it would be a great
read.

~~~
TheMozg
There is a great tutorial (it's actually a series of them) which I used:
[http://lodev.org/cgtutor/raycasting.html](http://lodev.org/cgtutor/raycasting.html)

It's old and C++ but explains raycasting very well.

And there is also a similar project in just 265 JS lines:
[http://www.playfuljs.com/a-first-person-engine-
in-265-lines/](http://www.playfuljs.com/a-first-person-engine-in-265-lines/)

~~~
n0us
Thanks, I'll check it out.

------
redthrowaway
Whose idea was it to have the gun reload slower if you're running away?
Deliciously evil.

Anyway, really cool project. Good work!

~~~
seivan
I think that's from the old original operation flashpoint. :-). It's a cool
design idea anyway.

------
myztic
Needs bash and gawk, bash you can avoid by changing

cmd = "bash -c 'read -n 1 input; echo $input'"

to

cmd = "saved=$(stty -g); stty raw; var=$(dd bs=1 count=1 2>/dev/null); stty
\"$saved\"; echo \"$var\""

all credit to izabera from #bash on freenode

~~~
TheMozg
Finally merged that.

------
tunesmith
This is hilarious. Is there any technical reason it couldn't have been written
twenty years ago?

~~~
TheMozg
I guess 20 years ago CS students weren't told to "write a Doom-like game" as
an awk homework =)

~~~
ethbro
Well, there were those bored days with a TI-83... _shudders at TI-BASIC_

~~~
bobwaycott
My son spends a ton of his class time programming games into his TI-83. He
even built his own Final Fantasy type game (when he really should have been
doing classwork). He built a battle system, and even a merchant/vendor for
buying upgrades. I had a lot of fun playing his game, and offered him some
ideas for improvement (which, again, were made during class time).

And yet, I can't get him to sit down and put any time into programming _on a
computer_. Sigh.

~~~
qwertyuiop924
TI-BASIC is a blessing and a curse. You can get the most non-technical people
to write code in it, but if you've had experience in a REAL language, you
can't bring yourself to.

------
quacker
Having never looked at awk aside from its usage in shell one-liners, that code
looks really nice. I might have to go learn awk for a bit.

------
mysterydip
Very cool! And easily modifiable, thanks to readable code as bliti said. Seems
well thought/laid out.

------
bliti
This is very cool. The code is very readable. I honestly expected a bit of
mess. It's easy to follow and managed to learn a bit about awk. Nice job!

------
kirang1989
I was inspired to check out AWK after reading this sentence from the book
Masterminds of Programming:

"If I had to choose a word to describe our centering forces in language
design, I’d say Kernighan emphasized ease of learning; Weiberger, soundness of
implementation; and I, utility. I think AWK has all three of these
properties."

------
thevibesman
My go-to-awk-guru-friend and I had fun playing with your game---if you
couldn't tell by the PRs ;)

~~~
TheMozg
Thanks to you and everyone for contribution. Seeing people care about this
little project reminds me why I decided to do programming for a living.

As for the PRs, apparently I've slept through all the action =) I'll get back
to them as soon as I can.

------
emmelaich
I was wondering how you'd read a key in raw mode in awk. The answer, I found
with a mix of horror and admiration is 3 forks. Two stty and one bash
(presuming read and echo are builtins)

~~~
i336_
Now it's been updated to use dd, and can run with /bin/sh.

It's sad that languages rise and fall by the feature base present in their
standard libraries.

------
arca_vorago
Awk is seriously awesome and too often forgotten or underrated.

Ill never forget the day I realized its true power was in shortness of code. I
took a one page perl script I couldnt get to work and turned it into a one
line awk script that worked.

------
baldfat
Now I have a new example to show AWK as a language. I usually get into
arguments about AWK not being a program.

------
tunnuz
Amazing!

------
Upvoter33
that is crazy awesome awk

------
latenightcoding
This is amazing.

------
Gnouc
Great work!

PS: You need gawk to run this.

------
ragnar123
Add more dragons

