Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
t_rf
Nov 24, 2006

Kleedrac posted:

I'll probably spend far more time on balance issues and tweaking the XP curve and other aspects of monsters, bosses, and player classes (yet another reason that needs to be its own class with inheritance for each and a tool to allow easy editing of the file format which will store it.) Again thank-you for your help, I hope this clears up my intent.

No. Unless you're making an uber-competitive multiplayer game like Starcraft where the balance is so essential it needs statistical analysis -- it will take at most a few weeks of work to tune and balance preexisting gameplay mechanics. It takes months to years to implement said mechanics, pump out content and scripting, and get the presentation and polish down pat. Basically, the tuning happens in between doing other things.

If you really want to focus on gameplay immediately, slap together a battle system prototype. Aim to do it in about a day; for an RPG, not hard since no graphics are needed, just model the relationships between different variables and stick a command-line interface on top. Cut all unnecessary features to hit the deadline. Your goal is simply to prove your gameplay, eliminate unknowns in the design, and identify the features are important to iterate on, and the ones that are useless to implement.

Do this, and you won't waste your loving time writing out pretty, non-functional classes with what appears to be a misguided worship of OO inheritance hierarchies(which most commercial developers have long since moved away from because a God Object results from using inheritance to define all gameplay entities). The best code is no code and the best tool is someone else's. The exception is if you are interested in researching game technology. In that case, by all means try something outrageous.

Also, if you studied Extreme Programming, you'd know that what you are doing right now isn't it. Planning far ahead and dividing up work as if it were an assembly line is a classic waterfall pattern.

As for your OP questions about tools, file formats and engine stuff: What you're looking for is the pipeline. It is ultimately up to you to decided how assets are created and imported into your game, what the user-facing interface is like, and how the game engine will save and restore data.

Using Python, you have a plethora of code available to base your own work off of. For a custom binary file format, you can just serialize everything using the built-in pickle library. For formats you want to edit with a text editor you can choose between XML, JSON, YAML, and miscellaneous others. If you have data with a lot of relationships that can be aggregated in multiple ways, you might want to use a SQLite database. You can implement loaders for existing engine formats, or formats for generic editing tools like Mappy and Tile Studio. No matter which you choose you still have to write some boilerplate to relate the external format (data order, tagging, etc.) to the internal one your game will use.

Adbot
ADBOT LOVES YOU

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through

Kleedrac posted:

Thanks for your ideas :) To clarify, however, there is method to my madness. Normally I take an extreme programming approach http://en.wikipedia.org/wiki/Extreme_Programming to things so this does make sense. In this case there are a few other factors which have steered me away from it. Firstly I would like to have this engine so doing a sequel or any other story I feel like writing (I used to run a lot of D&D campaigns but don't have the players these days) would be a cakewalk (especially if I implement some good tools.) Secondly in the extreme programming vein I will be working with a partner on this project. So breaking it up into classes ahead of time will allow us to work separately towards the over-arching goal. Beyond that writing the small code like drawing a sprite and having it respond to movement will be one minor part of this, I'll probably spend far more time on balance issues and tweaking the XP curve and other aspects of monsters, bosses, and player classes (yet another reason that needs to be its own class with inheritance for each and a tool to allow easy editing of the file format which will store it.) Again thank-you for your help, I hope this clears up my intent.

If you've never coded anything of this type before don't go assuming you already know what you will be doing. Throw away any ideas you have about lovely gimmicks like eXtreme programming. A proper game engine takes a lot of work and a lot of planning. The fact that you're going to be working with a partner means that you can't really get away with planning as you go. You don't want to step on the feet of your partner and visa versa.

Honestly for your needs I'd suggest using a game-building tool like RPG Maker XP or Game Maker. You'll mostly just be rewriting the code that they use, anyway. The file pipelines will already be set up and you can start right away at endlessly tweaking XP curves. Just because you didn't write the all of the code yourself doesn't make it any less your project.

If you're hellbent on coding your own, XNA has an RPG Starter Kit that would be perfect for you. http://creators.xna.com/en-US/starterkit/roleplayinggame

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

t_rf posted:

Do this, and you won't waste your loving time writing out pretty, non-functional classes with what appears to be a misguided worship of OO inheritance hierarchies(which most commercial developers have long since moved away from because a God Object results from using inheritance to define all gameplay entities).
How so? Unreal goes pretty crazy with inheritance and doesn't manage to have "God objects." edit: Except the bloated Pawn class, ugh.

quote:

A proper game engine takes a lot of work and a lot of planning.
Anybody planning on embarking on a large project like a game engine should seriously consider reading or at least understanding the premises presented in The Mythical Man-Month, and avoiding often-counterproductive habits like Not Invented Here Syndrome and premature optimization.

Starting from scratch is a pretty bad starting point too, game engines are large and complex pieces of software and it takes some clever design to not have things break down at the various interchange points. I'd strongly recommend against writing one until you've got a thorough grasp on an existing engine/framework/middleware so you can get an idea of how to glue all of the pieces together.

OneEightHundred fucked around with this message at 17:56 on Nov 14, 2008

Vinterstum
Jul 30, 2003

"Don't make an engine, make a game."

The engine comes by itself, pretty much. Focusing on what you actually need right there and then to make the next bit of functionality for your game, gets you a lot more motivated (you see immediate results) and increases the chance of actually finishing the project by quite a lot.

Edit: And never, ever, make your own engine for your first game.

Benji the Blade
Jun 22, 2004
Plate of shrimp.
Look Kleedrac, pretty much everyone who's responding to you is right. I'm not going to restate what they said, but you would do well to read it again.

You're talking about wanting to make more games down the line and so on, and you know what you should do? Forget about it. I'm serious. Don't think about any other games you want to make until this one is on its way out the door. Here's why: you'll be more likely to finish your first game if you aren't working on future games at the same time, and after you finish your first game, you'll be in an immeasurably better place to make decisions and judgments about how to make your second game. And the best news of all is that at that point, you'll have a working game to cannibalize for parts for the new game. You'll know what to rip out and what to reuse and how to reuse it.

Oh, and just in case you think I'm being condescending: this is how we do it in the industry. Game engines are usually extracted from games, sometimes after reuse in many games. In the cases where one is written from scratch, there is a reason that it's done by the most experienced programmers in the industry.

And as far as the window with the image not being a big part of what you're doing THAT'S THE GODDAMNED POINT! Do the smallest thing possible. Then do the next useful small thing. Repeat. You seem to have some belief that incremental development will not lead to clean or reusable design. This is what refactoring is for. On the contrary, your waterfall method will lead to a design that embodies your ignorance at the beginning of the process.

So you're working with someone else? Well, one of you better get the project off the ground to the point where it's big enough you two can both work on different systems at once, and in the mean time, the other can work on some small tool that you absolutely will need (say, a map editor), but again, do so as simply as possible.

Also, pay special attention to what MasterSlowPoke said about RPG Maker and Game Maker. It's a point I meant to raise, but if what you're most concerned about XP curves and all that, why would you spend time worrying about how sprites are blitted? People have done this before, and they've made good engines based on lots and lots of games that were built on top of them.

Star Warrior X was right: the path you're going down right now is a path I've been down and I've seen many people go down, and there's no finished game at the end of it.

Edited for clarity.

Benji the Blade fucked around with this message at 21:05 on Nov 14, 2008

Paradoxish
Dec 19, 2003

Will you stop going crazy in there?
Here's a simple rule of thumb that isn't beaten into the head of hobbyist game developers often enough: if you end up with a complete, functional game then it doesn't matter if the code it's built on sucks. This is actually a corollary to the idea that you should build games and not engines, but it deserves specific mention because it's so important. If you've never worked on a project like this before then it's difficult to plan your code on paper before you've even started. Improving small, working chunks of code later on is much easier and refactoring is an important skill to develop anyway.

Kleedrac
Jan 16, 2008

Mii, myself & I
You gentlemen all make very very good points, and now for my rebuttal. I'm beginning to see the light! I don't want to use RPG Maker because after shoe-horning several of my story ideas into it I find it just lacks in so many areas that it makes me more than a little crazy. I did want to build the engine first but what you guys are saying about creating the engine after the fact makes a lot more sense. Starting small and building also makes a lot of sense but I think I'll take the advice from t_rf about starting with the combat engine and expanding as opposed to making more (it was kinda my hello world in pygame) small programs to blit sprites around being controlled by kb/mouse/gamepad. I also want to say there's a reason I'm asking these questions and although I may disagree with your advice I do listen and research it and I do appreciate it. Thanks very much and be assured I'll be back to start more ill will once I actually run into a problem coding :v:

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!
Our game dev club tried XP. Turns out we vested ourselves highly in the Magpie paradigm. ("Oooh! Shiny! Want!") We thought we could control the flow of things as they were assembled, but it was a disaster. We had a super basic engine running. It was neat, and also totally unmaintainable.

Now, we are using an iterative approach. We figured out what our big targets were, starting with sending messages over a network. We completely ignore later iterations until we finish the current one.

Each iteration starts by examining what we want to do: Send messages, serialize an object, etc. Then we design the interfaces. We do several 'dry runs' to review and fix our interfaces. After they are complete, and only then, do we start thinking about pseudocode. Then we build prototypes, and if everything goes well, we refine (by discarding and rewriting) those prototypes.

Starting with code is a bad idea. A really bad idea. In fact, the code should only be about 15% of the work you do, the rest should really be design, testing, and analysis. Starting with code or pseduocode WILL cause you trouble in the future.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
You're making a logical fallacy there.

Attempt one: You used a certain technique, did random poo poo apparently, and failed.
Attempt two: You use another technique and have a bit more success.

Your conclusion: "The technique is the problem." Which completely ignores the fact that you now have a whole lot more experience in what you can do and what you need and what you want.

Also, XP IS an iterative approach. If you're doing that, well drat, you're STILL doing XP. You seem to think that XP means "No design, ever. :colbert:" It however only means: "Don't try to design EVERYTHING at once up-front."

Lastly, saying "starting with code is a bad idea" in a general manner and applying it in every case is dumb. The ONLY time it is correct is when you already know what the language and libraries at your disposal can do. However when you do not know that, then you need to get down and dirty, go in and just get some code done to learn what they can do.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
The problem is also that it's hard to make intelligent design decisions until you've worked with things for a while, and good ideas from effective systems will rub off. I can't count how many programmers (including myself!) first thought the best way to write objects in a game was to have superobjects that handled everything from behavior to sending out the OpenGL calls. Then later you want to add shaders and you realize how hosed you are.

If you want to write any performance-minded game, then you wind up needing to specialize things a bit, but the points to specialize on are often not clear and can make for some really bad design decisions.

Working with an existing functional platform will help you realize where these divisions are and how to write a good, maintainable codebase so that you don't wind up scrapping or convoluting everything.

nihilocrat
Jun 8, 2004

all the hep cats jam to "cat /dev/hda1 > /dev/audio"
Pyglet will basically just handle a few more things for you, and hammer the idea that event systems and task scheduling are a core part of games into your head earlier. The only gripe I have with it is that it's in pure python, which sort of misses the point of python. If you ever run into performance issues in the future (probably won't with an RPG), replace the pyglet sprites later with rabbyt ones. They are so similar that I was able to do this in one of my projects in just about an hour of work, it was mainly just switching naming conventions for members and getting it to cooperate with the existing physics model.

If you want to save even more time at the expense of performance, check out cocos2d. Like I said, for your problem domain you probably won't have to worry about performance. You game model is going to be very very thin (no need to update a physics simulation 60 times a second) so you can afford to have a lot more bling.

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!

Mithaldu posted:

You're making a logical fallacy there.

Attempt one: You used a certain technique, did random poo poo apparently, and failed.
Attempt two: You use another technique and have a bit more success.

Your conclusion: "The technique is the problem." Which completely ignores the fact that you now have a whole lot more experience in what you can do and what you need and what you want.

Also, XP IS an iterative approach. If you're doing that, well drat, you're STILL doing XP. You seem to think that XP means "No design, ever. :colbert:" It however only means: "Don't try to design EVERYTHING at once up-front."

Lastly, saying "starting with code is a bad idea" in a general manner and applying it in every case is dumb. The ONLY time it is correct is when you already know what the language and libraries at your disposal can do. However when you do not know that, then you need to get down and dirty, go in and just get some code done to learn what they can do.

Sorry, you are totally right. I wasn't clear enough.

When I said don't start with code, I forgot to mention that it is perfectly acceptable to write code as part of a prototype to inform the design stage, or as a training mechanism. But I think that to jump into actual project code first is going to give you trouble later.

Also, I think you are right, we were really undisciplined at first. One of our members thought he understood XP, and he was an idiot. The moral of the story, I guess, was more that you should understand the discipline required for any process before jumping in.

Star Warrior X
Jul 14, 2004

Pfhreak posted:

But I think that to jump into actual project code first is going to give you trouble later.

I disagree with this idea. Having something to play, something that you can run, and look at, and point to and say 'this is my game,' is really helpful, even when it's really simple, like a piece of placeholder art bouncing around and responding to input. It will inspire coders and artists to make it look better and be more functional, and salesmen, marketers, and executives are always happy to see progress.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Pfhreak posted:

But I think that to jump into actual project code first is going to give you trouble later.
It depends entirely and completely on your level of experience with the language and your tools, nothing else.

I have a good amount of experience with Perl and with programming in general and i had zero experience with OpenGL and only limited experience with the data i am using, but in this project (actual code) i used almost no design at all, the entirety of my design documents is 6 files, most of which are by now pretty outdated and/or obsolete or only serve as data lists. If i had started with design, i wouldn't have gotten anywhere at all.

The one and important point is: Only design when you know you'll not be able to keep a structure or flow in your head in its entirety, but already have a pretty good idea of how it would look like. If you don't already know how it would look like, then any "design" would be wild guesses. If you can keep its entirety in your mind, then you're wasting time.

Edit: Also, there's a considerable chance that, if you need to design in the first place, you're being too complex and should rethink what you're doing and split it up into smaller parts that can be kept in your mind.


Ok, yeah. In teams planning is necessary. :)
vvvv

Mithaldu fucked around with this message at 22:22 on Nov 15, 2008

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!

quote:

It depends entirely and completely on your level of experience with the language and your tools, nothing else.

I'd say there are other factors here too including the complexity of the program you are writing, the number of people you are working with, the span of time you plan to maintain the project.

Part of my experience comes from working on projects with 8 programmers, which is probably coloring the way I do things considerably. Each programmer might have a slightly different idea of how objects send messages, or how we serialize things over the network, and it can rapidly become chaos as they implement their own solutions to the problems they are encountering. I agree that if you need to crack open UML for your personal projects, you are probably over thinking things. But if you are writing a networked game with client/server interactions, scripting, or any complex drawing, it is probably to your advantage to spend the time in Visio, critically thinking over the design.

Once again, you guys are right. In projects where you can forsee the whole of the game in your head, and view the control flow in your head comfortably, producing work artifacts is something of an academic exercise. But you didn't really skip the design, you actually participated in the process, you just didn't need to write it down.

I don't advocate design for design's sake, but if the design teaches you something, then it was probably a valuable exercise. If you don't learn anything you didn't already know, then yeah, it was a waste of time.

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!

Pfhreak posted:

[..] But you didn't really skip the design, you actually participated in the process, you just didn't need to write it down.

I don't advocate design for design's sake, but if the design teaches you something, then it was probably a valuable exercise. If you don't learn anything you didn't already know, then yeah, it was a waste of time.

An excellent and insightful post. I don't have anything much to add at this point, I just wanted to express my appreciation and underscore this wisdom, in case anyone might have skimmed it.

Morpheus
Apr 18, 2008

My favourite little monsters
My first game was going to be a zombie survival Roguelike based on the Zombie Survival Handbook. It was going to be glorious! Who needed design, I just jumped right in, figuring I'd make it along the way.
Yeahhhhh. That was a bad idea. However, I learned a lot about programming styles, conventions, and why vectors in C++ are evil, evil things.

Anyway. On a completely unrelated subject (and project), I have a question for Les Goons: I'm making a sidescroller, and my little guy needs to swing his wrench forward for a melee attack. How is it done so that the wrench is lethal to enemies, but the guy is not? I would say it's two different sprites or something, but there're games where there is clearly just one sprite with 'damage strips', to coin a phrase I heard from Research Indicates, on the weapon. Do I have any options here?

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Morpheus posted:

vectors in C++ are evil, evil things.
What do you mean?

quote:

How is it done so that the wrench is lethal to enemies, but the guy is not? I would say it's two different sprites or something, but there're games where there is clearly just one sprite with 'damage strips', to coin a phrase I heard from Research Indicates, on the weapon. Do I have any options here?
Two different hitboxes.

Morpheus
Apr 18, 2008

My favourite little monsters

Mustach posted:

What do you mean?

I have very strong memories of the vectors in the STL. Let's see, there's the complete and utter lack of a remove function (instead, you must enumerate until you find the thing you want to remove, then remove the object between enumeratorPosition and enumeratorPosition+1). Then there's the pointers to vectors constantly deciding to null out the entire vector between two lines of code, randomly throughout the program. The only add function available was push_back(), if I recall correctly. Terrible things.

Mustach posted:

Different hitboxes

Aww nuts. So I guess I have to spawn an 'enemy-damaging' hitbox at the player's location, move it in such a way that represents the character's swing, and then apply damage if it touches something before I remove it huh. Bugger, was hoping to avoid that.

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through

Morpheus posted:

Aww nuts. So I guess I have to spawn an 'enemy-damaging' hitbox at the player's location, move it in such a way that represents the character's swing, and then apply damage if it touches something before I remove it huh. Bugger, was hoping to avoid that.

As an illustration, this is character's hitboxes from Super Smash Brothers Melee. The yellow boxes are where the player can be damaged and the red ones are the hitbox for the attack.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Morpheus posted:

I have very strong memories of the vectors in the STL. Let's see, there's the complete and utter lack of a remove function (instead, you must enumerate until you find the thing you want to remove, then remove the object between enumeratorPosition and enumeratorPosition+1). Then there's the pointers to vectors constantly deciding to null out the entire vector between two lines of code, randomly throughout the program. The only add function available was push_back(), if I recall correctly. Terrible things.
If you want element pointers, write a reference class that stores a pointer to the vector and the element offset and use that to act as one. Not that this will work with removes, but I don't think there are ANY languages that will give you resizable arrays and let you create persistent references to elements.

And yes, you can remove elements, use the "erase" method.

OneEightHundred fucked around with this message at 13:51 on Nov 16, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

but I don't think there are ANY languages that will give you resizable arrays and let you create persistent references to elements.
Sure there are. :)

code:
use '5.010';
my @array = (1,2,3,4);
my $ref = \$array[2];
say "[@array] $ref $$ref";

splice @array, 1,1;
say "[@array] $ref $$ref";

shift @array;
say "[@array] $ref $$ref";

unshift @array, 5;
say "[@array] $ref $$ref";

splice @array, 1,1;
say "[@array] $ref $$ref";

__END__

[1 2 3 4] SCALAR(0x2286ce4) 3
[1 3 4] SCALAR(0x2286ce4) 3
[3 4] SCALAR(0x2286ce4) 3
[5 3 4] SCALAR(0x2286ce4) 3
[5 4] SCALAR(0x2286ce4) 3

Scaevolus
Apr 16, 2007

Mithaldu posted:

Sure there are. :)
That's a coincidence of how realloc() works with very small chunks.

He should have stated it more clearly-- you can't guarantee that a pointer to an element in a resizable array will always be valid (barring obscure data structure).

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Scaevolus posted:

That's a coincidence of how realloc() works with very small chunks.
I'm pretty sure that that's not a coincidence, but actually how Perl is designed to work. If i get a ref to any variable, that ref will always point to that variable, even if it gets moved around inside other data structures.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Okay, guess I'm wrong. :suicide:

... although the vast majority of languages will not do that, even ones that are pretty high-level. It's not exactly a must-have feature.

Morpheus
Apr 18, 2008

My favourite little monsters

MasterSlowPoke posted:

As an illustration, this is character's hitboxes from Super Smash Brothers Melee. The yellow boxes are where the player can be damaged and the red ones are the hitbox for the attack.



Is there anywhere to see coding design documents that go over stuff like that image? The only trouble I have is with the higher-level design: what objects know about other objects, how are things connected, etc. This is the first time I've worked with animation stuff, so stuff like damage hitboxes, state-based animation, and all that stuff is totally alien to me.

t_rf
Nov 24, 2006

Morpheus posted:

Is there anywhere to see coding design documents that go over stuff like that image? The only trouble I have is with the higher-level design: what objects know about other objects, how are things connected, etc. This is the first time I've worked with animation stuff, so stuff like damage hitboxes, state-based animation, and all that stuff is totally alien to me.

I don't know about design documents, but here's a general template for what I've seen(and implemented) in working engines:

- Characters are spawned with all their collision, and it's disabled as needed. (This is generally done for simplicity of memory management)

- Characters have one (or more!) finite state machines. There are a wide variety of formalized finite state machine implementations, and variations on the FSM concept, but using them isn't required. One can also opt to wrangle some ad-hoc logic together. The state machine can drive as many or few things as desired; completely unreactive, immobile scenery won't need any state, while moving objects probably want some kind of physics state(ex. air vs. ground) and characters that engage in combat will contain some state for attack/hitreact/knockback/knockdown/death/etc. which manipulates positioning, anims and collision as needed; AI behaviors can also be handled with state machines. This is an area of game programming that nobody's very happy with, as a large number of states becomes extremely complex and hard to debug very quickly. If the logic feels overwhelming, write out flowcharts. If the flowcharts aren't enough, write out decision tables.

- Animation and state machines can cooperate and override each other; one can specify an animation format where at given frames of the anim a state-changing event is fired, and collision is turned on or off or moved. Similarly, a state machine will probably want to interrupt anims for things like player inputs or combat/environment damage.

- Scripting languages can act as a layer on top of all of the above, providing an additional pathway for logic without tinkering with an existing state machine.

The details of how characters interact with each other and how events are fired are specific to the game design; thus no one engine has a complete solution, just solutions that are good enough for the problem domain. A typical event one would write is something like "body collision triggers a hitreact on its parent when it intersects attack collision." This event describes your typical "you swing the sword and your opponent gets hurt" situation. As needed you can differentiate your collision's data more and more finely to resolve things like different types of weapons and armor, environmental effects vs melee vs ranged, etc.

There are also shortcuts that can be done in the design. Doing something like having the game loop drain health from characters with every frame that they're in damage collision lets you eschew hitreact states entirely, and reducing enemy AI to "move towards the player" means you won't need behavior states, but the resulting gameplay of these shortcuts is probably unacceptable to modern audiences.

a slime
Apr 11, 2005

Python kicks all kinds of rear end. I just started learning it last Wednesday and I am already sitting on a functional 2D game engine with continuous collision detection. I'm getting a pretty good frame rate already, and when I move the collision detection into C/C++, it's only going to get better.

Seriously. Pyglet + Rabbyt. It owns.

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!

not a dinosaur posted:

Python kicks all kinds of rear end. I just started learning it last Wednesday and I am already sitting on a functional 2D game engine with continuous collision detection. I'm getting a pretty good frame rate already, and when I move the collision detection into C/C++, it's only going to get better.

Seriously. Pyglet + Rabbyt. It owns.

I just can't get into python. I grapple with the concept of significant whitespace, and something about it just irks me.

Although, I come from a background of strongly typed languages, fancy IDEs, and strict OO design, so that probably explains it.

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!

Pfhreak posted:

I just can't get into python. I grapple with the concept of significant whitespace, and something about it just irks me.

Although, I come from a background of strongly typed languages, fancy IDEs, and strict OO design, so that probably explains it.

Please don't take offense, as this response isn't directly to you so much as to the complaint of "significant white space." I'm sure you're a cool guy.

The complaint with "significant white space" is a completely asinine. White space is always "significant", it's just not always enforced. Readability is always a concern when evaluating a language, and it's not possible to have a high degree of readability in a significant block of code without consistent use of white space.

But in most languages, white space is ignored by the compiler/interpreter and convention dictates that white space will be used anyway to make the code readable. An additional, human "layer" forces white space significance.

Well, may this be a core example of the Python philosophy at work. Generally speaking, the languages always tries to be explicit, provide "one obvious correct way" to do things, and not rely on mere convention for important language tasks. Readable code is important, as much as possible formatting is not left to convention, white space is mandated because Python code is designed to be readable.

If one just reads PEP8 and starts from there, there's absolutely no reason to complain about mandated white space except "I care about my personal idiosyncrasies more than readable code."

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I think the problem isn't as much the whitespace itself, but the lack of other readability features like ";" to denote the end of a command, or {} to encapsulate a block. Try having a structure that goes 4-5 levels deep and then find out that your program falls apart because a line at the end of the block wasn't in the right depth level.

Add to that the initially perceived lack of a way to do multi-line commands (maybe even actual. I don't know if it's possible and don't care enough to look it up). Suddenly the argument of "we enforce white-space to make it more readable!" looks mighty silly when everything around it and the enforcement itself seems to reduce readability.

In fact, personally speaking, whenever i look at python i see something that's barely readable and only is so because the whitespace is enforced. On the other hand, maybe i've just been looking at the wrong people's code.

Fake-Edit: In fact, i just looked up this PEP8 thing, and even the almighty Guido seems to be an idiot in regards to readability...
code:
class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if width == 0 and height == 0 and \
           color == 'red' and emphasis == 'strong' or \
           highlight > 100:
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)
Seriously, who in his right mind would tout this clusterfuck as an example of readability?


Edit: Other gems from mentioned document: :psyduck:

quote:

Comments:
You should use two spaces after a sentence-ending period.
When writing English, Strunk and White apply.

If you have to have Subversion, CVS, or RCS crud in your source file (__version__ = "$Revision: 63990 $")

Mithaldu fucked around with this message at 11:00 on Nov 23, 2008

take boat
Jul 8, 2006
boat: TAKEN

Mithaldu posted:

Fake-Edit: In fact, i just looked up this PEP8 thing, and even the almighty Guido seems to be an idiot in regards to readability...
Seriously, who in his right mind would tout this clusterfuck as an example of readability?
Edit: Other gems from mentioned document: :psyduck:
That's not an example of readability, that's an example of indentation and line breaking. That same code would look crappy in most any standard language, because it's crappy code.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

take boat posted:

That's not an example of readability, that's an example of indentation and line breaking.
I'm not sure about you, but if i were to write a guide on readability i'd ensure that every loving piece of code therein can serve as an example under any angle of observation. Reason: Every single newbie will follow the same train of thought as i did and WILL take those as examples.

take boat posted:

That same code would look crappy in most any standard language, because it's crappy code.
Haha, no.
code:
package Rectangle::Blob;

sub new {
    my ( $self, $width, $height, $color, $emphasis, $highlight ) = @_;
    
    $color      = 'black'   if !$color;
    $emphasis   = ''        if !$emphasis;
    $highlight  = 0         if !$highlight;
    
    raise ValueError("sorry, you lose")
    if (
        ( $width == 0 and $height == 0 and $color eq 'red' )
        and ( $emphasis eq 'strong' or $highlight > 100 )
    );
    
    raise ValueError("I don't think so -- values are $width, $height")
    if (
        ( $width == 0 and $height == 0 )
        and ( $color == 'red' or $emphasis eq '' )
    );
}

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!

Mithaldu posted:

code:
class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if width == 0 and height == 0 and \
           color == 'red' and emphasis == 'strong' or \
           highlight > 100:
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)
Seriously, who in his right mind would tout this clusterfuck as an example of readability?

This is not a sterling example of readability. This is "notice how I've broken lines after the binary operators". And while you're comment about a guide on readability should have great examples... well... you're right, it's not a great example.

Though, this isn't a newbie guide, either. This is a PEP. Perhaps my mistake is in suggesting it as a newbie guide.

Though, notably, your example isn't anything about whitespace. Your beef is with the blocks he's made with the white space insignificant portions! (I would agree, I don't break lines like that.)

Is this any better?

code:
class Rectangle(Blob):
    "Single line description about this class."
    def __init__(self, width, height, color='black', emphasis=None,
                 highlight=0):
        """
        Single line description of this function.

        :param width: what this does and type
        :param height: what this does and type
        :param color: what this does and type, default
        :param emphasis: what this does and type, default
        :param highlight: what this does and type, default
        """
        if (width == 0 and height == 0 and color == 'red' and
            emphasis == 'strong' or highlight > 100):
            raise ValueError("sorry, you lose")
        if (width == 0 and height == 0 and (color == 'red'
                                            or emphasis is None)):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)
or without docstrings:

code:
class Rectangle(Blob):
    def __init__(self, width, height, color='black', emphasis=None,
                 highlight=0):
        if (width == 0 and height == 0 and color == 'red' and
            emphasis == 'strong' or highlight > 100):
            raise ValueError("sorry, you lose")
        if (width == 0 and height == 0 and (color == 'red'
                                            or emphasis is None)):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)
This is how the same code would end up if I wrote it. (Well, the "Single line" description stuff would be "real".) The only real "problems" that creep up frequently is that an if block with a parenthetical condition ends up at the same indent as the block after it.

Also, while your Perl is formatted nicely, I consider it (well examples like it) very difficult to follow due to various constructions like "statement if condition". Perhaps this is an English construction, but you're never supposed to put conditions after an instruction in technical writing. In English, quick reading/scanning goes from left to write and ends after a complete thought occurs in a single sentence. As such, you're never supposed to put conditions after an instruction because a good portion of your audience is going to read and complete the instruction before reading the condition.

I would use the "statement if condition" is a sterling example of "extremely attractive syntax as the detriment of readability".

Edit: Oh poo poo! I just noticed that your exceptions are dependent on the if clause after them! Your extremely well formatted Perl isn't readable, it's actively deceptive! heh heh

tbradshaw fucked around with this message at 18:21 on Nov 23, 2008

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!
quote isn't edit. :(

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
You're forgetting one thing: Any user of C-style code will be trained to parse for block enclosures and semi-colons. As such the reversal to command/condition is absolutely no reduction in readability. Important points to note: People read downwards faster than sideways. Error messages should be descriptive or they're useless. As such if you gloss over the code you see:

raise ##error##
if ############
;

As the line above the error itself is free, you'll automatically have gained at least a rough understanding of what it does and even if you don't read that fast, you easily find it again. Then after having read it, you'll already know what the conditions check for and don't actually need to read them.

I did have it reversed when i first penned that, but i noticed that trying to laborously parse the conditions, to only then find that it's only an error that tells you what you already found out from the conditions is just plain a waste of time.

As for the 3 lines at the start that set the default, i could also have set them like this:
code:
$color      = $_[3] or 'black';
$emphasis   = $_[4] or '';
$highlight  = $_[5] or 0;
or even:
$color      ||= 'black';
$emphasis   ||= '';
$highlight  ||= 0;
However the first form is considered bad form, due to cutting down the signature line above and the second form comes dangerously close to being Perl golf. Additionally any C-style developer will notice the missing ; and immediately recognize the "if !" construct, so there's really not much of a problem in doing that.

I hope you see that i didn't just do the first thing any non-Perler suspects and used the most horrible things without even thinking about it, but carefully reasoned out why doing things in that way as opposed to the classic way does in fact improve readability.



As for your examples: They're better, yes. However i still find that the indentation is a bit chaotic, which is ironic for a white-space-heavy language, no? Furthermore the structure between the two ifs varies enough that it is not possible for the eye to get used to shapes and easily hop from the if to the actual command. Lastly, though this is minor: Combinatory operators like and or or should always be at the start of the line and in front of the object they refer to.

I am glad to see though that putting the conditions into proper parens removes the necessity of including the slashes and from where you are there would be only a minor tweak to be made to reach the "best" form, which is to linebreak before the last "and" in the second conditional. It would also help if the ":" could be moved to be in front of the "raise" in both cases, but i don't know if python's syntax can do that. If that were possible it would serve as a nice anchor for the eye to jump through.


Anyhow, here's my grief with the whitespace: Guido claims that by enforcing whitespace code automatically becomes more readable. Not so the case. Instead you have a Perl coder here telling you how to make stuff look nice. What was actually gained however is the potential for completely new and hilarious errors by making it possible for commands to execute outside of their intended scope. And lost were other tools, which as mentioned before, actually help improve readability, even if it means to write a bit more. Lastly, the probability of you putting commands in the wrong scope when dealing with complex structures rises due to the lack of closing markers.

... I shouldn't wrote about code when i'm tired. I totally zoned out on :words: here. :sweatdrop:

Mithaldu fucked around with this message at 19:24 on Nov 23, 2008

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!

Mithaldu posted:

You're forgetting one thing: Any user of C-style code will be trained to parse for block enclosures and semi-colons. As such the reversal to command/condition is absolutely no reduction in readability.

Presumptuous much? I'm trained in C-style code as well, and the reversal command/condition is absolutely atypical.

And you're using a "begging the question" logical fallacy. Yes, users of C-style code will be better at reading C-style code. This makes no statement regarding code readability in general.

Mithaldu posted:

Important points to note: People read downwards faster than sideways.

Source? I've never read this to be the case. I contend that cultural bias is the predominate factor in determining which "direction" reading is faster. The fact that languages on earth have evolved written language that writes in every direction seems to be a good generalized evidence collection.

Mithaldu posted:

Error messages should be descriptive or they're useless. As such if you gloss over the code you see:

raise ##error##
if ############
;

That's exactly what I read. And to me it meant:

* Raise an exception.
* If something, do something else.

The two were not explicitly related in any way. It was only after further examination that I realized that the if block didn't contain any branch blocks that I assumed that it must be referring to the block before it. This is very atypical.

Mithaldu posted:

Then after having read it, you'll already know what the conditions check for and don't actually need to read them.

Ack, this is exactly what I hate about Perl. "Implicit" everything. "Because my line of code was error free, you can just assume that the if statement does such and such." Why would I assume what the "if" statement does? Of course, because that usage follows a particular convention and that convention dictates what's in the statement. No thanks. I've worked in too many disparate code bases to trust unenforced conventions when reading code. For every great coder that uses the conventions properly, there are dozens that don't.

Mithaldu posted:

Additionally any C-style developer will notice the missing ; and immediately recognize the "if !" construct, so there's really not much of a problem in doing that.

This isn't true. This is also a "converse fallacy of accident". I've done plenty of C-style development, and I didn't immediately notice the missing ; and certainly didn't assume that the missing ; would indicate that the form of the statement had changed. Missing semicolons are the most common typo in C-style languages. Especially on a forum, I wouldn't assume perfect syntax.

Mithaldu posted:

I hope you see that i didn't just do the first thing any non-Perler suspects and used the most horrible things without even thinking about it, but carefully reasoned out why doing things in that way as opposed to the classic way does in fact improve readability.

It did not improve readability. In an example of readability, an experienced developer (me) read your code and didn't realize even the basic command structure without several re-reads. While Guido's particular Python example was merely ugly, it was certainly obvious.


Mithaldu posted:

As for your examples: They're better, yes. However i still find that the indentation is a bit chaotic, which is ironic for a white-space-heavy language, no?

Chaotic? It's the opposite! It's so predictable that sometimes it's ambiguous at a glance. It's failing is in it's rigidity.


Mithaldu posted:

Furthermore the structure between the two ifs varies enough that it is not possible for the eye to get used to shapes and easily hop from the if to the actual command.

Ironic indeed! After your example of if statements that aren't even apparent in what they do, one talks about visual profiles. Your visual profiles were that of a completely different structure: independent statement followed by conditional. You said yourself that "if you notice the missing ; it makes sense", that's not something identify by shape, it's only identifiable by parse tree.


Mithaldu posted:

Lastly, though this is minor: Combinatory operators like and or or should always be at the start of the line and in front of the object they refer to.

I like that better, too. Seems like a strange divergence from mathematic operators to do as Guido says.

Mithaldu posted:

Anyhow, here's my grief with the whitespace: Guido claims that by enforcing whitespace code automatically becomes more readable.

This has never been stated. Enforcing whitespace encourages more readable code. There's no magic bullet to readable code. You could turn your example into an unintelligible mess, perhaps an obfuscated one-liner, and Perl would applaud. Python refuses to run code that isn't at least properly white spaced.

Mithaldu posted:

Not so the case. Instead you have a Perl coder here telling you how to make stuff look nice. What was actually gained however is the potential for completely new and hilarious errors by making it possible for commands to execute outside of their intended scope. And lost were other tools, which as mentioned before, actually help improve readability, even if it means to write a bit more. Lastly, the probability of you putting commands in the wrong scope when dealing with complex structures rises due to the lack of closing markers.

This isn't true. The syntax features closing markers for data types. Also, you "told me how to make stuff look nice", but in turn your code wasn't obvious in what it does. Slightly less typeset code that is obvious in it's function is greatly preferable.



Most importantly, your entire posts on this topic could be summed up as:

1) I'm familiar with this syntax, it matches my style and thought process.
2) I know how to make this syntax very attractive and in a conventional way that others familiar with this syntax will understand it very well.
3) I understand the rationale of these conventions and agree with their presumptions.

And you know what? Good for you! Great coders are great in whatever language they find their home. Importantly, every precept you gave as an example is not generally true and is much more of a personal preference than an objective measure. (This is equally true with the premises with Python syntax.)

I don't think that there's any use in us trying to 'convince' each other towards either syntax. Python has a fine syntax, your preferences are otherwise. I personally can't stand Perl code, and it has nothing to do with white space and everything to do with maintaining code from various Perl monks after they've been gone on some other project for years, and it's horrible. :)

tbradshaw fucked around with this message at 22:13 on Nov 23, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
You get hung up on the wrong things and completely ignore the obvious thing that i can also do this and negate all your arguments about "weird" syntax order:
code:
package Rectangle::Blob;

sub new {
    my ( $self, $width, $height, $color, $emphasis, $highlight ) = @_;
    
    if( !$color     ) { $color      = 'black'; 	}
    if( !$emphasis  ) { $emphasis   = ''; 	}
    if( !$highlight ) { $highlight  = 0; 	}
    
    if (
        ( $width == 0 and $height == 0 and $color eq 'red' )
        and ( $emphasis eq 'strong' or $highlight > 100 )
    ) {
    	raise ValueError("sorry, you lose")
    }
    
    if (
        ( $width == 0 and $height == 0 )
        and ( $color == 'red' or $emphasis eq '' )
    ) {
    	raise ValueError("I don't think so -- values are $width, $height")
    }
}
Furthermore you ignore my original claim and act as if I'd said something else.

Then you go on to make a claim that my biggest point was completely wrong, only to go on to repeat my point with different words.

I agree there is no point in going on here.

Morpheus
Apr 18, 2008

My favourite little monsters
Right, so I'm starting to add AI to my game (in C#), and I'm trying to figure out how. I mean, I know how to program an AI, it's about programming multiple variations of AI into a game, one for each type of enemy. At the moment I'm not entirely sure what to do, specifically from the coding perspective. I mean, I know how to program a single AI. That's easy. But I don't want to create a separate AI class for each type of enemy. I'm certain there's a way around this, possibly using delegates. Any tips? There was mention of finite-state-machines earlier, which sound pretty good, but it's all a question of implementation.

Adbot
ADBOT LOVES YOU

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I think it would help if you'd drop a few words about what input the AI gets, what outputs it can form from that and maybe a rough sketch of how you would implement a base AI.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply