Building a Wolf 3D-Style Engine in PlayBASIC with Affine-Textured Polygons

March 31, 2025

 

Building a Wolf 3D-Style Engine in PlayBASIC with Affine-Textured Polygons

The idea behind this project was simple: Could I recreate a Wolfenstein 3D-style engine in PlayBASIC while maintaining good perspective but using affine texture-mapped polygons instead of traditional raycasting?

Floors and Ceilings: Subdivision for Perspective

Classic Wolfenstein 3D engines rely on raycasting, but I wanted to explore using polygons. This introduced two key challenges: rendering walls and handling floors/ceilings. I tackled floors first by subdividing floor tiles near the camera, ensuring that closer surfaces were represented with a denser set of polygons. This approach worked well, maintaining an accurate perspective without excessive computational overhead.

Walls: Adaptive Subdivision

I applied the same technique to walls, subdividing them based on their distance from the camera. Surfaces closer to the viewer were represented with more polygons, while those farther away used fewer. This adaptive approach preserved scene perspective while optimizing performance.

Ensuring Proper Polygon Order

A major challenge with polygon-based rendering is ensuring proper drawing order. Since walls, floors, and ceilings are drawn as independent polygons, z-fighting (incorrect layering of polygons) can be an issue. To address this, I implemented a two-pass rendering system:

  1. 1. First, floors and ceilings are drawn.
  2. 2. Then, walls are rendered on top.

This method prevents z-popping artifacts commonly seen in painters’ algorithms and produces a visually appealing scene.


Enhancing the Classic Wolf 3D Look: Adding Light Mapping

To push beyond the classic Wolfenstein 3D aesthetic, I added a light mapping pass. Implementing this in PlayBASIC required rendering the scene twice—essentially brute force—but the cost was only around a 20% performance hit. The visual improvement, however, was well worth it.

The process involved:

  1. 1. Drawing the texture-mapped scene.
  2. 2. Overlaying a Gouraud-shaded version of each triangle, where each pixel’s color was alpha-blended with the background.

This resulted in a real-time light-mapped scene with a Doom-like atmosphere, enhancing immersion and depth.


Pushing Further: 3D Polygonal Characters Instead of Sprites

A long-standing idea I wanted to explore was replacing traditional 2D sprites with 3D polygon-based characters. This concept originated from my work on a rendering engine called "Reality" for Amiga computers back in 1995, which aimed to integrate both sprites and 3D objects within a scene.

Implementing 3D Objects

To bring this concept into PlayBASIC’s Wolf 3D engine, I needed a way to load and render 3D models. I chose the DirectX ASCII format due to its simplicity. The loader extracted three key components:

  • Vertex data (point locations)
  • UV data (texture mapping coordinates)
  • Face data (which vertices form polygons)
  • Fortunately, I had already written a PlayBASIC loader for this format years ago. With minor modifications, I incorporated it into the project and built a simple object library for dynamic 3D models within the scene.

    Sorting and Rendering 3D Objects

    Rendering 3D models in a PlayBASIC-based engine required an efficient way to order polygons. Rather than manually sorting faces, I leveraged PlayBASIC’s built-in 2D camera system. Each face was assigned an average depth value (Z-depth), and the engine used the camera’s sorting system to manage rendering order. This approach avoided the need for a costly manual sort, maintaining decent perspective despite the lack of true z-buffering.

    The final result was impressive: a Wolfenstein 3D-inspired environment with fully textured, light-mapped walls and floors—now featuring real 3D characters and objects.


    Future Optimizations: Reducing Overdraw with a Portal System

    One of the biggest challenges in 3D rendering is overdraw—when objects outside the visible scene are still processed and rendered. While the engine is fast enough to handle this, unnecessary rendering wastes performance.

    To optimize, I am experimenting with a portal-based rendering system. This system:

  • Connects open areas (portals) within the game world.
  • Checks which portals are visible from the camera’s current position.
  • Recursively determines visibility, ensuring only necessary polygons are processed.
  • This technique should significantly improve rendering efficiency without sacrificing visual fidelity. However, that’s a topic for a future update!


    Get the PlayBASIC Source Code

    You can download the full PlayBASIC source code for this project from our forums. Stay tuned for more updates as I refine the engine and explore new rendering techniques!

  • Yet Another Wolfenstein 3D Demo (Texture Mapped Floors & Ceiling)



  • Reality: The Lost Amiga 3D Engine

    March 30, 2025

     

    Reality: The Lost Amiga 3D Engine

    What Is Reality?

    Reality was the name of our Wolfenstein 3D-style game engine, which became an umbrella term for anything related to that pursuit. The project aimed to create a fast and efficient first-person engine on a near-stock Amiga 1200 (020+FastRAM) in the mid-1990s. This archive contains the last known remaining compiled executables from my various attempts to achieve reasonable performance on the platform.

    Originally, the Reality project was most active between 1994 and 1995. Apart from a few screenshots shared with close friends, it was never publicly released. The executables included here represent alpha-stage software—functional but far from stable. While they take over the system in as OS-friendly a manner as I knew at the time, modern systems may not handle them well.



    About the Demos

    Reality.exe - Ray Casting Experiment

    This was the initial test of the engine, developed sometime in late 1993 or early 1994. The first major challenge was the chunky-to-planar (C2P) problem, where my initial attempts using unrolled bit sets failed spectacularly. While this approach might have worked for particle effects, it was a disaster for general-purpose rendering. However, after several iterations, I moved on to a bit-parallel rotation solution, which significantly improved performance.

    This is the only version of Reality that employs a true ray-casting method. The scene is constructed by casting rays outward from the camera’s field of view, step by step, checking for wall collisions. Each map pixel represents a vertical wall strip, likely stored as 8-bit data, allowing for 256 unique wall textures.

    Color depth was either 16 or 64 colors, which struck a balance between visual quality and conversion speed. This version laid the foundation for later advancements.


    Map.exe - 64-Color 2D Polygon Walls

    As development progressed, I re-evaluated the engine’s structure and opted for a different approach. Instead of a traditional grid-based map, I structured levels as a grid of evenly spaced vertices, where walls were formed by linking vertex pairs. This allowed for non-orthogonal walls and greater flexibility in map design.

    Rendering involved rotating and projecting the sector vertices, which determined floor and ceiling heights. The scene was then processed polygon-by-polygon. For each wall, I interpolated across its top and bottom, computing its Z-depth and texture U-values. Instead of rendering strips immediately, the engine stored them in a Z-buffer, ensuring proper visibility sorting.

    A unique optimization was that textures were stored rotated in memory, enabling rapid texel fetching using a simple 8-bit V-offset.


    Project Reality - 256-Color Rendering & 3D Objects

    By early 1994, the gaming world was in the grip of DOOM fever, and we ambitiously aimed to push Reality further. As Commodore's decline loomed, we set our sights on creating something akin to Blake Stone, but with even more complex environments and polygonal objects.

    This demo showcases the most advanced features we implemented:

  • 256-color rendering
  • Textured walls with transparency support
  • Depth-based lighting effects
  • Early support for floors & ceilings
  • Multiple rendering modes
  • Initial 3D polygon rendering
  • For polygonal objects, we experimented with a method where triangles were clipped against the depth buffer. The goal was to calculate the screen-space width of an object, scan across the depth buffer, and determine the visible clipping edges. This technique would have allowed objects to be properly occluded by walls while enabling partial visibility. While not perfect, it was an innovative approach at the time.

    Unfortunately, time and talent ran out. By the time we reached this stage, the Amiga community had already embraced Fears, Gloom, Breathless, and Alien Breed 3D. The dream of completing Reality faded, but looking back, I still wish I had been able to bring my full vision to life on screen.


    System Requirements

  • System: Amiga 1200 / Amiga 4000
  • Processor: 68020 or higher
  • Video: AGA chipset
  • RAM: 2MB + 2MB FastRAM
  • Sound: Not required

  • Final Thoughts

    Reality remains a fascinating relic of my early game development journey. While it never reached a finished state, it reflects the passion and creativity that fueled many indie Amiga developers during the 1990s. This archive preserves those efforts—flawed but ambitious, a glimpse into what could have been.

    Links:

  • Download Reality 3D Tech Demos(Amiga)

  • Amiga Demos

    October 10, 2011

     

    Metal Combat - Planar 3D Engine Tech Demo For Amiga A1200

    This short video is taken of a tech demo I wrote for the Amiga 1200 way back in 1995/1996. The demo is showing a planar based filled polygon rendering engine designed for A1200/020 systems with fast memory. The idea was to render the spans with the CPU and interleave this with the blitter, which turned out to be fairly good solution at the time.

    While this demo was originally developed to test the viability of the planar rendering concept, the hope was it'd be fast enough to build a Virtual Fighter styled game. With more optimization it probably would have been, but we didn't get that far.

    Code By: Kevin Picone
    Music By: Ardarc






    (Broken) Reality 1994/1995 Amiga Tech Demo

    The original goal of the Reality project was to create a Wolf 3D / Blade Stone styled 2.5D game engine for Amiga A1200 / 020 with Fastmem. It was pretty ambitious at the time, and looking back I wouldn't say that we ever really met our objective, but certainly gave it a good shot. The only down side was that almost nobody got to see it, so here's a warts and all version!

    The version shown here is about the only code that still assembles. There's newer versions of the source code, but they're missing lots of external files. None the less, this supports textured walls / floors with flat shaded polygons.

    For polygons, the original idea was to draw triangles as vertical spans, so they could be clipped against the walls 1D z buffer. But sadly that's not in this version. The walls are connected together line segments, to draw the view, we get a cone of verts and draw the walls attached (to the verts) into the depth buffer. The floors clip to the smallest wall segment in the buffer, so sadly there's a lot of overdraw, not to mention the funky texture slipping....

    The demo in the video, is running through the WinUAE emulator with an image of my A1200 hard drive. Most stuff seems to run ok, except the (AsmOne) assemblers ?, not sure why, but the combination seems rather unstable. So when you factor in the obvious bugs in my code ! :), this is best I can get it running in the short time available :( ... Hence the "Broken" Reality title.... Shame, I was enjoying the nostalgia.

    Code By: https://www.UnderwareDesign.com
    Art By: Raven (Textures are from Heretic)
    Music By: Ardvarc






    Vic Vision - Convert C64 Images To IFF (Amiga Program)

    Vic Vision is a program for Classic Amigas that converts raw Commodore 64 graphic images into Amiga IFF format. It was developed for 64 artists, demo / Game coders, nostalgia freaks, who might be moving onto the Amiga and would like to take their favorite artwork with them.

    Vic Vision supports many popular formats directly, such as FLI, AFLI, CFLI, Blazing Paddles, Koala, Raw Hardware Sprite Data, 8*8,8*16,16*16 fonts and many others, and also incorporates a custom format editor, allowing users to add support for either their own formats or any other that we've overlooked.






    Z Rotate (Amiga)


    This as a (very short) clip of another retro Amiga AGA effect. This is one a slightly different take on the regular Z-Rotate that was common at that time (Min 90's). It was later released as part of the experimental PLLB c2p package. Pllb is a set of C2p routines aimed at A1200 / 68020 with Fastmem.

    The demo is running _not_ running real hardware here sorry, my A1200 died long ago. None the less, you'll be able to find the demo on my site soon enough.

    https://www.UnderwareDesign.com






    Gouraud Cube (Amiga)

    This as a (very short) clip of another retro Amiga AGA effect, the classic gouraud cube.. Original, I know :).. Sadly the video compression kills the shading a bit though. Not too sure when this was first made now, probably been 1995/ 1997. The gouraud code is as you'd imagine it, pretty slow in retrospect. I think, it was only ever released as part of the experimental PLLB c2p package. Pllb is a set of C2p routines aimed at A1200 / 68020 with Fastmem.

    The demo is running _not_ running real hardware here sorry!, my A1200 died long ago. None the less, you'll be able to find the demo on my site soon enough.

    https://www.UnderwareDesign.com








    AGE Example - Loading 256 Colour Picture In AmosPro

    In very short this video we see the AGE library wrapper being used from AmosPRO. The demo frame work sets up the library, create a screen, loads the 8bit (256 colour) IFF, creates a copper list and then displays it.

    Developed By:
    https://www.underwaredesign.com







    Compressed Anim Replayer (Amiga AGA)


    This clip is showing a decompression system written for Amiga AGA 68020 systems back in around 1997/1998. The routine was written as a demo part where the objective was to get the animation data as small as possible, while retaining around a 10/12fps replay on real Amiga A1200/68020 hardware.

    The original animation consists of 120 frames, where each frame is 160x * 128y in 64 colours. The raw planar data for the whole animation weighs in at approximately 1440 odd K, even though the packer uses chucky pixels.

    The packer uses a three pass filter, stage one handlers string style byte repetitions, then there's a type a control byte replacement, with a bit merger pass at the end. The final code (which is big mess :) ), is long away from the original delta block / tile style packer, I'd intending upon using. But it worked out ok in the end.

    The compressed anim comes in 859K, so it's about 40% reduction over the raw planar version. What's surprising today though, is that ratio is still better than just LHA / LHX / RAR / ZIP'ing the original raw anim. But they're generic, and this was crafted to pack this animation and only this animation.

    Developed By:
    https://www.UnderwareDesign.com