Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
blueinferno776

How do you learn how to build source ports?

Recommended Posts

At the cost of sounding like an old bitter programming dinosaur, I'll reiterate my thoughts about such "programming made easy", "make your own games without being a programmer" etc. environments:

First off, they've been around since forever in some form. There were "platform game construction kits", "3D game makers", even "pinball construction kits" even in the 80s, on 8-bit computers.

In general, such environments are little more than toys, and no sane professional would rely exclusively on them. They are the programming equivalent of building a house with Lego Duplo bricks. Sure, they do have their uses, which is appeasing whoever "wants to make a game by skipping all the hard stuff", occasionally, on a whim, but that's it. Their value as educational tools/stepping stones for something more serious is also questionable, as they don't encourage or teach good programming practices or ways of thinking.

Yes, I know there are actual commercial games made with such tools, some of them pretty good, but almost none of the really good ones that stand out were made just with those tools by people who didn't know anything about programming. In fact, you can (and often need to) interface with external code in order to achieve a more complex effect than the dumbed-down interface allows you, or you need to have some idea of how to program interesting behavior so that your game is not a total copy & paste job. So in the end you do need to be a programmer.

Share this post


Link to post

The worst thing about these kits are the utterly inane scripting 'languages' they often use, of course these are mostly the ones aimed at the clueless newcomers.

I wouldn't say that they are bad per se, but most get disqualified just by not offering any decent programming capabilities which are indispensable even for simple games.

For a game like Doom such a kit is the epitome of stupidity, if you ask me. The entire game's internal design is so ill-suited to how these frameworks operate that the end result will be inevitably underwhelming.

Share this post


Link to post
Maes said:

At the cost of sounding like an old bitter programming dinosaur, I'll reiterate my thoughts about such "programming made easy", "make your own games without being a programmer" etc. environments:

Blitz3D requires a lot of programming knowledge, although i have no idea if it's close in any way to the known programming languages such as c++ ... etc , And it's by the way not only intended for games .

Share this post


Link to post
DMGUYDZ64 said:

Blitz3D requires a lot of programming knowledge


Actually, ALL those "make your own games" kits do, to various extents. Some may be dumbed down enough to lower the bar even for completely illiterate (in the programming sense) people, but in order to reach commercial-quality levels with any of them, one has to let the helper wheels/crutches/casts go and delve knee-deep (heh) into the Code.

Now, many claim "no programming knowledge needed", and for certain kinds of games that can created by copying + pasting ready-made resources + prefabs or even modifying a template, that might be true. Not exactly misleading advertising, just some good ol' marketing department bullshittin'/not telling the whole truth ;-)

DMGUYDZ64 said:

although i have no idea if it's close in any way to the known programming languages such as c++


Blitz3D in particular uses its own dialect of (gasp) BASIC, which is ultimately compiled too...wait for it....

Spoiler

C++

So, once again, as soon as someone realizes that his "bike" can run and corner faster without those helper wheels....

Share this post


Link to post

BlitzBasic is using a Basic dialect and it has its own libraries for video, audio etc.

I think it is very much different from using C++ and a library like SDL. For simple 2D applications, it should be easier to get started.

But a Doom-like engine? Errrrm, not so sure hehe. Also, it's not really free, so...

Share this post


Link to post
DMGUYDZ64 said:

Working with B3D is a bad idea unless i'm wrong, any Game based on it can't be ported to multiple platforms .

Oh yeah that's true.
Its really that guy's choice on what to use.
B3D is easier, but C, C++ and etc are more durable right?

Share this post


Link to post
Voros said:

Oh yeah that's true.
Its really that guy's choice on what to use.
B3D is easier, but C, C++ and etc are more durable right?

Yeah, i've been taking few lessons on them last weeks, they're very similar to the BlitzBasic .

Share this post


Link to post

If one is doing this for a potential career path and such, the eventual languages you may be primarily programming in are:

  • C
  • C++
  • C#
  • Java
  • Javascript
  • Python
  • Ruby

Share this post


Link to post

Graf: I was able to build gzdoom no problem on Ubuntu. I forgot how it was able to take care of those dependencys, it would tell me what was missing then it would give me the commands on the termenal to get them which was awsome.

When it comes to windows for compiling anything on it I am dumb as a bag of hammers. I missed the instuctions somehow, it's probably going to be facepalm territory when I do find them.

I find it more fun to compile gzdoom and run it versus unzipping the binarys.

Share this post


Link to post
GhostlyDeath said:

If one is doing this for a potential career path and such, the eventual languages you may be primarily programming in are:

  • C
  • C++
  • C#
  • Java
  • Javascript
  • Python
  • Ruby



You forgot Objective-C and Swift, which are indispensable if the name 'Apple' appears somewhere in the tasks that may need to be done. :P

Share this post


Link to post

You might want to add Fortran and Matlab to this list, if you're going to do simulations/engineering/scientific programming, though I admit they are somewhat more specialized and imply, at least partially, an academic career path.

Now, a FORTRAN port of Doom would be wicked...

Share this post


Link to post
Maes said:

You might want to add Fortran and Matlab to this list, if you're going to do simulations/engineering/scientific programming, though I admit they are somewhat more specialized and imply, at least partially, an academic career path.

Now, a FORTRAN port of Doom would be wicked...


A Forth Port (pun intended) would be much better!

Share this post


Link to post

Learn programming by modifying an existing program that works. That allows to you test your attempts in small increments. Otherwise it will be two years before you have anything that executes.

I cannot recommend C++ for learning programming. It requires an understanding of object oriented ideas on top of everything else.
C is a horrible language, but C++ kept the worst parts of C and fixed it up with some object oriented concepts. C++ did improve some things, but not enough.

I would recommend going back to one of the C ports of Doom, like PrBoom.
PrBoom will run FreeDoom and most Doom games and PWADS.
It will run under Linux, and compiles easily.
It has some C programming tricks, but most of it can be figured out.

The ports that I would recommend trying, that compile easily enough on Linux,
are PrBoom-2.5 (or PrBoom+), DoomLegacy, Edge (or 3DGE), and Eternity-Engine.

If you want something more advanced than PrBoom, and am willing to work under Linux, then try DoomLegacy 1.45. It has a makefile (and some CMake files) (I use the makefiles).
It is still C code, has lots of comments, and I have removed
many of the complicated C tricks in favor of easier to maintain, simple code.
It has extensive docs that explain what the user interface is supposed to be,
so you do not have to guess at it. It has 3dfloors, which complicates most of the drawing routines, making it much larger than PrBoom.

If you want to work with Windows then get a source port that is native to Windows.
That part is too hard to create without having access to lots of Windows documentation and experience.

The ZDoom code is complicated. Having looked at the ZDoom ports, I found it extensively uses C++ object programming and indirection. I have rarely found the code for any particular Doom operation, and that makes it very difficult
to learn basics from.

I still have a "Pinball construction" program somewhere in one of these boxes.
Those kind of programs are like a Widget kit with a visual interface. You can
only put the widgets together.

Share this post


Link to post

Sorry, wesleyjohnson, but this time I cannot let your ill-informed stuff stand. It's clear that your dislike for C++ and ZDoom clouds your judgment quite a bit.

So first: C++ does not automatically mean 'object oriented'.
Furthermore 'object oriented' doesn't automatically mean 'bad'.
C does not automatically mean 'simple'. In fact I believe that C - even moreso than C++ is an unsuitable language for learning programming, for that I'd recommend C# - unfortunately there's no Doom port using it.

And the fact that *YOU* have difficulties with C++ doesn't say anything about ZDoom's code - but it just reaffirms some severe case of tunnel vision.

And last but not least a warning to anyone in the learning phase: Stay the hell away of Doom Legacy! That source has been mishandled for 17 years and should be avoided at all costs!

Share this post


Link to post
Graf Zahl said:

for that I'd recommend C#


I would recommend Java 8 and up.

Graf Zahl said:

unfortunately there's no Doom port using it.


There was this https://www.doomworld.com/vb/post/608577. But I assume it was never completed. I do have this C# Doom source code lying around but since I cannot compile or run it I do not know how Doom it is.

Graf Zahl said:

And last but not least a warning to anyone in the learning phase: Stay the hell away of Doom Legacy! That source has been mishandled for 17 years and should be avoided at all costs!


Seeing that my port is based off Doom Legacy, what about me? I should note that I am in the process of porting my existing ReMooD code into pure Java code (most un-C-like) so essentially everything is being rewritten as it is ported over, using object orientation (no factories since they are ugly when they are usually not needed). In the end, the result will be that the C nature of Doom will be eradicated.

I should add that I have been programming C for about 15 years and Java for 10, so not exactly a newbie.

Doom Legacy has lots of programming oversights and is very crash heavy, just fixing those crashes in C ReMooD caused much slowdown because lots of bounds checking had to be done. For example, 3D floors render past the screen which means you can corrupt the game state (or more likely crash) if you looked at a 3D floor the wrong way. So once Java ReMooD is complete, it will be a completely fixed Doom Legacy compatible port. The only sad thing is the lack of DOS and Windows 98 support, but there are probably some hacks and such one can do to run newer Java on ancient systems.

If I had a time machine and could go back in time to tell myself something, I would not tell myself to not use Doom Legacy because since it was bug prone I learned lots of C, debugging, and bug fixing. If it were not for Doom Legacy I would probably be a horrible coder today.

Share this post


Link to post
GhostlyDeath said:

I would recommend Java 8 and up.


My main issue with Java - and its impact on newbie programmers - is that it has no value semantics for structs and classes.
This can lead to hideously inefficient coding if it needs to get worked around. And once people have learned this strategy there's little chance they get cured again. These people will write bad code for every language afterward. Been there, seen that when Java coders come fresh from school or university. C# coders generally are better suited.

Seeing that my port is based off Doom Legacy, what about me?


Well, to be honest - the last ReMooD version I checked out had its share of problems, most notably the broken menu replacement. I haven't followed development since then because the port is outside my field of interest.

Doom Legacy has lots of programming oversights and is very crash heavy, just fixing those crashes in C ReMooD caused much slowdown because lots of bounds checking had to be done. For example, 3D floors render past the screen which means you can corrupt the game state (or more likely crash) if you looked at a 3D floor the wrong way.


Yeah, stuff like that everywhere is my main issue with the original Legacy code base. Add to that some extremely questionable changes to gameplay behavior that really can affect the playability of some maps.

So once Java ReMooD is complete, it will be a completely fixed Doom Legacy compatible port. The only sad thing is the lack of DOS and Windows 98 support, but there are probably some hacks and such one can do to run newer Java on ancient systems.


Why Java? It's sad enough I need the runtime for Android development but I avoid using Java apps like the plague. They normally get deleted on sight after download... :D

If I had a time machine and could go back in time to tell myself something, I would not tell myself to not use Doom Legacy because since it was bug prone I learned lots of C, debugging, and bug fixing. If it were not for Doom Legacy I would probably be a horrible coder today.


Well, I learned my lesson early enough.
Back in 2000 when I started with Doom coding the first port I used was PrBoom which I slowly turned into my own engine by replacing the renderer piece by piece with my own code - that's what ultimately became GZDoom. But when I became interested in more advanced features, Legacy with its 3D floors was the first choice (since ZDoom back in the day was just as buggy and far more complex to support) But I quickly noticed how broken parts of the engine were so I had to undo lots of it again. Another complication was that the Allegro library it used back then was creating some serious issues with screwing up my system configuration.
That's when I turned to ZDoom, where I quickly started to see that all those bugs got fixed (Randy was far, far more receptive to bug reports than the Legacy team which ultimately got hung up on the failed 2.0 version) - and I never looked back. Legacy was just bad memories in the end.

Share this post


Link to post
Graf Zahl said:

My main issue with Java - and its impact on newbie programmers - is that it has no value semantics for structs and classes.
This can lead to hideously inefficient coding if it needs to get worked around. And once people have learned this strategy there's little chance they get cured again. These people will write bad code for every language afterward. Been there, seen that when Java coders come fresh from school or university. C# coders generally are better suited.


Well, for Java 7 and before I would agree with you but Java 8 had some game changers which gave enough incentive for me to port ReMooD to Java. So basically Java became good enough of a language for Doom about a year ago (March 8, 2014). The main features of Java 8 are lambdas which are very useful.

Lambdas are basically:

List<Foo> somelist = getMeAList();
somelist.forEach((__v) ->
  {
    System.out.println("Looking at bar " + __v);
    if (__v.isBar())
       System.out.printf("The bar is at %d rods.%n", __v.getRods());
  });
But you can also use something called method references:
List<Foo> somelist = getMeAList();
somelist.forEach(this::printRods);

// Somewhere later on...
public void printRods(Foo __v)
{
  System.out.println("Looking at bar " + __v);
  if (__v.isBar())
    System.out.printf("The bar is at %d rods.%n", __v.getRods());
}
Since Java 7 there exists something called "invokedynamic" which is a dynamic call site. The closest C representation would be a function pointer. The previously described lambda expressions use invokedynamic.

So the code examples above effectively compile to (in C, assuming a struct layout and ignoring garbage collection):
List somelist = getMeAList();
List_forEach(somelist, &printRods); // forEach(void (*__func)(List, Foo));

void List_forEach(List __qq, void (*__func)(List, Foo))
{
  int i;
  int n = Collection_size(__qq);

  for (i = 0; i < n; i++)
    __func(__qq, Collection_get(__qq, i));
}

void printRods(List __qq, Foo __v)
{
  PrintStream_println(System.out, primitive_add("Looking at bar ", Object_toString(__v)));
  if (Foo_isBar(__v) != 0)
    PrintStream_printf(System.out, "The bar is at %d rods.%n", primitive_arraynew(1, Foo_getRods(__v)));
}
Note that C and Java are different beasts so this is a quick 1:1 translation ignoring a bunch of things.

This allows the JVM to essentially inline function pointers (if it has the ability) or do other fun things. It can also cache the call site so essentially there is only a single allocation done for it. So it is much faster and more memory efficient than the old way of doing such a thing:
List<Foo> somelist = getMeAList();
somelist.forEach(new BiConsumer<List, Foo>()
  {
      @Override
      public void accept(List __from, Foo __v)
     {
      System.out.println("Looking at bar " + __v);
      if (__v.isBar())
        System.out.printf("The bar is at %d rods.%n", __v.getRods());
      }
  });
I suppose you can think of invokedynamic as a function pointer in C/C++ which can overwrite itself after it is called the first time.

Java 8 also adds some more stuff to the class library which has some useful functions.

There has been talk eventually of adding value types (structs) to Java in the future, might appear in Java 10 if they decide to vote for it.

As for Java, I personally like the very defined nature of it. No need to worry about whether integer overflow throws exceptions, or non-2's complement number systems, variadic argument stack corruption/values going missing, etc.

When it comes to schools, it is bad when they are out of date. There are schools out there today that still teach i286 assembly when they could be teaching MIPS as a start (due to its simplicity).

On an unrelated note, this forum really needs a monospaced text box.

Graf Zahl said:

Well, to be honest - the last ReMooD version I checked out had its share of problems, most notably the broken menu replacement. I haven't followed development since then because the port is outside my field of interest.


Well yes, ReMooD 0.8a is a bit ugly. The menus in ReMooD have constantly been changing because I just could not find a good way to do it. One thing I do not want is to end up with is PrBoom menus. Another thing is, I prefer to have most of the functionality available in game rather than for example with a launcher so it must be more complex in general.

Graf Zahl said:

Yeah, stuff like that everywhere is my main issue with the original Legacy code base. Add to that some extremely questionable changes to gameplay behavior that really can affect the playability of some maps.


This is mostly the reason why some stuff got stripped out completely such as hardware rendering support (that was a horrible mess). Heretic was fine but when ReMooD was around Heretic was not GPLed so it was illegal to have in there so that had to go too.

Although the C code is a bit ugly in ReMooD, to support Vanilla and previous Doom Legacy demos I have quite a bunch of game variables. While others are things I have added. The majority however are for compatibility purposes.

Graf Zahl said:

Why Java? It's sad enough I need the runtime for Android development but I avoid using Java apps like the plague. They normally get deleted on sight after download... :D


Read above. Also, Google's "Java" (the one that Android uses) is crippled and broken compared to the standard edition. It is also out of date and missing a bunch of things to the point where people end up just reimplementing stuff that would have been in the standard library. Going from Java 8 to Android depending on what you use can end up being a port of ZDoom to MSVC 6. You can ask Quasar about how much he loves MSVC 6 and when I worked with Odamex when it was required to support it, was hell. So think of when you are programming for Android that you are coding ZDoom on MSVC 6.

However, if you happen to love MSVC 6 and ZDoom compiles/works in it, then you can s/MSVC 6/Turbo C++/g.

So in short, there will most likely not be an Android ReMooD port until Google gets out of the stone age.

Graf Zahl said:

Well, I learned my lesson early enough.
Back in 2000 when I started with Doom coding the first port I used was PrBoom which I slowly turned into my own engine by replacing the renderer piece by piece with my own code - that's what ultimately became GZDoom. But when I became interested in more advanced features, Legacy with its 3D floors was the first choice (since ZDoom back in the day was just as buggy and far more complex to support) But I quickly noticed how broken parts of the engine were so I had to undo lots of it again. Another complication was that the Allegro library it used back then was creating some serious issues with screwing up my system configuration.


For C ReMooD, I ended up completely rewriting the interface code so the end result is that using stuff such as SDL or Allegro actually works better.

ReMooD was originally Linux Doom 1.10 ported to Windows, except I switched to Legacy for that nostalgic reason. Also when I started ReMooD, Doom Legacy was dead code wise but not community wise. The worst thing to happen to Doom Legacy recently was NewDoom going splat by a crazy sysadmin.

Graf Zahl said:

That's when I turned to ZDoom, where I quickly started to see that all those bugs got fixed (Randy was far, far more receptive to bug reports than the Legacy team which ultimately got hung up on the failed 2.0 version) - and I never looked back. Legacy was just bad memories in the end.


The problem with Legacy was that it mostly added too much too fast with not much refactoring going on.

Share this post


Link to post
GhostlyDeath said:

Read above. Also, Google's "Java" (the one that Android uses) is crippled and broken compared to the standard edition. It is also out of date and missing a bunch of things to the point where people end up just reimplementing stuff that would have been in the standard library.


That may well be - but I do not program Android in Java - I only do native cross-platform development. I only need Java so that I can get the stuff compiled and deployed.

GhostlyDeath said:

Going from Java 8 to Android depending on what you use can end up being a port of ZDoom to MSVC 6. You can ask Quasar about how much he loves MSVC 6 and when I worked with Odamex when it was required to support it, was hell. So think of when you are programming for Android that you are coding ZDoom on MSVC 6.

However, if you happen to love MSVC 6 and ZDoom compiles/works in it, then you can s/MSVC 6/Turbo C++/g.


I think that MSVC 6 is one utterly shitty compiler. Fortunately it bears little to no relevance these days. But it doesn't really stop there.
Due to the insane needs of the Doom community (e.g. Win98 support) ZDoom got stuck with Visual Studio 2005 as minimum required platform, meaning no C++11 features. I guess this is pretty much the same situation as Java 7 vs. Java 8.

GhostlyDeath said:

So in short, there will most likely not be an Android ReMooD port until Google gets out of the stone age.


I'd rather see them ditch their misguided Java effort for a sane native interface on which some other high level stuff can be built. But for that I've given up hope.

GhostlyDeath said:

The problem with Legacy was that it mostly added too much too fast with not much refactoring going on.


They not only added too much too fast - it was just as bad that much of what they added wasn't done properly. For example, nearly all the Boom stuff that got added to the engine was just slapped on - while leaving out some fundamental low level support code.

Share this post


Link to post
Graf Zahl said:

I think that MSVC 6 is one utterly shitty compiler. Fortunately it bears little to no relevance these days. But it doesn't really stop there.
Due to the insane needs of the Doom community (e.g. Win98 support) ZDoom got stuck with Visual Studio 2005 as minimum required platform, meaning no C++11 features. I guess this is pretty much the same situation as Java 7 vs. Java 8.


You know even Chocolate Doom dropped Windows 98 support and that is the most conservative port. There is KernelEx however, except Java 8 does not work on it because a bunch of stuff in it relies on a bunch of fancy new NT stuff. However, one could always leverage something such as LLVM to recompile Java/C/C++ into C that would work with Windows 98 for example. Modern programs these days should be fine since executable memory is now read-only so self modifying code is very rare now (except in virtualization, OS kernels, embedded stuff such as Arduinos, etc.). One could even probably statically recompile executables to run on older systems or have some kind of dynamic recompiler emulator.

There is ReactOS though, although it is more Windows Server 2003 (the server version of Windows XP). It is still in alpha development however.

Graf Zahl said:

They not only added too much too fast - it was just as bad that much of what they added wasn't done properly. For example, nearly all the Boom stuff that got added to the engine was just slapped on - while leaving out some fundamental low level support code.


Despite its flaws, Doom Legacy did have some innovations however and had a bunch of firsts.

Share this post


Link to post
GhostlyDeath said:

Despite its flaws, Doom Legacy did have some innovations however and had a bunch of firsts.



That it definitely had, too bad that it got so overshadowed by the problems...

Share this post


Link to post
GhostlyDeath said:

one could always leverage something such as LLVM to recompile Java/C/C++ into C that would work with Windows 98 for example


Doesn't LLVM rely on GCJ to begin with? And isn't that pretty much stuck at Java 5 or 6 features? Even if it's not, I'd be surprised if either kept up with newfangled devilries such as Lambdas or functional programming, that are hard to implement with statically compiled languages to begin with.

Finally, no matter what syntactic sugar or mathematical abstractions the higher level language provides...in the end the machine understands only basic math operations, BRANCH/IF, JMP/GOTO and CALL/GOSUB instructions :-)

Share this post


Link to post
Maes said:

Doesn't LLVM rely on GCJ to begin with? And isn't that pretty much stuck at Java 5 or 6 features? Even if it's not, I'd be surprised if either kept up with newfangled devilries such as Lambdas or functional programming, that are hard to implement with statically compiled languages to begin with.


Well - Objective-C got Lambda equivalents - C++ also has them - the problem has been solved already.

Share this post


Link to post

For a new learner, the typical C++ manual will try to have you doing everything objected oriented. That has little relevance to the Doom C code, and will only confuse. The terms are different, the program organization is different. It is not that you cannot use C++ to do structured programming instead of object oriented programming, it is that the tutorials you find are so hung up on object oriented programming they cannot teach basics anymore.

I really get tired of GZ attempts to denigrate other people and their work based on false information that he just makes up on the fly. Some hate trip based on stuff from years ago, a different team, and I am included in this hate trip by association with DoomLegacy.

None of this has anything to do with the poster's question.

I use DoomLegacy on Linux every few days, and it does not crash, nor behave anything like what these false descriptions would have you believe. His information is obsolete (by several years it seems), and has little relevance to the DoomLegacy v145.2. And like I said, if you want to use Windows, get a port developed on and for Windows.

And GZ obviously knows nothing of me or my experience level in this regards, just a pretense and a tactical insult. His posts are not complete unless he insults a few people, or a whole project.

Share this post


Link to post

I love lambdas :V

   gNoctScreens.forEachOfType<NoctScreen>([] (NoctScreen *r) {
      r->getTexture().abandonTexture();
   });

Share this post


Link to post
Maes said:

Doesn't LLVM rely on GCJ to begin with? And isn't that pretty much stuck at Java 5 or 6 features?


GCJ is at Java 5 level, however it calls itself Java 6 despite missing a bunch of things.

Share this post


Link to post
GhostlyDeath said:

  • Python


You think I may code a Python Doom source port with full Python addon support (including Python Bots)?

Share this post


Link to post
Gustavo6046 said:

You think I may code a Python Doom source port with full Python addon support (including Python Bots)?


Yes, nothing is stopping you from doing such a thing. Unless of course you lack a text editor, a python script executor, or a computer.

You could call it GustyDoom

Gustavo Python Doom.

Share this post


Link to post
wesleyjohnson said:

And GZ obviously knows nothing of me or my experience level in this regards, just a pretense and a tactical insult. His posts are not complete unless he insults a few people, or a whole project.


Look in the mirror for once and ask yourself why you are getting ridiculed!

Note that I do not do that with other developers because all of them seem to be approachable with feedback and act on it - in the 13 years I've been here you have been the ONLY source port maintainer who flat out ignored all of it - not just from me but from all Windows users!

You even ignored the source I posted that was supposed to help fix the Windows build!

And now tell me: Why should people listen to you, if you won't even fix your own product when someone gives you all the information you needed to get it fixed???

Share this post


Link to post

TL; DR version: to learn to build source ports you have to go through exactly the same drudgery, bullying, pain, tears, insults, sleepless nights, neverending Holy Wars between other schools of thoughts, bitter Flame Wars with "rival" programmers, tackling a lot of"classical" Cans Of Worms, putting up with shitty attitudes etc. etc. that every other programmer worthy of that name want through before you. Class dismissed.

Share this post


Link to post

Graf, you've been acting extra shitty lately. If you feel the need to savage wesleyjohnson and his work please limit it to your own forum and don't bring it here.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×