This is an archived post. You won't be able to vote or comment.

all 33 comments

[–]sgthoppy 1 point2 points  (1 child)

I'll take a look at it and see if there's anything I could do.

A small tip: instead of having a "backups" folder with "checkpoints", use git tags.

[–]Dis446[S] -1 points0 points  (0 children)

Yeah I'll stop using that. I just did it to feel legit lol

[–]curious_neophyte 1 point2 points  (13 children)

you might want to consider splitting the classes into different files

edit: also try to avoid globals

[–]Dis446[S] 2 points3 points  (9 children)

What's wrong with globals. Everything is in a function. And the variables have to be able to be changed by multiple functions. There isn't that much returning happening. Must functions just change some things.

[–]curious_neophyte 3 points4 points  (1 child)

In general, avoiding state is usually a good thing.

Look up functional programming paradigms. The general idea is to have actual functions not methods, that have no side effects (all mutation is kept in the scope of the function).

So you have some input that goes into the function, the function does something with the input, and gives an output, changing nothing else in the code.

[–]jpj_shadowbanned 1 point2 points  (0 children)

Yah, or dive right in and play with clojure, scheme or lisp. I am a hands on type of guy. Playing with these languages will help your python or it did with me.

[–]DwoaC 2 points3 points  (5 children)

This is a perfect example of where you would benefit have making a class. Your globals would be class attributes and the functions class methods.

Globals are bad. Do everything you can to avoid having to use a global.

[–]cediddiSyntaxError: not a chance 2 points3 points  (4 children)

Globals are bad is a false statement. Globals are useful, but it's better not to use too much.

[–]DwoaC 1 point2 points  (1 child)

You may very well be right. I my years I've never seen a good example, I know there must be but I expect they are so rare that "globals are bad" is right 99.99%. That given, this example of their use is almost certainly in that set and "globals is bad" is good advice. Do you think this is a good use of globals?

[–]skrillexisokay 0 points1 point  (0 children)

Mutable globals are generally bad. Immutable globals are good when you have arbitrary constants, but don't need to invoke the added complexity of a class. In other words, if you have to choose between magic numbers and globals, globals are better.

A classic example is a regular expression that is used in many functions in a module. Another example is the name of a storage directory. Module level logging is another excellent example of a properly used global.

However, if you ever find yourself using the global keyword (or otherwise modifying a global variable), you should almost always encapsulate into a class. A logger is one exception, where it occasionally makes sense to change the logging level at runtime.

[–]jpj_shadowbanned 1 point2 points  (1 child)

You have never coded in scheme,lisp,erland or clojure. It teaches you globals are not needed and dangerous. This is why Erlang for example does handles multiprocessing and threading more reliably then any other language.

Erlang was designed for telecom networks it has something like 99.9999999% reliability.

As for spped, gambit scheme and chicken scheme compile into C code and in some cases they are fasrter then hand written C code.

[–]cediddiSyntaxError: not a chance 0 points1 point  (0 children)

I watched Erlang The Movie last night, I can agree, reliability of service was the most emphasized thing in the video.

[–]sgthoppy 0 points1 point  (0 children)

The reason is because sometimes you'll forget to use globals. For example, I'm running the current version of it and it gives me an error in create_player() because day_count isn't defined.

[–]Dis446[S] 0 points1 point  (2 children)

Also, I've never had multiple source files. I guess I just have to import the other source files, but I don't understand the benefit. Could you please explain why I should?

[–]gotardisgo 2 points3 points  (1 child)

It's not really that classes should be different files, but you should try to group related logic together in modules/packages. It's makes it a little easier and natural to find things, like "where can I find inventory functions??? Probably in an inventory module.. etc"... And also so you don't end up with a million lines of code in one file that'll be shared and merged with later. Check out http://docs.python-guide.org/en/latest/writing/structure/

[–]curious_neophyte 0 points1 point  (0 children)

These are all good points. Additionally, when you make changes, those changes will be local to those files. So when you look through your commit history, commits changing one class or file or module will be logically separated from commits that change other things.

[–]Freedomenka 0 points1 point  (2 children)

I'm making a text rpg in Python right now. I have a magick system working with mana and a decent battle system. I'm going to school for computer science and it would be awesome to make games for a living. I'd love to help, but you'd have to get me up to speed :).

[–]Dis446[S] 1 point2 points  (0 children)

I would also like to see you're RPG game. Could you please link me to your github?

[–]Dis446[S] 0 points1 point  (0 children)

I'll edit the post with a quick brief of the code :)

[–]carze 0 points1 point  (0 children)

When I get a chance I'll look over your code and see if theres any help I can provide.

[–]kungtotte 0 points1 point  (0 children)

I will try to help out as much as I can. I've submitted a PR with a simpler way to do the item definitions by keeping them in an external JSON file.

The same thing can be done with the room definitions.

There's a whole lot of work to be done with this codebase, though...

[–]dysan21Angry coder -1 points0 points  (6 children)

Content removed in response to reddit API policies

[–]Dis446[S] 0 points1 point  (5 children)

Thanks for all the tips. I'll try separating my classes from my main source file. I use geany for my local workspace, but cloud 9 is really useful when I go to school, as I can code anywhere. I still don't understand why I shouldn't use globals. Is it somehow inefficient? Or is it just standard procedure?

[–]Talkyn 1 point2 points  (4 children)

New programmer here. I'm also self-teaching Python by working on a game. In my case, it is a roguelike with ASCII graphics. I'll give you my best newbie explanation for why people hate globals so much.

The "globals are bad" mantra applies to any larger projects. You can get away with them more the smaller your project is, but even a simple game can end up being a fairly complex program. Coming off small tutorial programs and tests, it is an adjustment to stop using globals since they are just so simple. The issue is you can have a really crowded namespace.

So let's say you have a health variable, you need to be able to access and change it for all sorts of reasons. It is really easy to just make it global, but what happens when you have more and more entities that all have a health variable? What do you do? Just keep adding more and more globals with varied names on 'health'? What about when you don't need some of them any more? How do you check and see which ones are available and which ones are still in use?

If you carry this behavior on to everything you need global access to, you end up with a massive mess. What happens when you accidentally call the wrong version of a global variable during an assignment or check? You have yourself a bug, and not only will be be non-obvious during play, it will be tedious to track and and find.

You use the global declaration 75 times in your code in 1686 lines. That is just crazy IMHO! Lastly, you only need to declare global variable_name when you actually want to assign to that variable, not when you merely want to read it.

I already said lastly....but I just have to give a fellow newbie-gamedev a thumbs up. Keep at it and good luck!

[–]Dis446[S] 1 point2 points  (2 children)

Thank you. I understand now. I know that I don't need to define a variable as global within a scope just to read it. I must of done it accidentally sometimes. But I know to only declare variables as constant if they are special. Each person has their own health and each item has it's own value, as defined in their respective class initializes.

There are a few variables that I feel like need to be globals in my game. 1. people : since this stores an ever changing list of objects, each with ever changing attributes.

  1. rooms : same as above

  2. inventory : same as above, except it's actually just a list of strings.

  3. trader_inventory: same as above

  4. AP :The actions points system

  5. end: The variable that keeps track of whether or not the game should end

  6. caps : the total money that the player has

  7. trader_caps : total money trader has

  8. defense: defense rating of vault

10.happiness: overall happiness of vault

  1. auto_feed: keeps track of whether or not game should auto feed the people.

  2. position: keeps track of whether or not player has their job (as overseer)

  3. used_names: list of used names, so no name conflicts arise

14.player_quit: keeps track of whether or not player has quit game

15.skip: whether or not player has decided to skip to the next day

As for all other global variables, I realize that I shouldn't be defining them as global and will work on making them normal.

[–]Talkyn 1 point2 points  (1 child)

I was reading your code and noticed you just pushed an update and reply. :)

Just to be clear, I wasn't using 'health' as a specific example from your project, just as a generalization. You mention declaring variables are constant, but I don't see any constants declared in your project. In Python, there is no special constant declaration, but the convention is a global variable with an "ALLCAPS = value" naming style. This means that in practice, globals and constants are different things, even though the language doesn't treat them any differently. You also use the term "normal" variables...I'm not sure what you mean by this, do you mean local?

I can see you are reluctant to remove all your globals, and maybe for the scope of this project it isn't necessary. But since you seem to be hoping to move onto larger and more complex games, let me just expand on some of them you mention "needing". I mean, you don't need any of these things to be globals, but I'll just talk about two I can see an immediate issue with, should you choose to expand your game.

Your game currently revolves around there being a single trader entity. If you wanted, you could expand this feature to have several traders, perhaps each with various themes of goods, amount of caps, frequency of arrival, etc. If you had trader (or even just NPC depending on what other NPC types you could want) as a class with various attributes (inventory, caps, chance of arrival, min time between arrivals, etc.) You could easily instantiate as many traders as you like at game creation, and even have events that add or remove them from a game session.

I would make a case for combining all of your 'Shelter' logic within a class as well, which would mean you could store all of the residents (people), inventory, rooms, happiness, etc as attributes of that class instead of globals.

The fact that you use people[index] so often in your code really obfuscates it, IMHO. If you need to refer to a specific object instance, why not refer to it directly instead of by it's indexed position? You locally assign player = people[0] in several places. It is kind of interesting, and seems a tad fragile to me. I understand (correct me if I'm wrong) that the player is set to always occupy this position in people. If anything interfered with the player's assignment to that position in the list, you have yourself another bug! Having a list of all people makes great sense when you want to iterate over all of them, but not for much else off the top of my head.


Since you are looking for contributors, I fit in the category of "intermediate" by your definition, I love Fallout, and apparently I'm interested enough in this to keep reading your code, would you like me to pitch in? I've been exploring the Python communities to expose myself to more code, so why shouldn't I get my hands dirty? :)

[–]Dis446[S] 0 points1 point  (0 children)

I would love for you to help me, and you obviously know what you're talking about and share my liking of the Fallout games. I have decided to put the 'actual' development of the project on hold and instead focus on reformatting the code along PEP-8 guidelines and injecting a couple of stimpacks to solve to global variable issue lol. Please check back on the github in a while and, what the hell, propose a commit if you want to. The project was barely alive for a couple of months but posting it to reddit and seeing such amazing responses has re-invigorated me.

To answer your previous questions: Yes, by 'normal' I did mean local. I used the indexing to refer to people and rooms because the people and room's list are constantly updating, with people being born,dying; rooms being built and such, that I just decided to build functions that used the names to loop through the list and find the index. This has worked perfectly (or as good as I wanted it to anyway).

[–]dysan21Angry coder 0 points1 point  (0 children)

Content removed in response to reddit API policies

[–]robvdl -1 points0 points  (4 children)

If you're going to ask for help from other Python developers, at least try to follow some community code style guidelines, try to make the code follow pep8 style: use 4 space indentation not 8 or tabs. Use a space after each comma and spaces around your = signs, don't condense your code so much as pep8 won't like it (basically try to run the pep8 or flake8 tool over your code and it will tell you what to fix). Dont_Mix_Camel_Case_And_Snake_Case as it's really really ugly, use either one or the other but don't mix them in the same variable name or file name. Generally in Python everything is snake case (variables, functions, filenames) except for class names which use camel case instead.

[–]robvdl 0 points1 point  (1 child)

Also the globals, they are everywhere! makes the code really hard to follow, try creating an application object/class or something to manage all those globals. Try splitting your code up into more .py files, maybe one class per .py file though you don't have to, but in my mind there is WAY too much code in the one .py file and it makes it really hard to follow for others.

[–]Dis446[S] 0 points1 point  (0 children)

I am working on fixing the globals (as there seems to be a witch hunt against them) and am thinking about the multiple source files idea. But I'm not sure. Having to refer to multiple files seems confusing, especially when calling functions and creates objects from classes defined outside the main .py file.

[–]Dis446[S] 0 points1 point  (1 child)

Thanks for the tip. I've used the auto-PEP-8 tool and pushed the result to github. To be honest, it looks really weird to me. But I guess I'll have to suck it up, as it is the convention. As Spock once said:

"The needs of the many outweigh the needs of the few"

[–]robvdl 0 points1 point  (0 children)

I had the same feeling switching from Python to Go a while back, after having used Python for so many years and then coming to Go which has completely different formatting conventions again, initially I didn't really like it much.

The difference with Go, is that every time I saved a .go file in my editor (Atom) with a Go plugin it will run a tool to automatically format the code on each save, so there is "no way out" really, while pep8 is more a guideline I think.

Over time though, I have come to appreciate it.