I'm considering tweaking my raycasting engine to make a few improvements and one of the ideas I had was to increase the horizontal texture resolution while maintaining the number of rays that are cast. I plan to do this by rendering 2 texture columns for each ray that's cast, testing the position where the ray hits the wall with a precision of 8 units per block, and using that information to draw 2 consecutive slices of a 16-column texture.
This is simple for distant walls, but there's this awkward point when textures are scaled between 100% and 200% their actual width, where some screen columns should represent 1 texture column and others should represent 2, and I'm having a hard time figuring out How to make that decision.
The simplest thing I can think of is to render 2 texture columns when a 1/8 strip of the block is hit only once, but use the actual 1/16 strip if the same 1/8 strip is hit twice or more times. The main problem is that this doesn't work well when block faces are obstructed, either by the sides of the screen or by other blocks, because a partially visible wide strip can be mistaken for a narrow strip. The other problem is that detecting whether columns are repeats or not requires some looking ahead, which conflicts a bit with the rendering pipeline I have currently set up.
I don't know if I explained the problem clearly, or if anyone here has any interest in thinking of possible solutions, but if you do, please share your thoughts. Thanks.
Stupid question. Can you use flat planes with well defined edges? Scaling would be less of an issue, in that scenario. (Like Star Fox).
That wouldn't help much I think. Even if I used another technique to find the exact edges of the walls, I doubt the NES would be able to do perspective-correct texture mapping on them as fast as my engine does now. The raycasting method is much simpler IMO, but we can only see what the rays hit. Unless we start shooting extra rays through walls or past the end of the FOV, but that could seriously affect the performance.
What I'm looking for is a cheap trick, like almost everything else in this engine is. Walls scaled to 100% or less use 2 conseccutive 1/16 strips from the texture, walls scaled to 200% or more use the exact 1/16 strip that was hit, and I need to find a good enough rule for what's in between.
I think I figured this out: since I want to draw 2 texture columns per ray, I should consider that the exact spot the ray hits is between the points I have to sample, which are a little to the left and a little to the right. "A little" is just a small percentage of the distance... probably
tan(1/2) * distance, which I can build a look-up table for.
This formula is only correct for perfectly perpendicular rays, but I don't think there'll be any noticeable distortion if it's used for rays hitting at steeper angles.
Anyway, this could (and probably should, for consistency) even be used in all cases, not just for walls scaled between 100% and 200%. Being able to use the same logic all the time is almost always better than handling special cases, IMO.
EDIT: I think the formula is wrong, I shouldn't be looking half a degree away from the center, it should be less. I'll figure out the exact value...
Just to let you know, my idea worked fine. The added horizontal resolution greatly improved texture fidelity, without needing extra rays:
Attachment:
01-before.png [ 4.11 KiB | Viewed 4173 times ]
Attachment:
02-after.png [ 4.49 KiB | Viewed 4173 times ]
My 3-year-old daughter said it looks just like Minecraft... guess I'll take that as a compliment!
Anyway, I've also been playing with jumping/ducking and looking up/down:
Attachment:
03-ducking-and-looking-up.png [ 4.6 KiB | Viewed 4173 times ]
The textures are getting a little too jagged for my taste, and since I can't think of many uses for this I might just give up on these features.
BTW, these shots are not from an NES program, but from a JavaScript prototype that uses an optimized version of the logic from my first raycaster. If all goes well with the prototype, I plan on making an updated NES version.
Can fudge either or both with some y-scroll, if you don't mind compromise.
Looks nice. What's the texture on the far right panel, though? It seems compromised near the corner.
Myask wrote:
Can fudge either or both with some y-scroll, if you don't mind compromise.
Scrolling could indeed help with looking up and down, but then there's the status bar in the way, and the edges to clip, so it's just easier to render the view with the center displaced up or down. What causes distortion is jumping/crouching, because the individual columns are shifted according to their distances (closer columns shift more than distant ones), causing some alignment issues with the texture mapping. I have no idea how to shift the columns and keep the textures aligned.
Quote:
Looks nice.
No it doesn't, it looks atrocious when scaled up!
But it's the best I can come up under the current constraints (no raster effects and no pattern updates). The lack of raster effects is because I originally didn't want to use a mapper with IRQs, and the motivation to use a fixed tileset is speed, since changing the pattern tables is a very slow process that would greatly impact the gameplay. I really don't want to sacrifice the performance or shrink the 3D view too much. I'm now considering using MMC3 IRQs to increase the color count and the vertical resolution though, in order to have multi-colored textures (all built from a base set of 4 colors through dithering, of course) and better depth representation.
Quote:
What's the texture on the far right panel, though? It seems compromised near the corner.
Yeah, the rays hit at a pretty steep angle there, and my hack for increasing the horizontal texture resolution doesn't work so well at steep angles (it's table-based and calibrated for walls being observed straight on). It's supposed to be the same crate texture from the other face.
Just in case anyone is interested, here's a GIF showing some of the new stuff my raycasting engine supports:
Attachment:
raycaster-optimized.gif [ 950.12 KiB | Viewed 3845 times ]
We now have tiled floors, and most importantly, objects! Well, for now it's just a blue rectangle, but it's there to demonstrate that objects are placed, scaled and clipped correctly.
This capture is still from my JavaScript prototype, but this stuff is already being ported to the NES. Now that objects are working, I'm confident I can make a cool NES game out of this. Let me know if anyone is interested!
Looks good. How many frames per second are you expecting?
I'm shooting for 15 frames per second. 3 hardware frames spent on the background, 1 frame for game logic and drawing objects. It'll probably drop to 12 at times, but that should still be playable.
EDIT:
My old demo does 15fps most of the time, but doesn't have many of the features of the new engine (tiled floors, objects, looking up/down, stacked blocks). I did optimize a lot of things compared to the old demo, such as:
- Turning the binary search that calculated wall heights into a simple table look-up;
- Replacing the real-time bresenham texture scaling with something much simpler (can't describe it in 1 line, though);
- Using a different technique for detecting which texture column was hit, saving me 1 multiplication per wall slice;
These should significantly improve the performance compared to the old demo, but the new additions will probably cancel out the performance boost, which is why I expect it to run at a similar speed.
Wow, and head tilt even. Looking very good.
Thanks. The head tilting is very simple really, it's done by simply moving the entire picture up/down. But I still think it makes the place look more 3D than if you could only look straight ahead. Not sure how I'll implement this action with the limited button count of an NES controller, though... I'm sure I'll have to rely on button combinations for extended actions such as looking up/down, changing weapons, strafing, and so on. I also can't think of many uses for this during actual gameplay, but I'll try to come up with something.
My main concern right now is rendering objects. They can't be drawn with background tiles because of the severe color limitations necessary to make everything fit in 256 tiles, so I always planned to draw objects with sprites. The problem is that the sprite capabilities of the NES aren't the best, and getting too close to objects will create problems. I'll have to prevent/discourage this kind of proximity (large bounding boxes?), but also design a sprite cycling method that deals gracefully with large objects for when they do happen.
tokumaru wrote:
Now that objects are working, I'm confident I can make a cool NES game out of this. Let me know if anyone is interested!
Sure. An actual raycasting game is still something that's completely missing on the NES.
What kind of game are you planning?
DRW wrote:
An actual raycasting game is still something that's completely missing on the NES.
Agreed.
Quote:
What kind of game are you planning?
The gameplay itself will be the typical "shoot the bad guys", "figure out how to progress", "get to the exit" type of thing for the most part, but instead of making the entire game have a single theme, I plan on paying homage to different first person shooters of the 90's by having various worlds based on different themes. Another thing I consider important is that game doesn't take itself too seriously, so even the blockiness of the graphics (and possibly other constraints) will be acknowledged in-game and justified by the story.
Looks very good indeed!
Besides an FPS, I imagine it could make a cool dungeon crawler. In games like Megami Tensei it's very easy to get lost due to choppy 3D-mazes and limited access to a map, but with a fully animated 3D-maze like this it would be easier to navigate. Head tilting could be used automatically in scenes like when you discover stairs or so rather than during gameplay.
Wow, I do not like FPS as games but I have to say it looks AMAZING ! Much better than the older version !
Wow, really. I can't wait to see this stuff running in actual NES code. It's above and beyond anything I imagined possible on this system. Kudos, tokumaru.
Bregalad wrote:
Wow, I do not like FPS as games but I have to say it looks AMAZING ! Much better than the older version !
Haha I honestly wasn't expecting a positive reaction from you of all people, considering your opinions about past raycasters, and specially the fact that the vertical resolution in this new version had to be reduced in order to fit everything I wanted in under 256 tiles! I did increase the overall viewport size to compensate for this though, and this compromise also allowed me to increase the horizontal texture resolution, so in the end it was probably a good trade off.
I guess this just goes to show that a little polish goes a long way in making something technologically limited look more appealing. And this is still using boring test textures, colors, and has no discernible objects, so I expect the final result, that'll have a much more cohesive design, to look particularly more engaging!
Thanks for the overall positive feedback, guys! I'm glad to know I'm not crazy for trying to code something so absurd for the NES, and that even though there are compromises that have to be made, you still think this is worth making.
I'll be porting this to the NES during the next few days and I'll let you know how it goes. There shouldn't be any problems, seeing as the JavaScript logic is pretty much the same that'll go into the ROM, all the data tables (and there are *many* look-up tables!) are the same and such, I just have to make the multiplications as fast as possible and implement a pipeline for buffering the VRAM updates.
Pokun wrote:
Besides an FPS, I imagine it could make a cool dungeon crawler.
That's a good idea, but since that's a type of game I never had much contact with, I wouldn't be able to design a game of this kind myself. I'd probably have to work with someone else to accomplish something off this nature.
Even with some experience, I'd say making a solid FPS game is at least as difficult, if in fact not much more difficult. You have to design something that works well with the technical limitations that you have, and without the low framerate being an annoyance. Wolfenstein 3D is "more advanced" than this, and is still so limited gameplay-wise, that it becomes repetitive extremely fast. Doom, on the other hand, is IMO a masterpiece - but I wouldn't want to play it as an NES raycaster.
I don't think a dungeon crawler RPG is necessarily the best way to go, although it would be an obvious choice - something inbetween that's still somewhat slow and tactical would also be a pretty good idea. When working with limitations such as these, it's important to design something that makes proper use of the unique 3D perspective for gameplay purposes (something Doom actually does better than most newer FPS games), rather than simply working in spite of it.
And I was happy that I got my 2d shadow casting thing working.
This thing is in a whole another dimension!
This has to be the most technically advanced thing on the NES so far no?
Really impressive work! I hope you manage to complete your project
Sumez wrote:
You have to design something that works well with the technical limitations that you have, and without the low framerate being an annoyance.
Wolfenstein 3D on the SNES almost fails due to the low framerate. I'm kinda considering that my threshold.
Quote:
Wolfenstein 3D is "more advanced" than this
It certainly looks better due to the higher resolution, color count, and framerate, but it lacks floor tiling and head tilting, both elements that could be used to improve the gameplay. Floor tiling can be used to represent dangers such as acid/lava rivers and bridges you might have to activate in order to reach the other side, for example. Bottomless pits are also possible.
Quote:
and is still so limited gameplay-wise, that it becomes repetitive extremely fast. Doom, on the other hand, is IMO a masterpiece - but I wouldn't want to play it as an NES raycaster.
Sure, the challenge of making something engaging under all these constraints is definitely present, but I'm confident I can come up with something fun.
rikami wrote:
This has to be the most technically advanced thing on the NES so far no?
The funny thing is that this uses the NES hardware in a very standard way, there's no crazy bankswitching, raster effects, forced blanking, none of that. The trick is all in making the math fit, and since I've never been particularly good with math, I'm taking this as a compliment!
tokumaru wrote:
but instead of making the entire game have a single theme, I plan on paying homage to different first person shooters of the 90's by having various worlds based on different themes. Another thing I consider important is that game doesn't take itself too seriously, so even the blockiness of the graphics (and possibly other constraints) will be acknowledged in-game and justified by the story.
Well, it is your game and your decision, but if you ask me, I would advise against this.
I would prefer a straight, serious first person shooter, not some self-aware tongue-in-cheek half parody/half hommage game.
To me, it's much more retro if you design a shooter that looks like if someone actually made this on the NES at a time when "Wolfenstein 3D" was popular, as if this was actually created in the final days of the NES. A game that can stand for itself, so that you can say:
Now the NES has its very own FPS, not just in a cheap ersatz way like "Operation Wolf", but a
real FPS.
But a game that specifically references famous existing games as an hommage and makes fun of itself regarding the technical limitations? Meh. Not really the theme that I would prefer for this genre.
DRW wrote:
Well, it is your game and your decision, but if you ask me, I would advise against this.
Too bad you didn't like the idea, but I have my reasons to follow this route.
Quote:
To me, it's much more retro if you design a shooter that looks like if someone actually made this on the NES at a time when "Wolfenstein 3D" was popular, as if this was actually created in the final days of the NES.
But then it's just more of the same, and with a severe technical disadvantage compared to the competition. I'd rather acknowledge what the game is, which's a piece of software made in 2017 for a badly outdated machine paying homage to a type of game that doesn't really exist anymore.
Quote:
A game that can stand for itself, so that you can say:
Now the NES has its very own FPS, not just in a cheap ersatz way like "Operation Wolf", but a real FPS.
It will still be that, hopefully, regardless of the excuse presented in the manual and/or cutscenes to justify the shooting of bad guys in maze-like pseudo-3D levels.
Quote:
But a game that specifically references famous existing games as an hommage and makes fun of itself regarding the technical limitations? Meh. Not really the theme that I would prefer for this genre.
Nothing will be directly referenced or stolen from existing games, just the level themes will be loosely based on typical tropes of old FPS games. Much like platformers often have ice levels, lava levels, sky levels, underground levels, and so on, I'll have city levels, space levels, hell levels, prison levels, cemetery levels, and such. 60+ levels of prison breaking can get old fast, so this is a way to break the monotony and make the most out of what the engine has to offer, because I can play with the different color modes I have set up for walls, floors and ceilings.
As for acknowledging the technical limitations, I felt like it was important to address the fact that this is targeting a much more limited platform than the games that inspired it did, and make it clear that this is not trying to be the ultimate first person shooter, but just a fun take on the genre.
tokumaru wrote:
But then it's just more of the same
Well, the defining characteristic would be that it's for the NES.
It's the same with a fighting game: If the NES ever has a fighting game, I would prefer a game with martial artists and a fighting tournament, not a game with aliens and robots and some outlandish story.
tokumaru wrote:
Nothing will be directly referenced or stolen from existing games, just the level themes will be loosely based on typical tropes of old FPS games. Much like platformers often have ice levels, lava levels, sky levels, underground levels, and so on, I'll have city levels, space levels, hell levels, prison levels, cemetery levels, and such.
O.k., that's something different then. The way you originally said it, it sounded more like you want to do a "Wolfenstein 3D" level where you fight nazis, then some moon space station level referencing "Doom" etc.
Or, to compare it to platformers: As if you wanted a "Mario" level, a "Castlevania" level, a "Mega Man" level etc.
But yeah, different
general level themes are totally cool. As long as the story is somewhat consistent.
tokumaru wrote:
that this is not trying to be the ultimate first person shooter, but just a fun take on the genre.
Well, until another, better one comes around, it would be the ultimate
NES FPS.
I've long admired your raycasting demo. Excited to see something coming of it!
I love it, seeing texture on the ground and the head tilting is really awesome. I thought it was already as good as it gets, but no.
Do you remember a long time ago when I asked about using your raycasting engine in Garage Cart #2 for something fun? I'd still like to do that, I could really use some inspiration to get that long-languished project moving again.
Hey, I don't have much to add for commentary, but this is cool. Have occasionally been peeking at your old raycasting demos for a long time.
Memblers wrote:
I love it, seeing texture on the ground and the head tilting is really awesome. I thought it was already as good as it gets, but no.
Haha! Thanks!
Quote:
Do you remember a long time ago when I asked about using your raycasting engine in Garage Cart #2 for something fun?
Of course I remember! We had some interesting ideas.
Quote:
I'd still like to do that, I could really use some inspiration to get that long-languished project moving again.
I'm up for it, but the new version of the engine uses way more look-up tables than before, so I can't guarantee it will fit in just 16KB anymore, it might need 32KB. On the plus side, using objects we can set up rooms with better ambiance.
If Garage Cart 2 uses something like the Action 53 mapper, 32K shouldn't be a problem.
I just wouldn't want it to steal space from other things featured in the cartridge.
Sumez wrote:
I don't think a dungeon crawler RPG is necessarily the best way to go, although it would be an obvious choice - something inbetween that's still somewhat slow and tactical would also be a pretty good idea. When working with limitations such as these, it's important to design something that makes proper use of the unique 3D perspective for gameplay purposes (something Doom actually does better than most newer FPS games), rather than simply working in spite of it.
Like Bergalad I'm not a huge fan of FPS but I am a fan of RPGs so a dungeon crawler is the first I'd think about to make, so I had to mention it.
Yeah a dungeon crawler might not really do the engine justice (unless you allow free roaming maybe), but I think it could improve dungeon crawlers as it at least makes smooth animations easy. Choppily animated dungeon crawlers (or no animation at all like in Portopia and Megami Tensei) makes it easy to loose your orientation.
Pokun wrote:
Looks very good indeed!
Besides an FPS, I imagine it could make a cool dungeon crawler. In games like Megami Tensei it's very easy to get lost due to choppy 3D-mazes and limited access to a map, but with a fully animated 3D-maze like this it would be easier to navigate. Head tilting could be used automatically in scenes like when you discover stairs or so rather than during gameplay.
I was going to suggest this, myself, only because the recently released "Tales of Popolon" is damn impressive, for the MSX!
https://www.youtube.com/watch?v=u9HiZfxoLmkThis game also used smaller characters, eliminating the object-size problems.
But I like Tokumaru's idea more! I'd rather "teach those alien bastards a lesson" than just generically shooting Nazis in the face.
Locomalito's "8-bit killer" took a more Contra-like approach to a Wolfenstein-styled shooter.
https://www.locomalito.com/8bit_killer.php
tokumaru wrote:
I just wouldn't want it to steal space from other things featured in the cartridge.
Oh, that's definitely not a problem. Looking at it now, it has at least one fully empty 32kB bank, and several more that are mostly empty. It went from being 128kB, to 256kB, to a 512kB project and it shows.
GC#2 will still be a product of it's time (10 years ago), so it will mostly be stuff from back then, and it will be on plain old 32kB banking on the GTROM board.
How many rays are you casting? 32?
How much time is the render taking compared to the raycasting?
The new design isn't running on the NES yet (I'm getting to it!), so I don't have that information yet.
The old raycaster used 28 rays, and rendering the walls was slightly slower than casting rays, IIRC, so the frame rate would drop a bit when you were facing a wall up-close. Thankfully, when actually playing a first person shooter you don't spend much time facing walls, so that shouldn't be a problem.
For the new design I added 2 more columns, for a total of 30 rays, and that's indeed the resolution for wall slices, but each slice contains 2 columns of texture, improving the perceived horizontal resolution.
I did a lot to improve the ray casting compared to the old design, but not so much the rendering. If anything, rendering is probably slower, since now I have floors, ceilings, and 2 textures per slice. I'll probably unroll some of the texturing code, though.