Making Graphics Like it's 1993

(staniks.github.io)

111 points | by sklopec 2 hours ago

12 comments

  • rob74 45 minutes ago
    I just noticed that this might be one of the rare shooters with a female protagonist: the cat has a calico pattern, and those are almost always female (https://en.wikipedia.org/wiki/Calico_cat).
  • trashb 8 minutes ago
    This game looks great I really like the style it is inspiring.

    The author seems to consider open-sourcing the engine, I would also be interested in the mentioned scripts for asset creation. Those scripts would make a great toolset for asset creation in this style.

  • rob74 1 hour ago
    This is taking a lot of inspiration from Doom, but the actual raycasting engine is more like Doom's predecessors, the most well-known of which is probably Wolfenstein 3D: perpendicular walls, constant floor and ceiling height. Wolf3D didn't have textured floors and ceilings because of performance reasons, but several other similar games had them. Doom and IIRC Duke Nukem as well used a BSP engine which was much more flexible (walls could intersect at any angle, variable floor and ceiling heights), although the levels were still "flat" (you couldn't have several "stories" inside a level, e.g. you couldn't design a bridge that you could walk over and under).
    • badsectoracula 23 minutes ago
      > Duke Nukem as well used a BSP engine

      The Build engine didn't use BSP, it treated connections between sectors as portals and rasterized the walls as (90 degree rotated) trapezoids while performing clipping against those portals. This allowed it to have dynamic wall geometry (e.g. moving trains, rotating light fixtures, etc) as well as "room-over-room" setups as long as you couldn't see both rooms at the same time (in both Blood and Shadow Warrior they found a workaround for it allowing to create more "3D" spaces by making identically shaped sectors with the floor of one sector acting as a portal to the ceiling of the other sector - supposedly this wasn't "natively" supported by the engine, but it was flexible enough for the game studios who used it -without even having access to the source- to do it themselves).

      The first level of Duke Nukem 3D does use a few Build tricks - e.g. another one is that sprites can be "axis aligned" instead of following the camera and they can also have collision - this can be used to create rudimentary 3D geometry by treating each sprite as an axis aligned quad and in the first level it is used to make a bridge between two buildings (right before the level exit button).

    • bluedino 25 minutes ago
      > Wolf3D didn't have textured floors and ceilings because of performance reasons, but several other similar games had them

      Blake Stone Rise of the Triad used later versions of the Wolf3D engine and had textured floors/ceilings

      > Doom and IIRC Duke Nukem as well used a BSP engine which was much more flexible

      Duke Nukem (Build engine) did not use BSP

      https://www.jonof.id.au/forum/topic-137.html#msg1548

    • scrumper 1 hour ago
      I thought at first it was just a skinned Wolfenstein 3D. Which is grossly unfair. A lot of work here.
    • Grumbledour 50 minutes ago
      Later on, in Shadow Warrior, you could even do that, i think they used portals to implement it and i remeber it was a pain to set up in the editor.
  • mysterydip 1 hour ago
    As a fellow 3d-engine-with-foolishly-unreasonable-constraints developer, I love the detail in the explanations here and seeing the process you went through.
  • blackhaz 20 minutes ago
    Everything is perfect here. The hero, the graphics, the title... <3
  • badsectoracula 18 minutes ago
    As a side note, the visual style in the game reminds me a lot of Exhumed / Powerslave :-).
  • trumpdong 1 hour ago
    For some reason I irrationally like the posterization effect that's created when something is darkened to almost zero.
  • nticompass 1 hour ago
    I respect the amount of work that goes into projects like this; I can't wait to be able to play it.
  • sgt 1 hour ago
    Really cool. It's also something LLM's are ridiculously bad at, so you kinda have to do it properly.
  • zerr 15 minutes ago
    I hope they leveraged Mode X :)
  • badsectoracula 36 minutes ago
    Nice, i've used similar approach for the lighting in Post Apocalyptic Petra[0] though i did use per-pixel LUT offset calculation[1] because it uses a generic 3D triangle rasterizer (the levels are based on grids like in Tomb Raider but they're rendered as triangles). Later i added sprite support for another gamejam but i never ended up finishing it and the sprite support is very rudimentary (and unoptimized - i just noticed i'm doing the LUT lookup for every pixel when drawing shaded sprites which isn't necessary).

    I did write a tool for generating the sprites from 3D models though[2]. It uses plain old OpenGL 1.1 to draw the sprite and grabs the framebuffer directly. It is drawn fullbright so i can paint the lighting directly on the sprite's texture (using a Krita plugin i wrote[3][4] - the model is something i threw together with Blender's default generated UV since i didn't care for the details).

    I wonder if doing some sort of postprocessing (after rendering with with shading) like you do with your game would help with the finer details since i also found that rendering from 3D models to sprites creates very "mushy" results most of the time because of all the details getting lost. I notice the colors also become more saturated after postprocessing in your examples, is this after it finds the closest color in the palette or the result of the postprocess? I'd like to keep the overall hue+saturation of the model so maybe doing post-processing on a grayscale render to shade the shadows/dark areas but keep highlights as-is and then multiplying that with the fullbright image would produce results that wont shift the saturation.

    [0] https://bad-sector.itch.io/post-apocalyptic-petra

    [1] https://codeberg.org/badsector/PetraEngine/src/commit/14ca16...

    [2] http://runtimeterror.com/pages/iv/images/95ddebc51e4dfa8a5af...

    [3] http://runtimeterror.com/tools/kritaview3d/

    [4] http://runtimeterror.com/pages/iv/images/535f0e09e590d8a1731...

    • sklopec 25 minutes ago
      >I notice the colors also become more saturated after postprocessing in your examples, is this after it finds the closest color in the palette or the result of the postprocess?

      It's the result of the Blender compositor postprocessing, just keep in mind it falls apart once you go low enough in resolution (it's an image space thing after all), so I'm not sure if that helps your case.

  • xyzsparetimexyz 1 hour ago
    It'd be more interesting if you made a similar looking game using modern APIs imo
    • sklopec 18 minutes ago
      How so? Doing this with modern OpenGL would be much simpler than the software rasterizer solution.

      I think I'm gonna have to do it anyway, because some players claim they get nausea when playing at such low resolution (320x240), and the only way to give them higher resolutions that perform reasonably is to have it hardware accelerated.

      Renderer is abstracted away already, but the real difference would probably be occlusion culling... With raycasting, I get it for free, but if I'd go down the hardware accelerated path I'd have to pick something more clever.

      Raycasting and software rendering in general tends to scale poorly with resolution, even with vectorization and all the bells and whistles of modern CPUs.

      • badsectoracula 15 minutes ago
        Unless you plan on rendering the level on some very retro hardware (think S3 Virge, maybe Voodoo 1) you can render the entire level in OpenGL with just zbuffer and alpha tested sprites and it'll run perfectly fine - if anything with such low polycount, chances are you're going to make the renderer slower by trying to do occlusion culling on any GPU released in the 21st century :-P. If you pack the geometry in a few vertex buffers (for each unique texture) even per-frame, you'll get four digit FPS in any relatively modern GPU.

        As an example this[0] video shows the benchmark from Post Apocalyptic Petra running on my previous GPU (RX 5700 XT) which all it does is build a per-frame (client-side) vertex-buffer in OpenGL 1.1 (the engine was made for actual retro PCs running DOS and Win9x so it does some rudimentary occlusion culling but that mainly affects 90s hardware, not anything released since 2000 or so). If anything, the rendering has so little overhead that half of the framerate is "eaten" by the FPS counter overlay :-P.

        [0] https://www.youtube.com/watch?v=64ysz5rXkzw