What counts as a Funge variant
The word Funge is used loosely, so it helps to sort the territory into layers. At the center is the Funge-98 specification, which defines Unefunge, Befunge and Trefunge for one, two and three dimensions. Just outside that sits the older Befunge-93, which Funge-98 grew out of. Further out are languages that borrow the central idea, a pointer moving through a grid of instruction cells, but change enough rules that they are better called cousins than members.
There is no single authority that decides who is in the family. The name is a community convention, and the boundary is blurry. Reasonable people draw it in different places, so this article describes common kinds of difference rather than a fixed catalog.
Variation in the specification itself
Even inside Funge-98, variation exists. The specification is large, and an interpreter may implement it fully or only in part. One common pattern is an interpreter that handles the core instructions and a few well-known extensions but omits others, such as file access or concurrent pointers. Another is an interpreter that adds features of its own behind its own fingerprints.
So when someone says a program is “Funge-98”, the useful follow-up question is which parts it needs. A program restricted to the common core runs almost anywhere. One that leans on rarely implemented instructions may run on only a handful of interpreters. Checking the system information an interpreter reports about itself is a standard way to learn what it supports.
Changing the dimensions
The most obvious axis of variation is the number of dimensions. The Funge-98 specification standardizes one, two and three. Nothing in the underlying idea stops there: a pointer’s direction is a vector, and a vector can have any number of components. Hobbyists have sometimes sketched four-dimensional or higher versions, mostly as thought experiments, because writing and visualizing such programs is difficult. The practical limit is human, not logical. We can lay out a plane on a screen and a few layers in a file, but not much more.
The next article in this cluster covers the one- and three-dimensional members in detail, so the point here is only that dimension count is the cleanest, most formal way a variant can differ.
Changing the shape of space
A second axis is the geometry. Funge assumes a square grid whose cells have four neighbors, and the pointer wraps around like a torus or its unbounded cousin. Other languages keep the pointer-on-a-grid model but change the grid. A hexagonal grid gives each cell six neighbors and changes what turning means, since there are no right angles. Others change the edges, so that instead of wrapping the pointer bounces or stops. These choices are not cosmetic; they decide what counts as a loop and how easily a program can be laid out by hand.
Changing the instructions and the data model
A third axis is what the pointer does when it arrives. Some languages in this style use mirrors in place of direction arrows: the instruction deflects the pointer at an angle, as a mirror deflects light. That is the territory of mirror commands, and the best-known example is a fish-themed language that keeps the stack and the grid but reworks the instruction set. Others replace the stack with a tape, a queue, or registers. Still others abandon characters altogether and use colors, as Piet does, which makes them closer to visual cousins than to Funge proper.
You can usually tell how far a language sits from the core by asking three questions. Does a pointer move through a grid of cells? Does it carry a direction that instructions can change? Does the program share the grid with its data? The more yes answers, the closer the language is to the family.
Why so many variants exist
Variants multiply for several reasons that are common across esoteric languages. Making one is a manageable project: a small spec and an interpreter can be written in an afternoon. A variant is also a way of asking a design question and seeing the answer, such as what happens if the grid is hexagonal or the stack becomes a queue. And naming a new language is part of the fun, which is a theme of esolang culture and of language naming conventions, where a pun on an existing name is a long tradition.
There is a serious side as well. Each variant is a small experiment in how much of a language’s feel comes from its memory model, its control flow or its syntax. Comparing a grid with a tape, for instance, shows how much of a Funge program’s character comes from putting the code and the data in one two-dimensional space.
Comparing variants fairly
When you meet a new Funge-like language, a few habits help. Read what it says about space, direction and wrapping first, because everything else depends on those. Check whether the stack underflows to zero or raises an error, and how the interpreter treats instructions it does not know. Look for a test program or a set of examples, since a spec alone often leaves corners open. And be cautious about claims of compatibility: “mostly Befunge” can mean very different things.
Finally, keep in mind that obscurity is part of this world. Many variants have one author, one interpreter and a short page of documentation. They are best treated as ideas to read and enjoy, not as tools with long-term support.