# Order From Chaos: Fractals

## Sierpiński Triangle

The creation of the Sierpiński Triangle can be done in many ways. One of the coolest is the use of random (chaotic) input, and developing order.

## Algorithm – The Chaos Game

The algorithm could not be more simple:
1. set 3 origin points (or 4 if you’re in 3D).
2. initialize a point (to anything, but to avoid artifacts, start at one of the origin points).
3. move 50% the distance to one of the origins (randomly pick one)
4. repeat step 3, drawing the points each time.

This is known as “Order from Chaos” from where I first heard it (yes, I spelled it wrong in the demo, did you notice?). It is also called the “Chaos Game” for generating the fractal from randomness.

## Three Dimensional

I showcase this in 2D and 3D. The rendering in 3D is handled in software on the CPU. No GPU, 4×4 or even 3×3 matrices, involved here (well, I need the GPU to draw the dots!). It uses the core 3D formula that I figured out after many attempts in Grade 8, which is at the root of all perspective correct matrix transforms. I remember thinking with this formula, I could render literally anything… I felt I had discovered the Holy Grail of computer graphics.

## Color

The coloring is interesting as well. Each origin has its own color. If the point it at the origin, that color takes 100% of the precedence of the color choice. If the point is equidistant from two origins, then they contribute the same amount.

Interestingly, neither the 2D nor 3D versions have points near the center location of the structure, so you’ll never see a color of equal mix of all 4 colors.

# Iterative Function System

Iterative Function System produces fractals using the chaos game: Order from Chaos.

## Inspiration

My prior video, “order from chaos” produced the Sierpinski Triangle in 2D and 3D. I recalled the IFS (iterative function system) method of producing fractals. Specifically, the Barnsley fern. It is reminiscent of a Assembly ’94 (demoparty) entry in the demoscene: “Verses” by Electromotive Force, showcasing an animation / transition between IFS fractals.

## VGA Graphics

“Verses” was made using VGA, which had many graphics modes, mostly demonstrated by its 256 color mode (18-bit color palette = 6-bit per RGB = 0..63) — the standard 320×200 mode 13h (and other Mode-X variants). However, their IFS demo ran in VGA mode 12h: 640×480 x 16-colors.

(I’ve always wondered what the Sierra line of 3D adventure games would’ve looked like if the artists deployed their phenomenal use of 16-color dithered graphics in VGA 640×480 vs. the ugly 320×200 digitized versions of painted scenes).

## How IFS Works

Versus amazed me with the showcase of the Sierpinski Triangle — since it was being produced by a different method unknown to me. How was this done? It’s actually quite similar to the chaos game. In fact, it likely makes more sense when you think about it from the IFS perspective. Let’s use the Sierpinski Triangle as an example, since it’s easy to view as self-similar.

IFS is a collection of transformations of existing points. If you start with the entire Sierpinski Triangle — how do you make the 3 sections of self-similarity? You transform the triangle to be half the size (in X and Y) and move it towards one of the 3 spots. That’s it! Those are the 3 transform functions used in IFS. (The Chaos Game — in which you move an existing point half-way to one of the triangle vertices — is actually just doing the same thing!).

Now take the Barnsley fern. It’s the same thing except: The entire fern becomes two things: the left leaf, and the right leaf — which involves a rotation. But it also becomes two more things: it becomes itself pushed “upward” so that both left/right leaves become the next leaves in the sequence, and its stem; a “reset” function (the starting point). Why is the stem transform required? Because if it just continued to become left/right leaves, and “upward” pushes into the array of such leaves, the points would become “trapped” in that recursion.

That begs the question: Why does the Sierpinski Triangle not require a 4th function that resets the fractal? Why don’t the points get trapped in recursion, and never find their way back “out” to become the entire fractal? Because the transforms are only 50% of the size, and if you continue halving, and sum all of these, you get the whole: 50% + 25% + 12.5% + 6.25% + … = 100%. This is not the case with the fern.

## Colors

There is no standard way to color. I have my own invention: I assign a color to each transformation function. During the chaos game of transforming an X,Y point over and over, it also gets the color of that transformation. Now, if you just immediately used that color, you’d get (in the case of the ferns), the stem being color A, left leaf = color B, right = color C, and the extension (i.e. 95% of the entire fractal) = color D. Ugly. So it only interpolates (LERPs) to the desired color. This is how the stem of the fern stays colored so well.

As for the non-nature fractals… I’m not too pleased with the coloring; both in how the colors “spread” through the fractal, and the “nature” color palettes are just plain bad. In these non-nature cases, it would actually be better (sometimes) if the color changed (was reset) immediately, with no interpolation — as it would showcase the direct result of each function.

## Functions Source

Fractal data is acquired from the gallery of examples of IFS Construction Kit, made by Larry Riddle.

# What is Stoicism?

Stoicism is a philosophy that originated in ancient Greece and was developed by thinkers such as Zeno of Citium, Epictetus, and Seneca. It is a school of thought that teaches individuals to cultivate inner strength, self-control, and a sense of calm in the face of adversity.

Stoics believe that happiness is achieved through a state of inner tranquility, which can be attained by living in accordance with reason and virtue. They believe that external events are beyond our control, but we can control our reactions to them. Therefore, they encourage individuals to focus on what they can control, such as their thoughts, feelings, and actions.

Stoicism emphasizes the importance of living in harmony with nature, and of developing a sense of detachment from material possessions and worldly pleasures. It also emphasizes the importance of living a life of service to others, and of developing a strong sense of moral character.

Overall, stoicism is a philosophy that emphasizes the importance of living a virtuous and self-disciplined life, and of finding inner peace and contentment through personal growth and development.

# Tribute to Future Crew

I was in the middle of implementing some sub-systems into the Xona System 8 engine:

I happened to notice my subscribers was at 360. My original plan for my YouTube channel was to release games that related to the number of subscribers at interesting numbers (such as 100, 250, 500, 1000). I was already at 170 when I had this idea, and 250 came and went before I prepared. Should I let 360 pass as well?  How about a quick demo relating to 360°?

I had recently watched Future Crew‘s Second Reality.  It has a rotozooming effect (rotation and zooming) of a really cool image drawn by the artist, Pixel. Therefore, I made a quick bi-linear texture-mapping rotation demo in tribute to Future Crew:

# Inaccuracies

VGA Mode 13h (and Mode-X) resolution is 320×200, fitted to a 4:3 aspect ratio screen, meaning it had 5:6 sized pixels (taller than wider). I don’t respect that here. My apologies to Pixel (a 20% distortion is not appropriate).

You need quite high resolutions to showcase a 320×200 non-square 6:5 pixel ratio image perfectly. 1600×1200 is the minimum. Given that my demo is running in 1920×1080, I could have shown most of the image, but my engine, and my demos, and my tribute to Future Crew, are all based on the low-resolution VGA mode.

# CPU vs GPU

My demo uses the GPU. I am not calculating each pixel individually, nor am I using assembly language. But, I did “invent” bilinear texture mapping several years before Second Reality: I programmed the Mode 7 graphics of F-Zero in GW-BASIC, and it only took 30 minutes to render a single frame. I could watch and count the pixels begin drawn one-by-one.

# Resolution

Second Reality drops to a lower resolution (160×100, from the original 320×200) to enable full-screen frame-rate (less pixel updates), which is 70 Hz for VGA. Using Mode-X you can write to 2 pixels at once, and also you can double the repeat scan from 2 to 4 (VGA 320×200 has 400 actual scan lines, double scan is the default per scanline). At the time, in 1993, most video cards couldn’t even handle a full 64,000 byte copy into video memory in 1/70th of a second. So you just could not achieve such frame rates! It was a big deal to see full-framerate animations.

# Memory Cache

Later demos (1994) shows an improved speed of rotozooming, full-screen, at near frame-rate on fast video cards, in full 320×200 resolution (HeartQuake comes to mind). Such demos led me to understand memory cache, and why texturing the whole screen a full line at a time is not an efficient use of reading memory — as the bilinear scan of the source texels goes all over memory, especially when rotated. It is far better to texture 8×8 sections… more complex code, more instructions, but much faster! Given CPU speeds today, this is crucial for writing performance critical code.

# Assembly Language

I had been chasing after assembly language since I was 7, when I first programmed on my TI-99/4A. I knew the real power in this machine, and my later Tandy 1000 SX, was extracted via assembly language, and BASIC was just not up to the challenge. My first Mode-7 demo took 30 minutes to render a single frame. I needed assembly.

But I didn’t have it.

Enter Second Reality.

# Second Reality Impact

Second Reality was my introduction to the demoscene. However, this introduction was not what you may think. I didn’t know of software cracking, graphics demos, or the demoscene. I was merely shown Second Reality… with the ridiculous explanation that there was an “assembly language” competition, and some Finnish kids decided to show off their assembly language skills, and showed up with Second Reality — a full-fledged multi-media demo that showcases a dozen effects simply not possible on a 486, most at the full frame rate (70 Hz), in Dolby surround sound (which isn’t even possible on the Gravis Ultrasound hardware they were using). My jaw dropped both watching the demo and wondering how they blew away their competition.

# Reality

I later learned this was the demoscene. Second Reality was entered into a “demo party” or “demo compo” called “Assembly ’93” (a pun on “assembly language” and “assembly of people”). It was not an “assembly language competition”, it was a graphics demo competition, where mostly everyone had programmed similar effects, to music, in their own multi-media presentations. Even after learning this, I was still amazed. It still seemed impossible. Their presentation was well beyond what other demos showcased. And I knew I needed to get my hands on assembly language…

# Game Engine

Xona System 8 is the name of a new game engine / game development framework that I am building in C# on top of the XNA / MonoGame framework.

Its purpose is primarily for building new games quickly — it is both a game engine in its own right, and also a game development framework, where games can be developed quickly.  Part of my goal is also to allow releasing older XNA games for release onto PC and other consoles — with the updated requirements of today’s games (resolutions, framerates, online services, etc.)

The below video shows its very beginnings.  Currently it showcases the distinction between the game and the engine, with clearly defined ownership: engine running the graphics, rendering, font manager, and update layer vs. the game simply requested such resources with minimal API access.

# First Showcase

Engine:

• Low resolution / pixel-zoom screen (I am Retro! “Retro Re-invisioned“)
• Graphics rendering sub-system
• Extensive font library (the fonts you see are my own)
• Font render & animation framework
• Texture / Sprite creation

Game Demo:

• Sprite requests
• Integration into the engine
• No level details handled
• simple engine API calls

# Driving Force

I have made several engines over the past couple of years (well I have all my life, since I was 7 — but in the past 2.5 years, I’ve made several in MonoGame), as you can see in my other videos.  Some created in less than 48-hours in game jams, and some are side passion projects.  Many are recreations of technology I invented long ago — which I built in hand-optimized assembly & machine language, Turbo Pascal, GW-BASIC, and TI BASIC (yes that’s a 50,000x speed difference — from 1 frame per 30 minutes for a half-screen F-Zero style texture mapper in Tandy graphics to 30 frames per second in assembly in VGA, pre-GPU).

Platforming Engine

Side-Scrolling Shmup Engine

Arena Shmup Engine

Voxel Engine

3D Ray Casting Engine

Equation Rendering Engine

3D Polygon Engine

# Barrier to Entry

It is time to break down the barriers to entry that prevent these engine demos from becoming full, feature-rich, implemented, playable, and releasable games.

It is time to collaborate all of the work into a single engine system – a game dev system – that allows the extra “fluff” of a game to be handled elegantly by a core engine, a system of sub-systems, that are all protected from the user (the game maker), and remove it from distracting efforts of focusing on the game.

Its purpose is to provide a framework from within which to make prototypes — such as simple weekend game jams, or quick ideas that can be tested and tried, without rewriting an engine from scratch (or borrowing code from a prior engine).

# Quick Development – Prototyping

While it is great to witness the core code from my 2D Side-Scroll Shmup Engine be reused almost verbatim in my 3D Voxel Engine (animation system just works, along with sprite scaling, with simple Vector2D changed into Vector3D) — along with the code from my 2D Arena Engine used verbatim in my 3D Ray Cast Engine (this still amazes me just how similar the 3D game is to the 2D game; I totally get it, Carmack).  What would be better is if the engine provided this code, the framework, to the games that want it.

I am going back to my roots as a TI BASIC, GW-BASIC, and Turbo Pascal developer where either the language was simple enough (BASIC dialects) or the language was powerful enough (Turbo Pascal units) to allow an extremely quick foundation upon which you could build.  I feel anyone who has not written code in the original BASIC interpreters that accompanied home computers — where you could write an entire game in a screenful of code (like I did with Tetris, including saving high scores) — is missing how simple & quick programming can (and should) be.  In structured languages you can build utility units to help out, as I did with Turbo Pascal, but for some reason this seems harder today.

No more.

The goal is a working graphics test from Visual Studio “File -> New -> Project” in 5 minutes flat, a full game in 1 hour, and a polished demo in a weekend.  No more barriers.

# Programming Concepts

I am keeping the following concepts in mind:

# Super Computer’sBest First Chess Move

The Sesse Super Computer runs automated analysis on interesting high-level chess events, in real-time, such as the World Championships.

# Super Computer Hardware

While its computing power varies, on December 29, 2021, during the 2021 World Chess Championship, Sesse was the following:

That’s 336 computing cores!  Each running at 2.0 GHz.

# Starting Chess Position

Interestingly, during the FIDE World Rapid & Blitz Chess Championship in Warshaw 2021, while waiting for a blitz match between Magnus Carlsen and Klementy Sychev, the computer analyzed the starting position:

Sesse analysis on the starting position

It analyzed this for 1 hour 24 minutes, computing 328,179,236 nodes per second (recall that Deep Blue, with its 256 custom build chess chips, could compute 200,000,000 per second during the middle game), for a total of 1,660,504,563,547 nodes (that’s 1.6 trillion nodes!), to a depth of 70 ply (75 selective):

Principal variation for starting position, along with alternate moves.

Analysis snapshot was taken at Wednesday, ‎December ‎29, ‎2021, ‏‎11:31 AM AST.

# Principal Variation

Analysis from the 336 x 2.0GHz Intel Ice Lake SP (OpenMPI):

Score: +0.25
PV: 1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. Re1 Nd6 6. Nxe5 Be7 7. Bf1 Nxe5 8. Rxe5 O-O 9 d4 Bf6 10. Re1 Re8 11. Bf4 Rxe1 12. Qxe1 Ne8 13 c3 d5 14. Bd3 g6 15. Nd2 Ng7 16. Qe2 Be6 17. Nf3 Bg4 18. h3 Bxf3 19. Qxf3 Ne6 20. Be3 Bg5 21. Re1 c6 22. g3 Bxe3 23. Rxe3 Qd7 24. Qe2 Re8 25. a4 Qd8 26. Kg2 h5 27. a5 Ng7 28. Rxe8+ Nxe8 29. Qe5 Kf8 30. b4

This position results at the end of the principal variation:

End of principal variation of Sesse analysis on starting position.

# Alternate First Moves

The following are all 20 potential first chess moves, using Multi-PV analysis, computed using the lower powered 16 x 4.2GHz AMD Zen 3, which reaches depth 49 and 50.

Interestingly, f4 is not the worst move.  However, it is the first of the negative scores, along with b4, h4, Nh3, Na3, f3, g4.  I guess weakening your King, and moving Knights to the board edges really are bad ideas!

Positive:
e4 +0.41 d50 1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. Re1 Nd6 6. Nxe5 Nxe5 (…)
g3 +0.23 d50 1. g3 c5 2. c4 Nc6 3. Bg2 g6 4. e3 Bg7 5. Nc3 e6 6. Nge2 Nge7 (…)
d4 +0.22 d50 1. d4 Nf6 2. Bf4 d5 3. e3 e6 4. Nf3 Bd6 5. Bxd6 Qxd6 6. c4 c5 (…)
c4 +0.17 d50 1. c4 Nf6 2. d4 e6 3. g3 Bb4+ 4. Bd2 Be7 5. Bg2 d5 6. Nf3 O-O (…)
Nf3 +0.15 d50 1. Nf3 Nf6 2. d4 e6 3. c4 d5 4. g3 Bb4+ 5. Bd2 Be7 6. Qc2 O-O (…)
e3 +0.12 d50 1. e3 Nf6 2. d4 d5 3. Nf3 e6 4. Bd3 Be7 5. b3 O-O 6. Bb2 b6 (…)

Draw:
Nc3 0.00 d49 1. Nc3 d5 2. d4 Nf6 3. Bf4 e6 4. Nb5 Na6 5. e3 Be7 6. Nf3 O-O (…)
a3 0.00 d50 1. a3 c5 2. e4 g6 3. Nf3 Bg7 4. h3 d6 5. Bb5+ Bd7 6. Bxd7+ Qxd7 (…)
a4 0.00 d49 1. a4 Nf6 2. d4 e6 3 Nf3 c5 4 e3 Nc6 5. Bd3 d5 6. O-O Bd6 (…)
b3 0.00 d50 1. b3 e5 2. Bb2 Nc6 3 e3 Nf6 4 Nf3 e4 5. Nd4 h5 6 c4 Rh6 (…)
c3 0.00 d50 1. c3 e5 2. d4 e4 3 c4 c6 4 Nc3 d5 5 a3 Be7 6 cxd5 cxd5 (…)
d3 0.00 d49 1. d3 d5 2. Nf3 Nf6 3. g3 Nc6 4. d4 Bf5 5. Bg2 e6 6. O-O Nb4 (…)
h3 0.00 d50 1. h3 e5 2. e4 Nf6 3. Nc3 Bb4 4. a3 Ba5 5. Nf3 O-O 6. Bet d6 (…)

Negative:
f4 -0.16 d49 1. f4 d5 2. Nf3 c5 3. g3 Nc6 4. Bg2 e6 5. O-O Be7 6. d3 Nf6 (…)
b4 -0.36 d49 1. b4 e5 2. Bb2 Bxb4 3. Bxe5 Nf6 4. c3 Be7 5. d4 d5 6. Bxf6 Bxf6 (…)
h4 -0.40 d49 1. h4 e5 2. c4 Nf6 3. d3 Bc5 4. e3 Bb6 5. Be2 d6 6. b4 c6 (…)
Nh3 -0.49 d49 1. Nh3 d5 2. d4 Nf6 3. Ng5 c5 4. e3 g6 5. dxc5 Qa5+ 6. c3 Qxc5 (…)
Na3 -0.69 d49 1. Na3 e5 2. Nc4 Nc6 3. e4 Nf6 4. d3 d5 5. exd5 Nxd5 6. Nf3 f6 (…)
f3 -0.74 d49 1. f3 e5 2. Nc3 Nc6 3. e3 d5 4. Bb5 Nf6 5. Nge2 Bd7 6. d3 a6 (…)
g4 -1.51 d49 1. g4 d5 2. e3 Nc6 3 d4 e5 4. Nc3 Be6 5. dxe5 Nxe5 6. h3 h5 (…)

# Kyosho Ultima

The original 1/0th scale R/C car, Kyosho Ultima, was released in 1986.  It won the 1/0th scale off-road electric World Championships in 1987.  You can watch a video of it.

Kyosho re-released this model in 2019, Kyosho EP 2WD Kit Ultima (part 30625).  It is the 8th model of the “Kyosho Vintage” re-releases, which is a part of their legendary series.

# Tools to Build Kyosho Ultima

I bought the following items to help build the Ultima Re-Release, with my review of each.

# Things Needed to Run Kyosho Ultima

The kit does not come with the following.

I have recommendations for each.

# Media

Kyosho Ultima website:

# Scary Virus

I had a scare today.  I sent my brother a C# MonoGame build of my own side project.  We were testing various monitor framerates and resolutions (I have a 240 Hz Alienware laptop, and he has dual 120 Hz monitors).

He found something shocking.  He couldn’t download (via Discord) because Windows Security found Trojan:Win32/Sabsik.TE.A!ml:

Threats found.
Trojan:Win32/Sabsik.TE.A!ml

Sabsik is a pretty nasty virus!

Sabsik executes commands from an attacker.

More details:

Microsoft Security Intelligence:
This threat can perform a number of actions of a malicious hacker’s choice on your PC.

Reddit:
Sabsik can be instructed to download and run additional malware, and it’s possible that more malware is present. Also, it both can and does steal data and credentials (password, login info, etc.) and encrypt data on your computer, and asking for a ransom to decrypt it again, aka ransomware. It usually tries to open a backdoor too, giving the attacker remote access to your computer.

Yikes.

# False Positive?

Developers are accustomed to virus scanners finding false positives in their private developer builds.  So, I ran a scan on my own machine, but was shocked that there were no results:

We were both running Windows 10.  But only one of the two computers was reporting this virus from the same executable.

# Inconsistent Findings

We tried scanning other builds, and the findings were inconsistent between them.  My computer reported no issues.  My brother’s computer reported Sabsik for some and not for others.  Since I am not building an executable with the virus inside of it, I thought maybe it was attaching itself to it after the build from discovering the activity on this recently created file, and ignoring older builds that I had not been messing with.

I was now wondering if the virus had compromised my own machine’s ability to virus scan.

# Windows Security Update Failure

We thought what could be different from the two computers, so we decided to check the Windows Security versions.  They were different!  Mine had updated within the hour, and my brother’s only updated 6 hours ago.

Windows Security version 1.355.417.0

The scan results disappeared.

A Windows Security update introduced this false positive, scaring who knows how many people out there, to be fixed hours later.

# Further Confirmation

I uploaded my build to Virus Total for a meta scan, which uses several dozen virus scanners.  One had a false positive for a different virus, and the rest showed no results found.  None found Sabsik.

# Always Type The Code

Don’t just copy code (from the Internet, coworkers, friends, or even from yourself from your own code).

Type it out.

Every time.

If you don’t know what the code means, character by character, and you could not arrive to it by yourself without addressing another source, then type it.  Only when you can write it yourself effortlessly are you allowed to copy and paste.

# Why?

Because this is how you learn.

Otherwise you are getting yourself into Learned Helplessness (video from Veritasium), where you are not learning yourself, but are using the energy from others so that you need not spend any.  The problem is this is a short term solution.  You learn nothing that takes you forward on a better path, where you can be self reliant (video from Lost Relic Games).

# Why “First Pixel”?

From an email (May 11, 2016):

I’m often reminded of getting the “First Pixel” on screen, back in the day where you had to get the graphics mode working, and then write to the proper memory address, and if your registers were correct, and your assembly was good, you wouldn’t soft boot your computer, and you’d see a dot on the screen.

A collection of quotes that Matt and I had from the demo scene explained this well:

“A DOT!!!! A FUCKING DOT!!!! YEAH!!!!!!!” — Chris Chapin, on getting his first graphic element working

This is now what I think about. I try to be pragmatic. Get the first thing working. Get object A talking to B. Get something spit out in the log to show it’s running. Get that First Pixel. I think I have a name I really like. Maybe I should make a blog called First Pixel. Also sounds like a good name for a retro video game.

I had forgotten at first that I heard about this from quotes from the demo scene, so I looked it up at work today. I found the post:

jheide@ccinet.ab.ca (Josh Heidebrecht) writes:

>I hope I made this journey sound like a long and difficult one,
>because it will be. But please don’t get scared away yet, after you
>put your first pixel on the screen you’ll feel the adrenalin rush run
>through your blood stream, and you’ll never be able to stop 🙂
>Good-Luck…

JH, you are the MAN! You just reminded me of when I first was sat down if front of a friend’s PC and I was just starting to learn Pascal. I found TASM and grabbed a couple of books laying around on VGA and ASM. In a 1/2 hour I wrote my VERY FIRST exe, it just switched to VGA and put a dot in the upper left hand corner of the screen and I screamed:

“A DOT!!!! A FUCKING DOT!!!! YEAH!!!!!!!”

So I can confirm that adrenalin rush. ;>

Canard@ax.com
Chris Chapin

Love it!

# Vanishing Point

Mike Birken’s fascinating F-Zero True Horizons page shows what F-Zero would look like if the rendering draw distance was not limited.

In-Game Screen Shot

Vanishing Point (courtesy of Mike Birken)

Mike discusses possible reasons F-Zero limited the draw distance.  While they are good guesses, I have stumbled upon the actual reason.

Teaser:  F-Zero already renders to the maximum draw distance allowed.  In fact, it draws further.  Some of the data near the horizon is actually garbage, but is unnoticeable due to the regularity of the level graphics.

So what’s the reason?

# Level Size

While pondering writing an F-Zero style engine in modern technology using MonoGame — which is something I wrote ages ago in 320×200 x 256-color Mode 13h (the same graphics mode that the original 1993 Doom ran on) — I thought I’d look at actual F-Zero maps.  My curiosity was to see how the designers managed to draw the track-limit circles within the restrictions of a tile-based graphics system.  My intention was to use today’s bitmapped graphics mode, where I can control individual pixels, to draw these circles perfectly.  All I need is a big texture — say, 4096×4096!

I was astonished to find out the maps were 4,000 to 6,000+ pixels in size.  Huge!  These size maps are much larger than the 1024×1024 pixel limit of SNES Mode-7 hardware.  Mode-7 is tile-based.  It can render 128×128 tiles, each 8×8 pixels in size, equaling 1024×1024 pixels.  Retro Game Mechanics Explained has a great video explaining these restrictions, “SNES Background Mode 7”.

Thus we have the true answer…

The Mode-7 1024×1024 tilemap limits the draw distance.

# Tile-Based Graphics

F-Zero uses the same technology that Super Mario Bros. does.  SMB expands a video screen, that barely has enough video memory to draw a single screen, and makes it appear as though the world is vast.  It reuses the same video memory as the screen scrolls, updating it (loading new content at the edge of the screen) as you run.  (And you thought today’s massive world AAA games were the first to do streaming!)  Retro Game Mechanics Explained has a perfect video for explaining this “Loading Seam”.

Consider games like Pilot Wings.  It shows the entire world… yet it’s tiny.  Why?  That’s how small 1024×1024 is.  F-Zero maps get into the 4,000 and 6,000 pixel size.  But you can only “view” a 1024×1024 chunk of it, as those 128×128 tiles are changed and slide as though the camera is moving through the world.

# Draw Distance Limitation

Using an F-Zero map (captured by Rick N. Bruns), let’s showcase a 1024×1024 section of that map, near the same location that Mike Birken shows in his F-Zero True Horizons page, Rendering section.

We’ll use “Map 3: Sand Ocean”, since it has some good artifacts to discuss:

In-Game Screen Shot (note draw distance and left/right side roads)

The white dot is the approximate camera location that Mike’s renders are using.

The blue square is a 1024×1024 pixel section marked off, centered on that camera location.

Since the game plays in 360 degrees, and players can spin quickly, the 1024×1024 playfield must capture in all directions.  Part of the “Loading Seam” technology is that you only need to update edges as you scroll.  This is what made Sonic the Hedgehog fast with its Blast Processing.  The same is true for F-Zero, running at 60 frames per second, using the slow SNES 3.58 MHz CPU.  You would not be able to use the entire tilemap for the forward direction (doubling the draw distance), as you would not be able to turn, because turning would require you to update half of the play field (8000 tiles) in a few frames, vs only 100 to 200 tiles per frame like F-Zero does.

# Draw Distance Limit Artifacts

The view distance is quite limited.  If the renderer attempted to render more, it would access beyond the tilemap edge.  You will not get more of the road in the distance.  You will get whatever is on the other edge of the tilemap, which is garbage.  You do not notice since usually the background track graphics are similar (sand is sand)..

You can actually see this wrapping limitation in action!

Take a look at the in-game screenshot again:

In Game Screen Shot (notice the distant roads on the left & right)

There are two roads in the distance; one to the left and one to the right.  In the actual map, neither of these exist.  The roads are gray, but only one side is black.  Not both sides, like a true road.  The same side is black for both.

Why?

Because they are the same road; they are being rendered from the same tilemap data.  Also, the tiles are garbage tiles; this draw distance has exceeded the tilemap limit, and is accessing tiles on the other side of the tilemap.  If you’ve watched the Loading Seam video, you’ll know that these are just random tiles from another part of the map.

The programmers of F-Zero really stretched the limits of the draw distance — so far that it actually draws garbage at times, where they hope you don’t notice.

# Discussion

I thought it may be interesting to respond to the original believed possibilities for the “false horizon” draw distance:

• Original design = Racetracks receding into mist
• It is possible this was part of the design.  Given the game world is flat, if there were no draw distance, then you would see the whole track in any direction you faced.  It’s probably a good idea to not reveal the entire world, but enough that you don’t feel robbed of vision.  It looks like F-Zero achieves this.  Even if it could draw further, designing such that it fades into the mist is probably a good idea.  Then again, at the low resolution of the SNES, it likely wouldn’t matter too much.
• Evolution from scan-line road engines to bi-linear texturing mapping Mode-7
• This is not the case, since F-Zero was explicitly a tech-demo of Mode-7, and the evolution was that it became a game.
• Fixed-Point math accuracy issues at far distances
• In general, it’s the close distances where the fixed-point math runs out of precision.  The more significant digits must be present for Mode-7 to work, to correctly scan 1024×1024 pixels of the 128×128 tile set of 8×8 texel tiles.
• Aliasing graphic artifacts of 1 sample per pixel at far distances
• Very true that this is an issue, but F-Zero seems to ignore this everywhere in the game.  Right out of the gate, it uses very poor textures for this single texel sampling method of Mode-7 (no mipmaps), such that even the power-up recharge station lines flicker, and most of the off-track graphics are a flickering mess.
• Memory limits to store more software sprite scaling at far distance
• The extras for small versions are negligible compared to the memory for all of the larger versions.  When you consider creating mipmaps of a texture, the first mipmap (half width, half height) is only 1/4th the size of the original. The next is 1/16th the size. Etc. Making only 1.333x the required size of just the original. Now, while software sprite scaling requires many more levels than just 50% size reduction each time, it gives a sense that the extra few very small ones is not a real concern.
• Limiting physics to “on-screen” track
• Certainly possible that true physics only applies to what you see, however any “statistical model” used for far away vehicles could be maintained even if they are in view (since they are far away.

# Two Player F-Zero

I suggest watching: The Making Of Super Mario Kart – Wrestling With Gaming and The Story of Super Mario Kart – Gaming Historian which describes Super Mario Kart arrived on the scene with a small world of just the 1024×1024 pixel world size, due to it being the only way that a 2-Player F-Zero could be made — which means you couldn’t have large worlds, and couldn’t have fast vehicles. Thus the go-karts. Thus the visibility of characters. Thus Mario and the gang being added.

These videos don’t explain why 2-player isn’t possible in F-Zero.

It’s because the current 128×128 tile set has to contain both players’ views, which means you have to limit them to 64×64 (or 64×128 or 128×64 — but you don’t know which direction they may face, so 64 is the limit).  This means you must halve the distance before the Mode-7 starts texturing mapping into the tiles of the other view.  While F-Zero “Single Player” already texture maps beyond the correct tile limits, you can imagine how much harder it would be to handle this with half the limit.

Off hand, you can double the size of the pixels on-screen, and have a super blocky looking F-Zero, with lots of chaotic random mess in the top-left and top-right corners of the screen (as those are tiles from your opponent racing into new tiles that have nothing to do with your viewpoint — again, while F-Zero “Single Player” does the same, at least those tiles are constant and unchanging!).  So you’d have to zoom even further.