Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

Guys, I need a program to help me program in python.

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
I have been programing the game I talked about in the other thread, Unity is on my list to check out, but right now I'm following soggie's suggestion and doing it in Python, with pygame.

But the thing is, the program is getting big, and I keep adding functions to it as I add the planned features, it's getting kinda hard to just traverse it to modify the functions as I need to correct errors and modify their behavior.

So, is there any program that let's me put the code in, and then treat the functions as folders on the windows explorer, that appear only when I need to see them? Preferably a program that will let me compile the code too, to test it out.

Short of that, I think I'm gonna have to order that shit alphabetically.
 

FruitOfFallout

Educated
Joined
Oct 19, 2010
Messages
117
Maybe IronPython?

My dad told me some time ago that they have it out for the new visual studio .
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
I looked for IronPython, but it seems it only supports until version 2.7. I'm using 3.1.

But I found notepad++ which has the code folding option. Quite nice.
 

Aikanaro

Liturgist
Joined
Feb 3, 2004
Messages
142
I use Eclipse with PyDev - it's decent. Most Python IDEs suck horribly.

Although if you're writing anywhere near decent code things should be split up enough into classes in separate files that you shouldn't have to be traversing too much code at once.
 

Deneidez

Educated
Joined
Oct 17, 2010
Messages
75
Location
Finland, Joensuu
desocupado said:
I have been programing the game I talked about in the other thread, Unity is on my list to check out, but right now I'm following soggie's suggestion and doing it in Python, with pygame.

But the thing is, the program is getting big, and I keep adding functions to it as I add the planned features, it's getting kinda hard to just traverse it to modify the functions as I need to correct errors and modify their behavior.

So, is there any program that let's me put the code in, and then treat the functions as folders on the windows explorer, that appear only when I need to see them? Preferably a program that will let me compile the code too, to test it out.

Short of that, I think I'm gonna have to order that shit alphabetically.
There is something wrong with your game design, if you have problems like you said. Stuff is usually split into new files and those files usually have nothing but one class(OO) or similar functions groups(procedural). Before making any bigger games with python I would recommend googling for "Object Oriented Game Design".

Here is one I made a while ago. Every box you see is a file and a class.

http://cs.joensuu.fi/~ppakar/seka/thisMeansLol.png
(Yeah, this is the naked forest one.)

And for editor I recommend notepad++ or emacs(heh).
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
First, people who recommend objects don't usually have a clue what that means. Objects are useful in libraries, where you design for extension. They are decidedly less useful for oneshot programs, that you don't plan to spend years on, with various versions etc.

If you keep it functional, that is: no/minimal state, the function approach is easier to parse and comprehend, since it minimizes the weakness of the structural approach, though it might make for messy/long code (but OO also does if you don't keep in mind polymorphism opportunities).
Regardless, you always want to minimize state in your domain (not optimization for things like lists - that is not domain). It's easier to comprehend.

Basically, someone that hasn't internalized the Liskov substitution principle has no idea why (and how subtle it is) the idea of OO is so pushed by academia (and that is not checked for you by the compiler), and the other advantages arise in very vast, very stateful codebases.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Always refactor ofcourse, though using python that is harder. Rename functions until they make sense - look at the names again in one week and see if they still make sense, maybe the design changed/you were drunk and they don't. Don't be afraid to move things out into subfunctions or merge them back if they aren't used in more than one place etc. I guarantee that you will notice bugs and unclear things doing this. You can even do a few primitive tests when you are sure of a part of your design.

You should be a code gardener, not some hack like obsidian. :x
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
SCO said:
Always refactor ofcourse, though using python that is harder. Rename functions until they make sense - look at the names again in one week and see if they still make sense, maybe the design changed/you were drunk and they don't. Don't be afraid to move things out into subfunctions or merge them back if they aren't used in more than one place etc. I guarantee that you will notice bugs and unclear things doing this. You can even do a few primitive tests when you are sure of a part of your design.

You should be a code gardener, not some hack like obsidian. :x

I'm actually doing that, sometimes I don't add features, I just go around cleaning up the mess I made first, eliminating redundancies, adding comments, making sure everything is understandable. I also have small functions that do a small thing, like paint the "ground" a color to show the movement range in the screen, or to simply detect if there's a unit where you clicked.

About OO. Well. This is ugly. I was storing my units in a list of lists. But those lists inside were getting big. I was at 17 attributes to remember when I decided to modify that (by attributes I mean stuff like movement range, accuracy, damage, hp, etc, etc)

Everything was working fine, but since function indexes don't lead to very clear concepts (movement range was "unit_list[unit_index][4]" for instance. I actually did not know what unit unit_index represented, but I made the program look for the unit I clicked inside the array and work with it.) and there's all this talk about OO...

Well, I tried to put shit in classes. A list of objects was my idea, so I could organize, and maybe as I go learning, toy with this OO thing.

Well, long story short, I don't know how to copy the actual objects into the list, they end up referring to the same object, and shit stopped working right, some functions I could fix, modify as needed, but the function to put the object in the list...

Now I have to revert to an earlier version, big waste of time...

And how do you split files? I did not know you could have several files with code being a part of the same program.

EDIT: Just clarifying what I wrote.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
God Bless ctrl+z. Saved the work I did last night. Except for the failed attempt to use classes.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
You understand the concept of references and copy right?

Why would you want to copy a object that you have already initialized into the list?
(there are reasons, involving defensive programming - avoiding badly designed parts of the program you don't know about modifying things behind your back while you still use the object - and threads)

This is part of what i meant about stateful and "organizing your functions":
Your functions and subfunctions should always leave the object in a consistent state, and that is much harder if there is lots of state. You might find that your logic will not work with a inconsistent state, and be tempted to add hacks. Avoid it if you can - go back and find the code that did it. Let me give you a example of "inconsistent" state:
Code:
//invented syntax
int x, y
rotate(int degrees):-
x = x cos degrees + y sin degrees
y = − x sin degrees + y cos degrees

You should see the error quickly. Not so surprisingly, the way to avoid inconsistent state in this case, is to make a temporary variable and make sure at the end of the function that the x and y are in consistent states. Tests/asserts are useful to detect this, but they are not part of your program the output should never be tested at runtime except if you're doing military computers that have to check about cosmic rays and shit. The input is permissible, at the boundary of your code, if you're using shit libraries.

Not coincidently, code like the code above is one of the reasons that recent languages "copy" primitives into functions instead of using pointers.
dosomething(&x) might not work so good if it uses x inside the function and the argument. It doesn't avoid the class of errors like the example shows, but it is not quite as mysterious.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Your program flow should be like a Relay race. The token is the object/state, the functions are the runners. The primitive function that handles all tokens (objects/state) in a list should get them from the container, and pass them to the other ones (and their subs) by putting them in the argument list of the others. This way, you can control accidental modifications. It is advisable not to use them again after "passing" them. They might have changed, and the only way you'll understand how, is to have very clear names for the subfunctions (and they only do 1 thing ofcourse). Don't go into contortions to avoid it however.

This will guide your structure. Classical structural top-down design.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
But hey, i bad programmer anyway. Go on and persist. Bugs get found eventually. Bad design is forever though (as i well know)
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
SCO said:
You understand the concept of references and copy right?

I understand the concept, although sometimes I don't remember/confound which command does copy, and which ones does only reference the same item.

SCO said:
Why would you want to copy a object that you have already initialized into the list?

Because I might have several tanks, identical ones, except for the starting position and current hp. So I create a list from a template, change the values for x and y (position in the grid) and add them to the unit_list list. So when I access unit_list[0], it's the first tank, unit_list[1] is the same as in the same model, but not the same unit.

I'm not sure that's the "right" or best way, but that's the way I could think of.


SCO said:
This is part of what i meant about stateful and "organizing your functions":
Your functions and subfunctions should always leave the object in a consistent state, and that is much harder if there is lots of state. You might find that your logic will not work with a inconsistent state, and be tempted to add hacks. Avoid it if you can - go back and find the code that did it. Let me give you a example of "inconsistent" state:
Code:
//invented syntax
int x, y
rotate(int degrees):-
x = x cos degrees + y sin degrees
y = − x sin degrees + y cos degrees

You should see the error quickly. Not so surprisingly, the way to avoid inconsistent state in this case, is to make a temporary variable and make sure at the end of the function that the x and y are in consistent states. Tests/asserts are useful to detect this, but they are not part of your program the output should never be tested at runtime except if you're doing military computers that have to check about cosmic rays and shit. The input is permissible, at the boundary of your code, if you're using shit libraries.

Not coincidently, code like the code above is one of the reasons that recent languages "copy" primitives into functions instead of using pointers.
dosomething(&x) might not work so good if it uses x inside the function and the argument. It doesn't avoid the class of errors like the example shows, but it is not quite as mysterious.

Most of my functions leave the original list intact, except when I want them to modify, which is the case of the move(ind) function. This function gets an unit, by it's index (ind) found and returned by other function, and modifies its x and y values.

I still have to add more units, right now there's only tank. But it's quite easy to do so, since I just have to follow the same positions in the new unit template and all the functions will work with them.

So in the end, I have a few list templates:

EDIT: When I say attributes in a list, I don't mean attributes in a programming sense, I mean unit attributes, like the movement, range, hp, etc. The "attributes" in the list tank are variables. I will quote "attributes" when they refer to game attributes, not programming ones.

tank[several "attributes"]
future_units[several "attributes" in the same order to conserve indexes]

A working list to use on my functions:

unit_list[tank, tank, future_units, etc]["attribute" index]

And inside tank1, tank2, I have mostly the same values for the "attributes", except for x, y, current hp, has moved this turn, has attacked this turn.

This way works fine, because the templates can have the same name, and be the same, and when I use unit_list.append(tank), the program adds a new list to unit_list, NOT just the references. Which was my problem with classes. I just added references to the same object, and I don't know how to create multiple objects with the same name in a list, I don't even know if it's possible.

You might ask, "why not just call your second tank "tank 2"?"

Well, because I can simply create (as I have done) a function that skipping the error control, messages, and menu opening to choose which unit parts, says simply:

unit_list.append(tank)
graphical part here

To use tank2, instead of tank, well... I don't know how to do that. unit_list does NOT, as far as I know store the template list name, so there's no way to check for a "tank2" object, so that it can impede the program of adding it again and thus creating the 2 references 1 object problem.

Also, I don't think a loop would work, since I can't make:
variablename_number = blah blah blah
while changing just "number" in the variable name. And if I could, I would still need to bypass the "checking if there's already a variablename_number" in the unit_list.

EDIT: Actually, with objects, I think I can create a loop which changes one attribute, so it might be possible, something like tank.number.changing_variable = template
But then I would have to acces them by writing tank.number.1.attribute.
Which is a lot of writing.

I could create an object with an extra attribute, that tells the number of the unit, and a function that checks if there's already an object with that number in the unit_list list. But by fucking jesus, that's a lot of work, and I might end up running into some problem I can't foresee and can't deal with later.

I hope what I wrote is clear, communication is hard enough without one of the parts not understanding exactly what it's talking about.
 

snoek

Cipher
Joined
May 5, 2003
Messages
1,125
Location
Belgium, bro
hacking == bad indeed,
if you find yourself applying hacks, go back & do a rewrite of the code that caused the problem
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Correct way to prevent a object being added twice:
Just don't do it. Add the objects you will use at the start of the program, or immediatly after creating them. Don't add objects you "got" from the list.
Alternative ways, descending in ugliness and performance properties.
Set datatype: checks if the object you added is already in the set. Doesn't add if so.
Map datatype: same, but checks a key instead of the object (as you would expect, most sets are disguised maps with the object itself as key).
List : remove the object before adding it again. There are some performance optimizations you can do depending on the type of list, but just don't do them now. This is the slowest "simple" data structure to modify in the middle.


The following advice applies only if you want to do O.O.

If you use these kind of lists with objects, you're trying to use the flyweight pattern ... whether you know it or not.
It is something i would dub, "experts only" since it is a way to "escape" object orientation for a memory optimization that might not even work, depending. Just organize your attributes as a plain class and clone the object or create a new one. Thus you would only have 1 list of "game entities" or something like that.

Whether you know it or not, a new list IS a object of a predefined class, just with a special syntax.
At this point i recommend you to read the python syntax for creating objects and classes.
Creating a class, will immerse you in a few new concepts too, constructors etc. Just read it.

http://docs.python.org/py3k/tutorial/cl ... ion-syntax (class syntax)

A aside:

A trick some games use is to keep various lists/sets, one for things that collide, one for things that don't collide, and whatever other disjoint calculation that is costly (don't store the same object in different lists unless you want bugs and hacks). When you iterate over these lists, to draw, collide, move, if you already separated the subsets, you can optimize the function calls if you're careful.
This is a kind of "logical" partitioning. There is also region partitioning optimizations, that can be better. As always, the trick in computing is to minimize the moving parts, speaking metaphorically.
If you are iterating over the same list twice on a "game cycle" you are not being optimal however, on at least one respect, since by definition, you could have done it on one list for all objects and make them ignore the commands that make no sense.
My advice for now? Forget optimizations.
 

acolyte

Educated
Joined
Jan 24, 2010
Messages
107
This may or may not help you in your problem with classes and instances:

Code:
class Tank:
    x = 100
    y = 100

print "Note that in Python \"classes are objects in their own right, even without instances (quote from \"Learning Python\"). "
print "(" + str(Tank.x) + ", " + str(Tank.y) + ")\n"

objectList = []

def createTank(x, y):
    tank_instance = Tank()

    tank_instance.x = x
    tank_instance.y = y

    objectList.append(tank_instance)

def printObjects():
    for obj in objectList:
        print "(" + str(obj.x) + ", " + str(obj.y) + ")\n"

# Populate list with 10 tanks.
for i in range(10):
    createTank(i, i)

print "Printing all objects in list (here only tanks)."
printObjects()

(Note that I'm not a Python programmer, and this is for illustration only)
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Forgot. Languages normally have a "static" property keyword.

In most, this means the attribute/property is common (shared) to all object of that class. There is your way to have a common mesh - you will want this to be immutable to prevent surprizes - you'll want one for damaged objects too, but if you want that static or not depends on localized damage and the degree it shows, if its generated dynamically etc.

Fun!
 

acolyte

Educated
Joined
Jan 24, 2010
Messages
107
I don't think so. It's more likely that objects with 3D representation would contain something like a pointer to a mesh/geometry object. Plus this way their 3D representation could change dynamically at run-time. Static - not such a good idea; not in this case anyway.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
It would have the "pointer" (current_mesh) anyway. It would only start with it assigned to the static object. It's the same optimization that he is doing, but less messy. You can also do it purely functionally, by passing the same mesh object to each new object. But then you have to have the mesh object accessible somewhere else (that might be a good idea, i always had a class to read files to objects too).

BTW, the poster above is right in that "static" behaves badly with classes: you're basically saying that the static attribute is relevant - without modification - for all subclasses too. Which is pretty :M . Overriding statics is impossible for fields in java (only methods) dunno about python.

One of the reasons i dislike statics and singletons. The functional/constructor approach avoids this.
So i guess he is right after all, don't use static unless you are sure you are at a inheritance leaf. Lol backtracking.
Pass the meshes you want to share in the constructor/factory function.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Guys, thanks for the enthusiasm, but slow down. All of the posts were hard to understand because of a lot of concepts mentioned that I don't know, but these last ones overdid it.

I read the Liskov substitution principle, and you are right, I'm not sure I understand.

And I'm also reading about classes, read yesterday before trying to convert.

"Note that in Python \"classes are objects in their own right, even without instances (quote from \"Learning Python\"). "

I realized that yesterday, if you create a class called tank, you can go and start attributing stuff to tank without declaring that tank is and object of the tank class.

Correct way to prevent a object being added twice:
Just don't do it. Add the objects you will use at the start of the program, or immediatly after creating them. Don't add objects you "got" from the list.

But that's the thing, from start I need several equal objects in my list because I have to deploy several tanks, and they're all equal.

Maybe it's a naming thing I got wrong? And I'm calling object what I should be calling "object instance"?

I will take a look at acolyte's example and see what I can understand

If you are iterating over the same list twice on a "game cycle" you are not being optimal however, on at least one respect, since by definition, you could have done it on one list for all objects and make them ignore the commands that make no sense.
My advice for now? Forget optimizations.

Not only twice, several times on a game cycle.

But optimization is alien to me. You mean as in making the program go faster (more efficient)? Well I have no clue whatsoever what sort of code is faster or slower. None at all. So can't deal with that.

The "static" property keyword flew over my head. Don't understand that. Don't know what is a mesh or inheritance leaf either.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Forget about optimization now. You will have a data structure (list whatever) that you will cycle in each pygame engine main method. Then you will handle player input, find collisions, update things based on collisions run ai and draw.

You're going to need pathfinding code eventually if your game is to be interesting (ai avoid obstacles, not getting in each others way etc). This will be the hardest part if you don't cheat by faaaaaaar (real path planning with obstacles).

This is crazy stuff, i don't know the python pygame equivalents:
http://www.critterai.org/nav
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom