Our new Indie Games subforum is now open for business in G&T. Go and check it out, you might land a code for a free game. If you're developing an indie game and want to post about it, follow these directions. If you don't, he'll break your legs! Hahaha! Seriously though.
Our rules have been updated and given their own forum. Go and look at them! They are nice, and there may be new ones that you didn't know about! Hooray for rules! Hooray for The System! Hooray for Conforming!

PA Programming Thread - The Best Servers Are The Ones You Don't Use

15758596062

Posts

  • DekabalDekabal Registered User
    edited March 2011
    Thanks for the help, i'm going to work on seperating our the JFrame stuff before I continue. As for the random stats, i'm planning on implementing a save system if found in a tutorial. One thing I do still need help understanding is how to implement other classes. I know the basic idea of polymorphism but how do you implement whole classes, or do you just implement a certian part of one? I really need some explanation on how that works.

  • DrunkMcDrunkMc Registered User regular
    edited March 2011
    Dekabal wrote: »
    Thanks for the help, i'm going to work on seperating our the JFrame stuff before I continue. As for the random stats, i'm planning on implementing a save system if found in a tutorial. One thing I do still need help understanding is how to implement other classes. I know the basic idea of polymorphism but how do you implement whole classes, or do you just implement a certian part of one? I really need some explanation on how that works.

    Just think, what does every type of character you are making have in common. Let's say, Health and name.
    (Doing from memory, so don't shout too much about syntax errors)
    Spoiling Code Blocks
    Spoiler:
    Now your Mage has Health, a Name and Mana, and can get them all despite not re-writing the getHealth and getNames.

    If you have a Rogue who has energy you'd dot he same thing with Energy instead of mana. If you have a BattleMage who also has a Rage stat, you can extend Mage and add Rage.

    Quick Note on Polymorphism, you can extend only ONE class. So if you are making a MageRogue, you can't say ....extends Mage,Rogue. You'd have to extend either Mage or Rogue, and add the other stats to that.

    That's the basics of creating a basic class then extending it in different ways. Hope that helps you get started!

  • DekabalDekabal Registered User
    edited March 2011
    DrunkMc wrote: »
    Dekabal wrote: »
    Thanks for the help, i'm going to work on seperating our the JFrame stuff before I continue. As for the random stats, i'm planning on implementing a save system if found in a tutorial. One thing I do still need help understanding is how to implement other classes. I know the basic idea of polymorphism but how do you implement whole classes, or do you just implement a certian part of one? I really need some explanation on how that works.

    Just think, what does every type of character you are making have in common. Let's say, Health and name.
    (Doing from memory, so don't shout too much about syntax errors)
    Spoiling Code Blocks
    Spoiler:
    Now your Mage has Health, a Name and Mana, and can get them all despite not re-writing the getHealth and getNames.

    If you have a Rogue who has energy you'd dot he same thing with Energy instead of mana. If you have a BattleMage who also has a Rage stat, you can extend Mage and add Rage.

    Quick Note on Polymorphism, you can extend only ONE class. So if you are making a MageRogue, you can't say ....extends Mage,Rogue. You'd have to extend either Mage or Rogue, and add the other stats to that.

    That's the basics of creating a basic class then extending it in different ways. Hope that helps you get started!

    So you would set those classes to to take a string and int and return them. Then in your main class, for me it would be a text area, you would call up those classes to display what was put in, like name = Adventurer.getName() or would it be name = Adventurer(name)? Also, how would that work for an action listener. I have my fight button in my code and I want the action listener to call up a class that will display battle text in a text area (eventually I would like to make it a separate window). BTW your explanation was very good.

  • KakodaimonosKakodaimonos Registered User regular
    edited March 2011
    seabass wrote: »
    Is there a book of best practices for game programming somewhere, or an online tutorial? A couple of friends and I are working on a 2d shooter in our spare time (in OCaml), and we're running headlong into a lot of questions that have to have been answered in the past. Working on things like collision detection, loading in level geometry, making that match up with the background, and so on feels like we're re-inventing the wheel constantly, and it would be nice to know if we've taken a good approach or not.

    Are you particularly attached to OCaml? And what platform is this on? Linux or Windows?

  • IcemopperIcemopper Registered User regular
    edited March 2011
    I've got a couple C questions:

    I'm assuming for the time being that home() is always called home() and not something like start() or lookatme() or whatever else I want to call it?

    And what is up with return0 on the print command? Why isn't it return 1 for true like everything else seems to be?

    steam_sig.png PSN:Icemopper
  • ASimPersonASimPerson And they will tremble again at the sound of our silence!Registered User regular
    edited March 2011
    Icemopper wrote: »
    I've got a couple C questions:

    I'm assuming for the time being that home() is always called home() and not something like start() or lookatme() or whatever else I want to call it?

    And what is up with return0 on the print command? Why isn't it return 1 for true like everything else seems to be?

    home()?

    You mean main()?

    Also, the normal convention for error returns in C is 0 on success and non-zero on failure. Though printf() actually returns the number of characters it printed and a negative value if it fails. Anyway, 0 on success makes sense if you think about it, because then your error cases look like:
    if (func()) {
        // handle error 
    }
    // otherwise proceed normally
    

    I.e., you only need to do anything special if something bad happens. If you want to branch on success, just stick a ! in front of it.

    As a side note, while you should generally always check return values, printf() is generally taken for granted. (Note, though, always check returns from malloc().)

    redoctober2.png
    SE++ Forum Battle Archive | PST = Pacific Standard Time | DRUNKSTUCK: A Homestuck recap
  • IcemopperIcemopper Registered User regular
    edited March 2011
    Ah main! I knew I shouldn't post without consulting the book in the morning. That's what I get for reading late at night. Ah well, it is a learning process.

    And that makes sense, thanks for explaining. I guess the guide I'm using could be better in the area of explaining, but the internet (and you folks) vastly make up for any lacking areas.

    Thanks!

    steam_sig.png PSN:Icemopper
  • seabassseabass Doctor MassachusettsRegistered User regular
    edited March 2011
    seabass wrote: »
    Is there a book of best practices for game programming somewhere, or an online tutorial? A couple of friends and I are working on a 2d shooter in our spare time (in OCaml), and we're running headlong into a lot of questions that have to have been answered in the past. Working on things like collision detection, loading in level geometry, making that match up with the background, and so on feels like we're re-inventing the wheel constantly, and it would be nice to know if we've taken a good approach or not.

    Are you particularly attached to OCaml? And what platform is this on? Linux or Windows?

    Well, we all know Ocaml pretty well. We thought about learning Go for kicks or moving over to C++ to get better library support. Right now our stuff builds on anything nix-ish, and you can get it to build under windows with a little elbow grease. The development is mostly happening under linux and OS X though.

    Right now the biggest issue has been the libraries. OCaml has opengl and sdl libraries, but they're pretty dated.

    Run you pigeons, it's Robert Frost!
  • DrunkMcDrunkMc Registered User regular
    edited March 2011
    QUOTE TREE SNIP!!
    Dekabal wrote: »
    So you would set those classes to to take a string and int and return them. Then in your main class, for me it would be a text area, you would call up those classes to display what was put in, like name = Adventurer.getName() or would it be name = Adventurer(name)? Also, how would that work for an action listener. I have my fight button in my code and I want the action listener to call up a class that will display battle text in a text area (eventually I would like to make it a separate window). BTW your explanation was very good.

    Spoiling wall of text and code.
    Spoiler:

    Also note, and this goes for any new GUI developers out there, do NOT be afraid to tear down your GUI and start over 1,001 times. you learn as you go and things you did in the beginning you realize you can do better, so do it! I've learned GUIs by constantly redesigning and working things that are "done", just because I know I can do it better. Eventually you will be happy with what you have, and despite being able to do better, it's not really worth it. That's when I'm happy!

  • bowenbowen Registered User regular
    edited March 2011
    Okay so multi-thread access of variables in QT.

    Let's say I have a QList I allocate in one thread, and add to it. When I try to access it in another thread I get runtime errors. Is there a specific procedure I have to call before I can add/modify/read the QList members without getting a runtime error? I have a mutex but it's not through QT, it's just a bool. I guess this is not enough and I need to do something through QT, but what? Is what I'm doing even possible? I'd hope so. I remember seeing something about moving a variable between threads with a function call.

  • templewulftemplewulf Registered User regular
    edited March 2011
    ASimPerson wrote: »
    Icemopper wrote: »
    I've got a couple C questions:

    I'm assuming for the time being that home() is always called home() and not something like start() or lookatme() or whatever else I want to call it?

    And what is up with return0 on the print command? Why isn't it return 1 for true like everything else seems to be?

    home()?

    You mean main()?

    Also, the normal convention for error returns in C is 0 on success and non-zero on failure. Though printf() actually returns the number of characters it printed and a negative value if it fails. Anyway, 0 on success makes sense if you think about it, because then your error cases look like:
    if (func()) {
        // handle error 
    }
    // otherwise proceed normally
    

    I.e., you only need to do anything special if something bad happens. If you want to branch on success, just stick a ! in front of it.

    As a side note, while you should generally always check return values, printf() is generally taken for granted. (Note, though, always check returns from malloc().)

    ASimPerson is absolutely right, but I just want to say that I hate C-style error handling. I prefer the C++ style, in which the handling of errors is separated out from return values.
    Spoiler:

    Edit:
    @Icemopper: I forget, are you working in C++, or are you sticking to straight C?

    Friend me: Twitter | Google+
    Invite me: XBox Live | PS3 | Steam
    Link to me: Number Sorter | Achievement Generator
  • InfidelInfidel Heretic Registered User regular
    edited March 2011
    bowen wrote: »
    Okay so multi-thread access of variables in QT.

    Let's say I have a QList I allocate in one thread, and add to it. When I try to access it in another thread I get runtime errors. Is there a specific procedure I have to call before I can add/modify/read the QList members without getting a runtime error? I have a mutex but it's not through QT, it's just a bool. I guess this is not enough and I need to do something through QT, but what? Is what I'm doing even possible? I'd hope so. I remember seeing something about moving a variable between threads with a function call.

    I don't believe there is any built-in thread safety for QList. (that you can enable/take advantage of easily I mean)

    You want to either wrap it in your own thread-safe class (by adding mutex locks on your calls before performing the operation on the internal QList) or come up with a method of passing data using signals and slots.

    TwitchTV channel: OrokosPA OrokosPA
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • bowenbowen Registered User regular
    edited March 2011
    Infidel wrote: »
    bowen wrote: »
    Okay so multi-thread access of variables in QT.

    Let's say I have a QList I allocate in one thread, and add to it. When I try to access it in another thread I get runtime errors. Is there a specific procedure I have to call before I can add/modify/read the QList members without getting a runtime error? I have a mutex but it's not through QT, it's just a bool. I guess this is not enough and I need to do something through QT, but what? Is what I'm doing even possible? I'd hope so. I remember seeing something about moving a variable between threads with a function call.

    I don't believe there is any built-in thread safety for QList. (that you can enable/take advantage of easily I mean)

    You want to either wrap it in your own thread-safe class (by adding mutex locks on your calls before performing the operation on the internal QList) or come up with a method of passing data using signals and slots.

    Hmm I have gone the mutex route for now, however, I still get the runtime errors. I don't have the code with me as I was working on it at home, but I'll go over the mutex again. For all I know I probably just put the mutex on the inserting portion rather than dataready portion. Thanks infidel.

  • InfidelInfidel Heretic Registered User regular
    edited March 2011
    bowen wrote: »
    Infidel wrote: »
    bowen wrote: »
    Okay so multi-thread access of variables in QT.

    Let's say I have a QList I allocate in one thread, and add to it. When I try to access it in another thread I get runtime errors. Is there a specific procedure I have to call before I can add/modify/read the QList members without getting a runtime error? I have a mutex but it's not through QT, it's just a bool. I guess this is not enough and I need to do something through QT, but what? Is what I'm doing even possible? I'd hope so. I remember seeing something about moving a variable between threads with a function call.

    I don't believe there is any built-in thread safety for QList. (that you can enable/take advantage of easily I mean)

    You want to either wrap it in your own thread-safe class (by adding mutex locks on your calls before performing the operation on the internal QList) or come up with a method of passing data using signals and slots.

    Hmm I have gone the mutex route for now, however, I still get the runtime errors. I don't have the code with me as I was working on it at home, but I'll go over the mutex again. For all I know I probably just put the mutex on the inserting portion rather than dataready portion. Thanks infidel.

    If you're rolling your own thread code for accessing the QList, I suggest the wrapper pattern to make it much easier to code and maintain and avoid "oh I accessed it wrong in this function woooops." :) QListTS or something and expose the methods you're using with a QMutexLocker.

    TwitchTV channel: OrokosPA OrokosPA
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • bowenbowen Registered User regular
    edited March 2011
    Once I get the basic mutex working I'll probably end up switching it to slot/signal anyways for cleaner code. The only reason I'm not is because my Java/.NET code use threading in conjunction with events. Mainly because the Java and .NET still use the low level approach to the networking library and don't really have events in it, last I checked.

  • EtheaEthea Registered User regular
    edited March 2011
    This is a good place to start reading for QObjects and QThreads: http://doc.qt.nokia.com/latest/threads-qobject.html

  • bowenbowen Registered User regular
    edited March 2011
    That's what I was looking for ethea. I couldn't find that page again. I think I know what is the problem now. Thanks to both of you.

  • EvilMonkeyEvilMonkey Registered User regular
    edited March 2011
    Jasconius wrote: »
    textmate also costs money


    most things in fact cost money

    Which is lame.

    Unless, of course, I am receiving some of that money. Then it suddenly becomes acceptable, even great.

    There's actually a couple of pieces of coding-related software I'm interested in picking up once I graduate and have a job again. SublimeText is one, but I've also heard really good things about Beyond Compare, for merging code. I can't think of any others off the top of my head, but I'm sure there are some that either I have forgotten or I haven't encountered yet.
    I loves me some Beyond Compare but I haven't done much in the way of comparison shopping. I really should purchase a license but the glitchy trial code (your trial is up but thats ok keep using the product) just enables my procrastination.

    [PSN: SciencePiggy] [Steam]
  • IcemopperIcemopper Registered User regular
    edited March 2011
    templewulf wrote: »

    ASimPerson is absolutely right, but I just want to say that I hate C-style error handling. I prefer the C++ style, in which the handling of errors is separated out from return values.
    Spoiler:

    Edit:
    @Icemopper: I forget, are you working in C++, or are you sticking to straight C?

    Straight C. What I've got so far is just
    #include <stdio.h>
    
    int main(void){
        printf("Hello World!");
        return 0;
    }
    

    And that's it... I'm still not so sure what the return 0 actually does.


    And has anybody worked with Wordpress before and gotten <code> tags to actually keep spaces? This is frustrating....

    steam_sig.png PSN:Icemopper
  • iTunesIsEviliTunesIsEvil Registered User regular
    edited March 2011
    return 0;
    
    Exits the function you're currently in, and sends back a value of "0" as an integer. In this case, since you're in main(), you're exiting the program, and telling the OS (or whoever's listening) that you exited without an error.

    Basically. I'm sure someone can give a little nicer/more-in-depth answer.

  • IcemopperIcemopper Registered User regular
    edited March 2011
    That answer will be perfectly acceptable for the time being, I'm sure. I actually understand that as an answer, I mean.

    steam_sig.png PSN:Icemopper
  • EtheaEthea Registered User regular
    edited March 2011
    bowen wrote: »
    That's what I was looking for ethea. I couldn't find that page again. I think I know what is the problem now. Thanks to both of you.

    Thanks I am just practicing before I become an official Qt ambassador.

  • bowenbowen Registered User regular
    edited March 2011
    That's pretty much it.

    http://en.wikipedia.org/wiki/Exit_status

    Not really too helpful other than you're telling the OS, "Hey I'm done, everything looks good." Some OS' (most desktop ones anyways) will clean up after your program too, if you left dangling pointers or other garbage in memory.

    Edit: it plays a huge part when you write your own functions, though.

    Let's say you have a function (DISCLAIMER: CODE MAY NOT COMPILE):
    int LoginUser(char* user, char* pass) {
      int success = 0;
    
      //do stuff here
    
      return success;
    }
    

    You could do a whole slew of functions to test for user logins. Maybe the authentication server is down, return 1, maybe the password is incorrect, return 2, maybe the username doesn't exist, return 3.

    This let's you do something like"
    switch(LoginUser("MyUser","MyPass")) {
      case 0:
        printf("Success!");
        break;
      case 1:
        printf("Authentication Server is Offline");
        break;
      //... so on
    }
    
    

  • InfidelInfidel Heretic Registered User regular
    edited March 2011
    return 0;
    
    Exits the function you're currently in, and sends back a value of "0" as an integer. In this case, since you're in main(), you're exiting the program, and telling the OS (or whoever's listening) that you exited without an error.

    Basically. I'm sure someone can give a little nicer/more-in-depth answer.

    That's effectively all you need to concern yourself with at this point yes.

    Think about a function call and how it returns a value. Well, programs are actually called, and main() is the function they call, and it returns a number back. (Not technically detailed or correct but all you need to think about it as, yet again.)

    What it returns for a program is by convention zero for no-error and non-zero for error, just a convention. Why it is like that is because you may have many different error conditions you wish to relate, but almost always only need one "no error here" distinction, so if we make "no-error" to be zero it makes it very easy to test whether an error occurred or not, computer-wise.

    TwitchTV channel: OrokosPA OrokosPA
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • iTunesIsEviliTunesIsEvil Registered User regular
    edited March 2011
    The bestest is when you run into some really weird program where the error-exit-code is zero. Someone really thought that out well. "I know, instead of using a wide range of values to specifically let the consumer know what error caused us to exit we'll just return this one value that can't tell the user anything!"

    I really wish I could remember which program it was that did that to me. I know I've run into win32 functions where they give back a non-zero int to indicate success.

  • bowenbowen Registered User regular
    edited March 2011
    The bestest is when you run into some really weird program where the error-exit-code is zero. Someone really thought that out well. "I know, instead of using a wide range of values to specifically let the consumer know what error caused us to exit we'll just return this one value that can't tell the user anything!"

    I really wish I could remember which program it was that did that to me. I know I've run into win32 functions where they give back a non-zero int to indicate success.

    I can think of a few. Mostly because it makes using the if/else control really easy. Those are usually the libraries that use an excess amount of GetLastError() functions.

  • EndEnd Registered User regular
    edited March 2011
    Well...if we're talking about functions instead of program exit...

    Most "standard" functions require you to inspect errno or GetLastError() to get more information.

    Zero is often a valid return value (printf, open, etc) anyway. It seems more common to me that an error will result in a negative return value instead of a zero return value.

    if we're too far behind / and really out of time / is there another world they plan to find?
    zaleiria-by-lexxy-sig~medium.jpgsteam~tinythumb.png
  • bowenbowen Registered User regular
    edited March 2011
    Zero should be the expected return of a success. I was lamenting at the cases where 0 means failure (as a very sly way to imitate a boolean with an integer), to make if/else and detect errors more easily, and then using GetLastError as the more verbose version.

    As I understand it if your function returns a negative value, it will still evaluate as true in an if statement in C, or at least it should because it's "not 0." Anything other than 0 is a success to the if control, IIRC. That's pretty tangential to this, though.

  • iTunesIsEviliTunesIsEvil Registered User regular
    edited March 2011
    Would it be more accurate to say "0 is a true to the if control?"

    Success/failure and true/false line up only when they're that simple. But, lucky programmers we are, we've got to deal with success, fail - file not found, fail - couldn't get handle to file, fail - hey this is Windows wtf are you using those path separators for, etc. :P

  • ASimPersonASimPerson And they will tremble again at the sound of our silence!Registered User regular
    edited March 2011
    bowen wrote: »
    As I understand it if your function returns a negative value, it will still evaluate as true in an if statement in C, or at least it should because it's "not 0." Anything other than 0 is a success to the if control, IIRC. That's pretty tangential to this, though.

    This is correct, btw. Zero evaluates to false and non-zero to true.

    redoctober2.png
    SE++ Forum Battle Archive | PST = Pacific Standard Time | DRUNKSTUCK: A Homestuck recap
  • bowenbowen Registered User regular
    edited March 2011
    Would it be more accurate to say "0 is a true to the if control?"

    Success/failure and true/false line up only when they're that simple. But, lucky programmers we are, we've got to deal with success, fail - file not found, fail - couldn't get handle to file, fail - hey this is Windows wtf are you using those path separators for, etc. :P

    If you do:
    if(0) {
      printf("True!");
    }
    
    

    It will not evaluate with C, at least on gcc anyways. Edit, and this is why true = 1 as an integer value, usually, and why people return 0 as failure. It makes some weird spooky logical sense. Technically true could be -1 and still evaluate, or -201201.

  • iTunesIsEviliTunesIsEvil Registered User regular
    edited March 2011
    I lopped off "anything other than" in my quote there. Because I'm a moron and didn't check that what I'd written made sense.

    It made sense in my head, goddamnit. I knew what I meant. :wink:

  • bowenbowen Registered User regular
    edited March 2011
    Ah yeah I figured that's what you meant. Not that I've ever done something like that... :whistle:

  • ecco the dolphinecco the dolphin Registered User regular
    edited March 2011
    bowen wrote: »
    Ah yeah I figured that's what you meant. Not that I've ever done something like that... :whistle:

    [strike]strcmp[/strike]strncmp?

    strncmp?!?!

    STRNCMMMPPPP!!!!

    Penny Arcade Developers at PADev.net.
  • IcemopperIcemopper Registered User regular
    edited March 2011
    Well you guys are all awesome. Thanks for the massive amount of help!

    steam_sig.png PSN:Icemopper
  • bowenbowen Registered User regular
    edited March 2011
    bowen wrote: »
    Ah yeah I figured that's what you meant. Not that I've ever done something like that... :whistle:

    [strike]strcmp[/strike]strncmp?

    strncmp?!?!

    STRNCMMMPPPP!!!!

    olol wat is this

  • Gandalf_the_CrazedGandalf_the_Crazed Vigilo ConfidoRegistered User regular
    edited March 2011
    XNA Game Studio...is this something I need to be using if I want to make a platformer as a learning exercise? If so, what version? If not, then what (if anything)?

    PEUsig_zps56da03ec.jpg
  • ecco the dolphinecco the dolphin Registered User regular
    edited March 2011
    Soooooooo, soliciting Language/Framework/Purpose for a new OP! I'll try and put it up in about 13 hours. If this gets locked, PM me!
    Language: Verilog
    Framework: None
    Purpose: Low level development

    If you thought assembly language was low level, try Verilog or any of the other HDL languages on for size. Verilog is designed to describe how bits change every clock cycle. And not just one bit either, but potentially every bit available in the device that you are developing for.

    This allows for massive parallelism - the sheer number of calculations per clock cycle can easily exceed both general purpose processors and DSPs.

    It can also drive men insane.

    I see square waves everywhere.

    Penny Arcade Developers at PADev.net.
  • SmasherSmasher Starting to get dizzy Registered User regular
    edited March 2011
    Soooooooo, soliciting Language/Framework/Purpose for a new OP! I'll try and put it up in about 13 hours. If this gets locked, PM me!
    Language: Verilog
    Framework: None
    Purpose: Low level development

    If you thought assembly language was low level, try Verilog or any of the other HDL languages on for size. Verilog is designed to describe how bits change every clock cycle. And not just one bit either, but potentially every bit available in the device that you are developing for.

    This allows for massive parallelism - the sheer number of calculations per clock cycle can easily exceed both general purpose processors and DSPs.

    It can also drive men insane.

    I see square waves everywhere.

    (hopefully this problem gets ported to the new thread)

    For a fun exercise, construct in hardware an instruction that determines whether a given 16-bit value has more ones than zeroes, that has less than twice the cycle time of a 16-bit carry-look ahead (CLA) adder. Naturally, the lower the cycle time the better.

  • seabassseabass Doctor MassachusettsRegistered User regular
    edited March 2011
    XNA Game Studio...is this something I need to be using if I want to make a platformer as a learning exercise? If so, what version? If not, then what (if anything)?

    Depends on what you have access to development wise and what you're trying to learn. If you just want more practice writing code, java would probably be just as good as C# + Xna for writing a little game. If you're looking for experience using libraries, then using some sdl libraries from your favorite language might be just as good. Of course, if your goal is to get some practical development experience for consoles, XNA it is.

    Run you pigeons, it's Robert Frost!
This discussion has been closed.