Necromunda Andy Cowell's The Sumper, programming, data structures, and digital archaeology

Flamekebab

Gang Hero
Gorkamorka Warboss
Feb 17, 2011
1,010
2,168
133
34
Rotherham, UK
fox-box.co.uk
Brace yourself because this topic is going into deep nerd territory. You've been warned!


Every now and again though I think of a particular gang name, "the Mushy Gun Militia", and wonder. Also it turns out that if you googled the gang name prior to me posting this topic you'd get one result:
5KCt61S.png

(Google bought the Usenet archives in 2001 so that's a newsgroup posting from 1996 with just the name of the gang)

I think of the gang name because in the late '90s I stumbled across Andy Cowell's Necromunda page and was perplexed and excited by what I found. I wasn't really sure what I was looking at but it was some sort of program written for Necromunda. I think I thought it was something for randomly generating gangs or something like that. It wasn't, but that's the rough idea my younger self had.

Some years later, in 2005, I once again thought about it and decided to ask over on the Ubuntu forums. I was starting to get into using Linux as my main operating system and Andy's page seemed a lot like the more advanced stuff I'd seen related to Linux. (Side note: I no longer use Linux as my main desktop OS - instead I use macOS which under the hood essentially is Linux but with better support for commercial software. It's not technically Linux but they're very, very similar based on my experience using both)

The responses I got were helpful but I didn't truly understand what was going on, to be honest. I stopped thinking about it. Do you ever have those moments of "maybe I'll understand when I'm older?" and then reflect on them years later? I had one of those whilst trying to sleep last night. I'm older now...

I said earlier I don't use Linux as my desktop OS - I do still use it daily though. It's running on the VPS I use to run my websites. I can pull up a Linux command line as long as I have an internet connection - even from my phone. I don't know if it was Linux or some other *nix related system Andy was using back in the day but on my VPS I installed a couple of dependencies (Bison and Flex. These two are used to build something that can parse the input files into something workable - more on that in a bit). After that it threw a few warnings but otherwise compiled happily:

Bash:
flamekebab@mail:~/sumper# make
bison -d nec.y
flex nec.lex
gcc -g -o nec lex.yy.c nec.tab.c main.c -lfl
main.c: In function ‘do_stats’:
main.c:187:44: warning: passing argument 4 of ‘qsort’ from incompatible pointer type [enabled by default]
     qsort(gangs, gang_count, sizeof(struct _gang *), reverse_gang_compare);
                                            ^
In file included from main.c:2:0:
/usr/include/stdlib.h:765:13: note: expected ‘__compar_fn_t’ but argument is of type ‘int (*)(struct _gang **, struct _gang **)’
 extern void qsort (void *__base, size_t __nmemb, size_t __size,
             ^
main.c:208:48: warning: passing argument 4 of ‘qsort’ from incompatible pointer type [enabled by default]
     qsort(members, member_count, sizeof(struct _member *), reverse_member_compare);
                                                ^
In file included from main.c:2:0:
/usr/include/stdlib.h:765:13: note: expected ‘__compar_fn_t’ but argument is of type ‘int (*)(struct _member **, struct _member **)’
 extern void qsort (void *__base, size_t __nmemb, size_t __size,
             ^
flamekebab@mail:~/sumper# ls
lex.yy.c  main.c  Makefile  militia.txt  [B]nec[/B]  nec.lex  necro.h  nec.tab.c  nec.tab.h  nec.y
I don't speak enough C to know what's going on but it spat out a binary ("nec") which I then renamed to "sumper" as that's what Andy called it originally.

Okay, so what does the program do?
Well the thing I understand now that I didn't in 2005 is standard streams (stdin and stdout). This is standardised Unix thing (and so applies to Linux, *BSD, and so on too). Essentially it's text. A program spits out text and takes in text. You can take the output of one program and feed it into another.

So on Andy's page he gives this example:
Bash:
mattel:[/blue/homes/cowell/src/nec] cat militia.txt | ./sumper -t
Gang: The Mushy Gun Milita [ 1327 ]

Member            M  BS  WS   S   T   W   I   A  Ld
el Feygun......   4   4   4   4   3   1   3   1   8     170   85
Leader            EQ: Boltgun, Massive Axe

Sumo...........   4   3   3   3   3   1   3   1   7     195   72
Heavy             EQ: Heavy Stubber, Laspistol

Full Otto......   4   4   2   3   3   1   3   1   7      80   36
Ganger            EQ: Autogun, Stub gun
                  IN: Lost 1 finger on left hand

Joey the Slug..   4   3   3   3   3   1   3   1   7     100   30
Ganger            EQ: Shotgun (sld/sctr/mstpr/bolt), Stub gun

Plasmo.........   4   3   3   3   3   1   3   1   7     110   29
Ganger            EQ: Chainsword, Plasma pistol, Stub gun

Toothpick......   4   3   3   3   3   1   3   1   7     110   26
Ganger            EQ: Bolt pistol, Stub gun, Frag grenades

Sawtooth.......   4   3   3   4   3   1   3   1   7     105   32
Ganger            EQ: Chainsword, Laspistol w/Hot shot

Wispy..........   4   2   3   3   3   1   4   1   6      55   17
Juve              EQ: Hand flamer, Stub gun
                  SK: Crack shot

Tyco...........   4   4   3   3   3   2   4   1   8      75    0
Scummer           EQ: Knife, 2 Bolt Pistols
                  SK: Gunfighter, Quick Draw
What he's doing there is using the program cat to read the contents of militia.txt. Normally it'd just display it:
Bash:
flamekebab@mail:~/sumper# cat militia.txt
Name "The Mushy Gun Milita"
Rating 1268
Territory Vents, Tunnels, Settlement, "Drinking hole", Slag
Stash 30
Hoard = ( "Heavy Stubber", "Your Mama" )

#Member "el Feygun" Leader 4 4 4 3 3 1 3 1 8 IN=("Old Battle Wounds", "Head Wound") EQ=("Boltgun", "Massive Axe") SK=(Infiltration) 170 66
Member "el Feygun" Leader 4 4 4 3 3 1 3 1 8 IN=() EQ=("Boltgun", "Massive Axe") SK=() 170 66

Member Sumo Heavy 4 3 3 3 3 1 3 1 7 IN=() EQ=("Heavy Stubber", Laspistol) SK=() 195 64

Member "Full Otto" Ganger 4 3 3 3 3 1 3 1 7 IN=() EQ=(Autogun, "Stub gun") SK=() 80 21

Member "Joey the Slug" Ganger 4 3 3 3 3 1 3 1 7 IN=() EQ=("Shotgun (sld/sctr/mstpr/bolt)", "Stub gun") SK=() 100 23

Member Plasmo Ganger 4 3 3 3 3 1 3 1 7 IN=() EQ=(Chainsword, "Plasma pistol", "Stub gun") SK=() 110 21

Member Toothpick Ganger 4 3 3 3 3 1 3 1 7 IN=() EQ=("Bolt pistol", "Stub gun", "Frag grenades") SK=() 110 21

Member Sawtooth Ganger 4 3 3 3 3 1 3 1 7 IN=() EQ=(Chainsword, Laspistol) SK=() 90 22

Member "Louie the Punk" Juve 4 2 2 3 3 1 3 1 6 IN=() EQ=("Stub gun", Maul) SK=() 45 0

Member Wispy Juve 4 2 2 3 3 1 3 1 6 IN=() EQ=("Hand flamer", "Stub gun") SK=() 55 0

Member Tyco Scummer 4 3 4 3 3 2 4 1 8 IN=() EQ=(Knife, "2 Bolt Pistols") SK=(Gunfighter, "Quick Draw") 15 60
flamekebab@mail:~/sumper#
But instead he's using | ("pipe") to send that text into the sumper. It then reads it and outputs a nicely formatted bit of text.

Something's puzzling me about that though - as far as I can tell the code he released doesn't include a -t option! It has -s and -h options that output stats and HTML respectively but I don't see anything for -t!
Similarly in his other example there's something missing:
Bash:
mattel:[/blue/homes/cowell/src/nec] cat militia.txt | ./sumper -s
 
Rank of gangs by rating:
The Mushy Gun Milita:  1327
 
Sort gang members by experience.
el Feygun (The Mushy Gun Milita):          85
Sumo (The Mushy Gun Milita):               72
Full Otto (The Mushy Gun Milita):          36
Sawtooth (The Mushy Gun Milita):           32
Joey the Slug (The Mushy Gun Milita):      30
Plasmo (The Mushy Gun Milita):             29
Toothpick (The Mushy Gun Milita):          26
Wispy (The Mushy Gun Milita):              17
Tyco (The Mushy Gun Milita):               0
 
Sort gang members by wounding hits
Tyco (The Mushy Gun Milita):               2
Wispy (The Mushy Gun Milita):              2
Full Otto (The Mushy Gun Milita):          2
el Feygun (The Mushy Gun Milita):          1
Joey the Slug (The Mushy Gun Milita):      0
Toothpick (The Mushy Gun Milita):          0
Sawtooth (The Mushy Gun Milita):           0
Sumo (The Mushy Gun Milita):               0
Plasmo (The Mushy Gun Milita):             0

If I run the same militia.txt through the program I get this output:
Bash:
flamekebab@mail:~/sumper# cat militia.txt | ./sumper -s
We have 1 gangs.
The Mushy Gun Milita:1268   

We have 10 members.
el Feygun (The Mushy Gun Milita):    66
Sumo (The Mushy Gun Milita):    64
Tyco (The Mushy Gun Milita):    60
Joey the Slug (The Mushy Gun Milita):    23
Sawtooth (The Mushy Gun Milita):    22
Full Otto (The Mushy Gun Milita):    21
Plasmo (The Mushy Gun Milita):    21
Toothpick (The Mushy Gun Milita):    21
Louie the Punk (The Mushy Gun Milita):    0
Wispy (The Mushy Gun Milita):    0

Spot the difference.
Yeah, there's no wounding hits (and the headings are different). More to the point the file that contains the gang data doesn't contain wounding hits. The header file for it doesn't even have a structure for it!
C:
struct _member {
    char *name, *pos;
    int m, ws, bs, s, t, w, i, a, ld;
    char *injuries, *equipment, *skills;
    int cost, exp;
    char *gang_name;
    struct _member *next;
};
It's not that it'd be hard to add it - just that it's not there!

So that makes me feel a bit better about not getting it to work "properly" back in '05. It looks like the examples on the page are based on a more advanced version of The Sumper that he didn't publish. Bit of a shame but no big deal.

The thing that strikes me about all of this is the sheer overkill of it when seen through a modern lens. Not overkill for the time, just compared to how I'd handle things. Let's talk about that for a bit.
Conceptually what Andy did was to design a data structure - a standardised way to record information about Necromunda gangs. He wrote a program that would read in that data. Once the data is in the program operations can be performed on it ("The grammar loads all the gang info into data structures, thus you can write a C rear-end to do whatever you want with it."). You'd have to write the functions yourself but you wouldn't be starting from scratch.

The reason this is a bit of a big deal is because the year was 1996. I'll come back to that in a moment.

If I wanted to write something similar these days I'd probably use something like Python or JavaScript. I'm comfortable in both languages and their syntax is a hell of a lot easier than C. I started learning C a while back but gave up as it seemed like a lot of faff for the sorts of things I want to do - way too low-level for messing about with text data. Python is just fine!

I'd want to store the gang data in a way that'd be easy to read. I'd probably use JSON ("JavaScript Object Notation" - it has JS in the name but it's used in loads of languages as it's a nice format).

That'd look something like this:
JSON:
{
    "Name": "The Mushy Gun Milita",
    "Rating": 1268,
    "Territory": ["Vents", "Tunnels", "Settlement", "Drinking Hole", "Slag"],
    "Stash": 30,
    "Hoard": ["Heavy Stubber", "Your Mama"],
    "Members": [{
            "memberName": "El Feygun",
            "position": "Leader",
            "characteristics": {
                "M": 4,
                "WS": 4,
                "BS": 4,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 8
            },
            "injuries": [],
            "equipment": ["Boltgun", "Massive Axe"],
            "skills": [],
            "cost": 170,
            "experience": 66
        },

        {
            "memberName": "Sumo",
            "position": "Heavy",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 3,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 7
            },
            "injuries": [],
            "equipment": ["Heavy Stubber", "Laspistol"],
            "skills": [],
            "cost": 195,
            "experience": 64
        },

        {
            "memberName": "Full Otto",
            "position": "Ganger",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 3,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 7
            },
            "injuries": [],
            "equipment": ["Autogun", "Stub gun"],
            "skills": [],
            "cost": 80,
            "experience": 21
        },

        {
            "memberName": "Joey the Slug",
            "position": "Ganger",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 3,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 7
            },
            "injuries": [],
            "equipment": ["Shotgun (sld/sctr/mstpr/bolt)", "Stub gun"],
            "skills": [],
            "cost": 100,
            "experience": 23
        },

        {
            "memberName": "Plasmo",
            "position": "Ganger",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 3,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 7
            },
            "injuries": [],
            "equipment": ["Chainsword", "Plasma pistol", "Stub gun"],
            "skills": [],
            "cost": 110,
            "experience": 21
        },

        {
            "memberName": "Toothpick",
            "position": "Ganger",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 3,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 7
            },
            "injuries": [],
            "equipment": ["Bolt pistol", "Stub gun", "Frag grenades"],
            "skills": [],
            "cost": 110,
            "experience": 21
        },

        {
            "memberName": "Sawtooth",
            "position": "Ganger",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 3,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 7
            },
            "injuries": [],
            "equipment": ["Chainsword", "Laspistol"],
            "skills": [],
            "cost": 90,
            "experience": 22
        },

        {
            "memberName": "Louie the Punk",
            "position": "Juve",
            "characteristics": {
                "M": 4,
                "WS": 2,
                "BS": 2,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 6
            },
            "injuries": [],
            "equipment": ["Stub gun", "Maul"],
            "skills": [],
            "cost": 45,
            "experience": 0
        },

        {
            "memberName": "Wispy",
            "position": "Juve",
            "characteristics": {
                "M": 4,
                "WS": 2,
                "BS": 2,
                "S": 3,
                "T": 3,
                "W": 1,
                "I": 3,
                "A": 1,
                "LD": 6
            },
            "injuries": [],
            "equipment": ["Hand flamer", "Stub gun"],
            "skills": [],
            "cost": 55,
            "experience": 0
        },

        {
            "memberName": "Tyco",
            "position": "Scummer",
            "characteristics": {
                "M": 4,
                "WS": 3,
                "BS": 4,
                "S": 3,
                "T": 3,
                "W": 2,
                "I": 4,
                "A": 1,
                "LD": 8
            },
            "injuries": [],
            "equipment": ["Knife", "2 Bolt Pistols"],
            "skills": ["Gunfighter - Quick Draw"],
            "cost": 15,
            "experience": 60
        }
    ]

}
It's fairly human readable and you can see what each thing in it is. If I was designing from scratch I might fiddle around with how skills are handled and things like that but that's nitty-gritty stuff.
With the data laid out like this you could do things like this:
gang.members[0].memberName
That'd give you the first gang member's name. It's easily possible to drill down to whatever bit of information you need with fairly clear code.

So why didn't Andy do something like that?

Well it was April 1996. Easily accessible data structures like JSON simply didn't exist yet!
JavaScript as a language wasn't standardised until 1997 so definitely no JSON (not until the early 2000s). What other options were there?
Well, maybe XML? Nope, not until 1998.
Uh... YAML? Nope. Not until 2001.

There's a few other formats but basically there was nothing around to handle this job! He had to figure it out and write his own! How cool is that!
Similarly Python in principle existed but it wasn't until version 2+ that I heard of anyone using it and that wasn't until 1998. Java existed but had only been released three months earlier.
Ruby? Well that was released onto Japanese news groups in December '95 but 1.0 wasn't until December '96.
C#? 2000.

No wonder Andy wrote it in C - there weren't exactly loads of mature alternatives! (C first saw release in 1972 so it had loads of support by 1996).

In general this has just been a wonderful bit of digital archaeology for me. Figuring out what Andy built, why, how, and how far ahead of his time he was. These days we have amazing tools like YakTribe's Necromunda tool but someone was working on its distant ancestor way back when the game was new!

Thanks for coming with me on this expedition. I hope I can now finally put my curiosity to rest. Then again, he also wrote weapon summaries in PostScript and I know naff-all about that at the time of writing...
 

Space Truckin

Gang Hero
Dec 16, 2015
1,597
3,216
158
Cruz Bay, St. John, USVI
Very cool write up. Have you tried contacting Andy? Just curious.
As far as options back in the day otherwise known as while at uni...i remeber working through pascal, fortran in the 90s and on to c++ etc. Your write up kinda took me back thru memory lane.

Havent been working in programming for 3 years now and kinda missing it.
 
  • Like
Reactions: Flamekebab

Flamekebab

Gang Hero
Gorkamorka Warboss
Feb 17, 2011
1,010
2,168
133
34
Rotherham, UK
fox-box.co.uk
Very cool write up.
Cheers! Writing it was weirdly cathartic.
Have you tried contacting Andy? Just curious.
I haven't - based on the email address supplied I cannot imagine it's still active. I'm not sure how best to track him down. I figured that if he's likely to see it anywhere it'd be here!

As far as options back in the day otherwise known as while at uni...i remeber working through pascal, fortran in the 90s and on to c++ etc.
Sounds like my understanding was about right in that case - that's reassuring. I tried Pascal in about 2004 or so without much luck but I've never looked into Fortran. I took one look at C++ around that time too and noped out. I could probably handle it now but the same problem I had back then sort of still applies - I've no idea what I'd use it for.

Your write up kinda took me back thru memory lane.
Excellent! That's basically what I wrote it for. It was before my time as an adult but it's really interesting looking back and piecing together the how and why of things. Contrasting it with how easy we have it now really brings into sharp focus how far we've come and how quickly. No JSON - eek!

Havent been working in programming for 3 years now and kinda missing it.
I've never worked in programming as a career. I've done it for work (I wrote the invoicing system for Fox Box, for example, and that uses a lot of the same principles as the HTML output that Andy wrote for the roster generator) but I've no idea what it'd be like to do it within a professional structure. I totally get you on missing it though - the problem solving side of it is weirdly satisfying!
 

Space Truckin

Gang Hero
Dec 16, 2015
1,597
3,216
158
Cruz Bay, St. John, USVI
Weirdly satisfying is a good way to out it.
I ended up working w PHP doing plug ins and fixes for Word Press sites. Recovering hacked sites was always fun. Especially going thru the code and trying to figure out what they were up to.
 
  • Like
Reactions: Flamekebab

vt102

New Member
Feb 22, 2016
2
13
3
Farragut, TN, USA
LMFAO, Andy Cowell here...in a bit of nostalgia, I googled Mushy Gun Militia and this came up...you've made my night @Flamekebab .

I was in graduate school at the time, and probably using lex and yacc for reasons of personal interest, rather than anything practical. Or maybe I didn't know better at the time. You gotta remember, though, that back then, there was a good chance that any random user on the Internet understood that stuff...it was a different time.

I think you're correct, though, about the formatting thinking. Today, I would probably use YAML/JSON, but at the time, most "data" files like that were configuration files. Maybe there was something like a standard .INI parser or something, but I just wasn't aware of anything like that...a lot of the thinking, as I recall, was to write parsers for domain specific languages. Still a thing, just appropriately more rare.

Today, I'd write it in Python, too. Much like why I likely used lex/yacc at the time, today I'd probably make it completely serverless on AWS. C will always be my first love, though-- fairly impractical now, but I learned so much with it.

FWIW, I was playing Necromunda (and, before that, 3rd edition Blood Bowl) at the local comic book shop. All my close personal friends, I met through those campaigns/leagues. Though many of us are distributed throughout the USA now, we still get together twice a year to revel and play games. COVID-19 is ruining our summer plans, but now we find ourselves all playing board games every week. It's all pretty awesome, relatively speaking, and I'm very thankful to have had Necromunda and BB back in the day to help me find my friends. I bought the latest base game, painted up a Genestealer Cult, something I always wanted to do...but it's just not the same without the old gang nearby. THAT was the magic part.

Also FWIW, at the time, there was a right wing domestic terrorist group in the news called the Michigan Militia. I took the name from them.
 

vt102

New Member
Feb 22, 2016
2
13
3
Farragut, TN, USA
> ...how far ahead of his time he was

For the record, I played the first game of online Blood Bowl, as far as I'm aware, too. We did letters and numbers on the sides of the pitch, and chatted on IRC, "I'm moving my Gutter Runner from K9 to M10, Dodging to M11..." I wrote an IRC bot to handle all the dice rolling.
 

Flamekebab

Gang Hero
Gorkamorka Warboss
Feb 17, 2011
1,010
2,168
133
34
Rotherham, UK
fox-box.co.uk
LMFAO, Andy Cowell here...in a bit of nostalgia, I googled Mushy Gun Militia and this came up...you've made my night @Flamekebab .
That was way quicker than expected! Also brilliant!

I was in graduate school at the time, and probably using lex and yacc for reasons of personal interest, rather than anything practical. Or maybe I didn't know better at the time. You gotta remember, though, that back then, there was a good chance that any random user on the Internet understood that stuff...it was a different time.
That hadn't occurred to me, now you mention it. I guess I'd assumed that if I was a kid bumbling around in ~'99 then things probably weren't that different - daft assumption, I know.

I think you're correct, though, about the formatting thinking. Today, I would probably use YAML/JSON, but at the time, most "data" files like that were configuration files. Maybe there was something like a standard .INI parser or something, but I just wasn't aware of anything like that...a lot of the thinking, as I recall, was to write parsers for domain specific languages. Still a thing, just appropriately more rare.

Today, I'd write it in Python, too. Much like why I likely used lex/yacc at the time, today I'd probably make it completely serverless on AWS. C will always be my first love, though-- fairly impractical now, but I learned so much with it.
Wow. I got it... right? Validation feels weird. Kinda tingly!

I'm pleased that I don't know what a serverless setup would look like - it means there's plenty more for me to learn. The journey so far has been wonderful - long may it continue.

I think an Arduino workshop I was part of used C so perhaps at some point I'll need to dive in properly. The recent work I've done in Python has been really nice though and I don't relish the notion of something lower level unless really necessary.

FWIW, I was playing Necromunda (and, before that, 3rd edition Blood Bowl) at the local comic book shop. All my close personal friends, I met through those campaigns/leagues. Though many of us are distributed throughout the USA now, we still get together twice a year to revel and play games. COVID-19 is ruining our summer plans, but now we find ourselves all playing board games every week. It's all pretty awesome, relatively speaking, and I'm very thankful to have had Necromunda and BB back in the day to help me find my friends. I bought the latest base game, painted up a Genestealer Cult, something I always wanted to do...but it's just not the same without the old gang nearby. THAT was the magic part.
It sounds amazing. I've played Necromunda campaigns but it's not really the same as being there when it was new and the Underhive was barely explored.


Also FWIW, at the time, there was a right wing domestic terrorist group in the news called the Michigan Militia. I took the name from them.
Ah! It means a lot to me to learn that. Tying up loose ends from my distant past with fresh knowledge makes me smile. Thank you.


> ...how far ahead of his time he was

For the record, I played the first game of online Blood Bowl, as far as I'm aware, too. We did letters and numbers on the sides of the pitch, and chatted on IRC, "I'm moving my Gutter Runner from K9 to M10, Dodging to M11..." I wrote an IRC bot to handle all the dice rolling.
Well now that's just ridiculously awesome! I've always wondered what IRC bots were written in!
 

Malo

YakTribe Mechanicum
Staff member
Yak Founder
Feb 17, 2011
5,465
6,825
233
47
York, PA, USA
yaktribe.games
Wow, came across this thread randomly from searching for something else. What a really cool find and fantastic that the original author is a member here and replied! I love this community.

In 1995 when Necromunda first came out, I built a FileMaker database for our group to store and update our gangs and that was the inspiration for YakTribe when I moved to the US and started playing again. ah nostalgia!