Ray Casting Demo (Pxl Library 2.0)


nathanielbabiak 2020-04-26 16:12 (Edited)

The sprites across the top help orient the player. Turn on debug to see framerate. Press pause to see the rough pause menu. Tap "A" to see a sample rendering of some doors. Hold "B" to walk, turn slowly, and strafe around corners a bit more. I'm thinking this will be for aiming.

This upload uses the Pxl Library. The current version of the Pxl Library is available here: https://lowresnx.inutilis.com/topic.php?id=1501

Wolf 3D Demo.nx | Open in app
2020-05-06 03:33
Wolf 3D Demo.nx | Open in app
2020-04-28 01:28
Wolf 3D Demo.nx | Open in app
2020-04-26 16:12

was8bit 2020-04-26 16:39

Super duper wonderously wonderful !!!

GAMELEGEND 2020-04-26 16:48

This is awesome i also like that it has a moon and a star

was8bit 2020-04-26 16:52

There are actually a few things in the sky,,as well as a textured floor!!

GAMELEGEND 2020-04-26 16:54

Why is this poor practice what would be the right way to do it

GLOBAL A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , B0 , B1 , B2 , B3 , B4 , B5 , B6 , B7
GLOBAL A0M, A1M, A2M, A3M, A4M, A5M, A6M, A7M, B0M, B1M, B2M, B3M, B4M, B5M, B6M, B7M

was8bit 2020-04-26 16:56

Oh, just figured out that PAUSE toggles between walk and run :)

nathanielbabiak 2020-04-26 18:13 (Edited)

I'm glad y'all like it!

@was8bit - the sky was originally going to have cardinal directions (N/S/E/W) shown, but I figured the text would be pretty arbitrary, so there's a "north star" instead of N, and a moon too. The next version will have those sprites rotate at the same scale as the wall panels. (And the jumping issue with strafing will be fixed too - I just noticed it.)

@GAMELEGEND - the most maintainable code is written in small, modular sections that limit what's effected. (It helps other programmers to understand a whole project when it's presented that way, and it limits the damage any individual can do if they modify it poorly.) In this language, we've only got SUB to work with. If those same variables were declared and initialized inside MAIN (and therefore local), rather than declared and initialized with GLOBAL, each of them would need passed as an argument to WOLF_DRAW, and each variable passed costs a clock cycle.

nathanielbabiak 2020-04-26 18:19 (Edited)

Oh! One more thing I forgot to mention... I decided not to set up buttons A/B to strafe, so that those buttons could be reserved for other things. But, when you change direction, strafing occurs automatically (just a little). I found that really helped orient me in the 3D environment.

@was8bit - the texture on the floor is a dither. You can see the available dithers in the Char Designer. I set up the dithers so my wife could easily pick the colors of the panels, panel moulding, and floor. I'm no good at color matching, and LowRes NX is pretty limited too.

Timo 2020-04-26 18:41

Very impressive, I'm surprised by the performance!

nathanielbabiak 2020-04-26 18:55

Thank you! (When was8bit shared your original code, I noticed it seemed like the original LowRes didn't have a significant performance cost for pixel-level graphics.) I used what I learned making Pxl Library to optimize this a lot. Each byte is only written once per screen update, and the bytes are written in eight-row-blocks where possible. It's in the WOLF_DRAW subprogram. (Not to mention completely taking advantage of the 1 clock cycle cost of floating point operations.)

desbyc 2020-04-26 20:33


G-9 2020-04-27 08:29

If there is an exit ?? :)

G-9 2020-04-27 08:31


If you can do like ^^^^ this ...

nathanielbabiak 2020-04-27 14:36

That's definitely the plan! Unfortunately, LowRes NX is too slow to allow textured wall panels (or even walls with more than 3 colors total). I have some ideas though for decorating the panels though, they're commented in the source below WOLF_SHADER (to be implemented in the next version).

Jonnywhateva 2020-04-27 21:31

Wow this is fantastic! Definitely going to look through your code and see how this one ticks! Well done! :)

nathanielbabiak 2020-04-28 01:29 (Edited)

I fixed the cardinal directions - now they project onto the inside of a skybox. I have a few more improvements planned, but had to work too much today.

Also, you can strafe with A/B now, but not permanently, it's just to help me debug the jumping issue. (I know what's causing it, just haven't worked out the math to fix it yet, since I want to fix some other stuff on the subject of movement at the same time.)

Jack Sbertox 2020-04-28 14:44

Itโ€™s possible to make a sort of doom with this?

nathanielbabiak 2020-04-28 19:39

The system is too slow for Doom, but will work OK for 1992's Wolfenstein 3D. There won't be textures on the walls though, just simple geometric shapes and patterns. I have a motif developed so the player associates switches with doors though, so besides being much more abstract, I think it'll work out OK.

What's funny is, the wall patterns will have to be super simple compared to Wolfenstein 3D, but the enemies will be just as detailed.

GAMELEGEND 2020-04-28 20:02

Are the blue dots going to be replaced with a floor?

nathanielbabiak 2020-04-28 20:13 (Edited)

Unfortunately the floor can't be textured either. The floor can be a dither (the available dithers are in the Char Designer). If the floor had a complex pattern or a texture to it, then it would need projected from 3D to 2D. The system's too slow for that.

Also, I've optimized a few more things (haven't uploaded yet) to make it even faster. *BUT*, it's going to slow down substantially when the display gets buffered. (I need to buffer the display so that there's enough cells available for enemies and objects.)

PranXter 2020-05-05 18:39

Almost as good as mine. Just kidding lol. Iโ€™ve figured out the math, just not how to present it.

nathanielbabiak 2020-05-06 03:42

Just some quick comments on my latest update - it's now one to two frames-per-screen-update faster than before, and there's also an 'interleave' setting to speed things up by 50 pct after that. The BG Designer is used to read off the level data, and besides doors, switches, buttons, and sound, all expected feature expansions are commented with "(NOT YET)..." so I can keep track of everything.

Barring crazy work hours, this should take another few weeks to wrap up, then it's on to game mechanics!

GAMELEGEND 2020-05-06 03:44

The 3d graphics are better now but why do the walls break up when you turn

nathanielbabiak 2020-05-06 03:47 (Edited)

That's the interleave. Since the display is made of individual cells, the interleave will only cast rays onto every-other-column of cells in a single screen-update. You can turn it off by searching for WOLF_INTERLEAVE and setting the value to 0 (not 1), but it will then update the whole screen at once rather than just half, so it's much slower.

It's going to slow down significantly when the buffer is added, but that's required so that it can have enemies and objects 3D-projected into the environment. It needs to be as fast as possible otherwise.

I also tried not refreshing the sky or panel pixels to save clock cycles, but it turns out that's not really significant. The slowest calcs are in the ray casting algorithm itself.

GAMELEGEND 2020-05-06 03:49 (Edited)

I see now
good job on the graphics

nathanielbabiak 2020-05-06 03:53

Thank you!

Mrlegoboy 2020-05-31 21:59

wow this really works!

LRCFresh 2020-08-01 18:23

somebody knows their calculus ๐Ÿ‘€

Ultranautix 2020-09-04 08:39

Great work! I do wanna know how you made the texture for the walls, i want to customize them.

nathanielbabiak 2020-11-18 04:00 (Edited)

I promised in another thread that I'd upload the latest version this weekend, but I couldn't wait! I'm super excited to share this with all of you! (And proud of the accomplishment too.)


The new version draws a single frame in 30,000 CC (vs. 130,000 CC in the old version). And, the old version used a direct display, whereas this one uses the Pxl Library buffer (costing 6,000 CC). I could actually get this up to 45 FPS (24,000 CC) without a buffer using the Pxl Library direct display, but that wastes so many characters that could be used for sprites. And besides, 1992's Wolfenstein 3D ran at 35 FPS, so I think it's finally "good enough". ;-)

This version uses two distinct interleaves at the same time, so it needs to calculate a quarter of the screen real estate for a single frame. (Much improved from the old version - that was terrible!)

...more to come y'all...


nathanielbabiak 2020-11-18 04:22 (Edited)

Oh, Ultranautix, I haven't forgotten about your comment either...

There's 15 possible box characters - use the Gfx Designer tool to edit Rom #6 to add your own. (And read the notes in the source code at the top of the ROMs first!) (Note that box type 0 is possible, but will never be selected without significant modifications to other code.)

After you add your own boxes in the "level editor" (Gfx Designer tool), you can write what happens in SUB CALC_COLUMN. (I should probably rename that to CALC_RC_COL, but whatever.) I saved box types 2 through 14 for future updates, so there's plenty to pick from. When you start writing what happens, you can use box type 1 as a go-by.

...Basically, you need to set the four "RETURN_" variables within CALC_COLUMN...

Do a CTRL+F for MNPEN to get an explanation for how the PY1 and PY2 return variables work. You'll have to divide your line height by RC_RAYM to "project" into 3D. You can tell how far the line is (located horizontally) from the edge of the box with RC_WALL, which ranges from 0 to 100%.

For the pixel color return variables PC1 and PC2, the box type 1 go-by will show you how to "add" color 1, 2, or 3, or "subtract" color 1 or 2 (from color 3). Whenever you add or subtract color, always make sure the lookup array is indexing RC_COL (since that means you're looking-up the current pixel column).

You can also use RC_BOXP, which contains the cell attribute data from the "level editor".

And I'll say it again - all of these concepts are used within CALC_COLUMN in the go-by, so get familiar with that first and just start changing things!

GAMELEGEND 2020-11-18 04:33 (Edited)

nice job on the update

nathanielbabiak 2020-11-18 04:36 (Edited)

Thanks! I feel like the 3D engine is maybe 70% done at this point. I'll have another upload (eventually) where it'll be mostly polished off. Then it's on to sound!

was8bit 2020-11-18 04:44

I was running thru your maze, and got an error mesage....

Error Message.nx | Open in app
2020-11-18 04:44

nathanielbabiak 2020-11-18 04:45

Yeah - this lacks proper clipping. If you hold "B" to walk, it'll (mostly) clip properly, but at the running speed you'll run completely off the map!

was8bit 2020-11-18 04:47

Oh, i was TOTALLY warping thru the thing ;)

nathanielbabiak 2020-11-18 04:53

To avoid clipping, you can make another map in the Gfx Designer tool - up to 64x64. Check out ROM #6

Alice 2020-11-18 08:01

Very cool...considering what was being built on similar systems years ago...this is definitely worth developing. Not sure if there is enough coding room to build a flexible engine but it would make a great base for all sorts of games.

Good job!

nathanielbabiak 2020-11-21 22:37

Todays update fixes clipping, and has tightened up much of the rendering code. It also provides a proof-of-concept door. This actually runs so fast I'm going to try textured walls next. More to come...

nathanielbabiak 2020-11-23 00:07 (Edited)

Today's update reaches the natural stopping point of the demo. The rendering code is done, and there's now two proof-of-concept doors (one recessed and one sliding). They're combinable, and would move by a "percentage-of-open" in an actual game. There's also another proof-of-concept wall graphic (triangle).

I'm excited to try a textured wall, but it'll require a complete rewrite of the graphical portion, so it'll take some time. It's next on the list though!

was8bit 2020-11-23 05:06

Cool stuff!!! :)

... im working too much to wrap my brain around it right now, but i will hopefully soon :)

Ultranautix 2020-12-22 07:52

Ah! The explanation to custom walls is pretty hard to understand since i am on an iPad and i donโ€™t understand coding in VISUAL BASIC, but iโ€™ll see what i can do!

nathanielbabiak 2021-04-13 04:14 (Edited)

I was able to squeeze just a few clock cycles more from the rendering - it's enough that the panels can be a bit prettier! I also updated the doors - press "A" to open/close the four example doors (it's only graphical, the map data doesn't update, you can't walk through them).

It's around 30% slower in the hallway of triangles now, but I think the extra graphics are worth the cost. I wouldn't plan on using too many "special" panels like that anyway.

Log in to reply.