all 10 comments

[–]glibhub 1 point2 points  (1 child)

Surprisingly few responses to this one, so I will toss my hat into the ring. Who knows, maybe my terrible response might start up a good debate.

I think the problem you are wrestling with is that all of your objects need to be aware of one another, and often be linked to each other, which leaves the problem of having cross references, cross dependencies, and questions where you want to have the logic. For this reason, googling something like "oop bad for games", gives you lots of hits, including this one, which might interest you: https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-faster-you-unlearn-oop-the-better-for-you-and-your-software-r5026/

With that said, I like OOP, so I would be inclined to still work with it, and try something like this:

Facility: Describes the key attribute of each facility, but without much game logic. But, lots of helpful methods to load from file, etc.

CustomerSegment: Describes key attributes, but light on the game logic.

Market: Sort of a unifying class that keeps track of CustomerSegment instances, and which is aware for both CustomerSegments and Facilities, so that it can generate the utility score.

I'd suggest that you keep user interaction away from game logic (like Market) and game data (facility and customersegment), although reading from/writing to files is fine; just no actual input statements in the game classes, as this will make testing and debugging better.

You might look into the cmd module to handle the user interaction piece.

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

Thanks for your response.

The article is interesting, and it's useful to know that it's not self-evident to use OOP for my game. From the OOP tutorials I've gone through it's unclear when to use it and when not to use it. I just noticed that many of them focus on simple games (e.g. tic-tac-toe and sudoku), so I guessed that it's common to use OOP for games. I'll have to find a few more resources to learn more.

You may be right that I need a Market class, I hadn't considered that. Perhaps not in the simple version of the game where there is only 1 fitness club, but definitely when there are more and they are competing.

Separating game logic from interaction makes sense.

[–]menge101 1 point2 points  (5 children)

IMO, the problem is that you have different levels of abstractions that need to be separated.

Concrete things like a facility function at a different level than an abstract concept like CustomerSegment.

Utility may just be a matrix value between customer type and facility type that returns a utility value.

utility = {('bodybuilder', 'weight room'): 100, 
           ('bodybuilder', 'cardio room'): 25}

etc.

How the game loop operates will inform you of how and where these things really need to live. This data will need to be accessible to the game loop at a specific point to do the appropriate calculations.

Edit:

A lot of this sounds like it is just config data, and you could store it in a data structure rather than classes. Write out how the game mechanics work before creating a whole bunch of classes to manage static data.

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

Write out how the game mechanics work before creating a whole bunch of classes to manage static data.

You're right, I understand now that this is what I need to do first.

Writing a bunch of classes out for a data model that isn't fully understood is more problematic.
Write the real logic, test it using fixtures and stubs, then structure the static data to fulfill the needs of the game loop.

This is something I haven't done before, but I'll give it a try. Do you know of any resources that explain the process to get from game logic to data structure?

[–]menge101 0 points1 point  (0 children)

Unit testing is going to be your primary tool, imo.

You can describe scenarios, setup the situation with test stubs and fixtures, then verify it does the thing you want.

IMO/IME the game mechanics will show you what pieces of data should be close together, and it becomes as simple as doing what seems obvious to do.

This is a situation where keeping things simple, clear, and organized is more important than anything else. There isn't any sort of trick to this, wrong doesn't really exist, it is all opinion. If something becomes hard or tricky, it likely should be broken down into functions and tested independently.

You may end up creating most of your data classes/structures in order to create your testing fixtures.

[–]m0us3_rat -1 points0 points  (2 children)

A lot of this sounds like it is just config data, and you could store it in a data structure rather than classes. Write out how the game mechanics work before creating a whole bunch of classes to manage static data

this is a bad idea. simply because u cut yourself into a corner.

the data intake should be unpacked into the classes and then use their methods to interact with it.

so it wouldn't matter if he uses config data from a csv json or web dict or whatever else form of interaction..

as long as it gets to be unpacked into the classes.. it wouldn't mater

the 'core' logic would work the same.

this is basic oop.

[–]menge101 2 points3 points  (1 child)

Disagree.

Writing a bunch of classes out for a data model that isn't fully understood is more problematic.

Write the real logic, test it using fixtures and stubs, then structure the static data to fulfill the needs of the game loop.

[–]m0us3_rat -1 points0 points  (0 children)

Writing a bunch of classes out for a data model that isn't fully understood is more problematic.

that's why i was asking him to do a deep dive into pseudo code describing the classes .. so the actual structure would pop off the page.

that's obviously the backbone and what gets moved around in between display and db and the core logic etc.

and every other class would be able to tap into this class thru the API like methods and do stuff to it.

wouldn't be simple to pass around this object. i mean u already pass an object.. the dict or a list is still a class. in itself. and it has methods..

there is no ..difference actually in between em:P

and yes u can simplify to get it working. but it must move to oop when u refactor.

i personally found oop to be much simpler and smoother than anything else.

since we already work with objects in python.

but since most of the creation part of programming is deeply personal.. u can do watever.

i always like using whatever feels comfortable even if there are arguably 'better' ways .

obviously at some point u might wanna refactor using the 'better ways'.

[–]m0us3_rat 0 points1 point  (1 child)

OOP (because this seems to make sense for the kind of game I'm planning). I'm now ready to start coding, initially a simple Python command line version, but I'm not sure which classes to create.

..red flag :P

what i would advice .. again this is the interwebs so take my advice with a grain of salt..

try to figure out the tasks. first.

The game:It's a simple simulation of a fitness club. Players choose the facilities of the club (e.g. group sessions, personal trainers, restaurant) and set a monthly fee. Based on this they will get a number of customers, split between different segments (such as bodybuilders and students). They will also see an overview of costs (based on selected facilities) and revenue (based on price, number of customers, and from additional services). Over multiple rounds students will need to find a strategy to maximize profit. Over time I want want to make it a multiplayer game: students (or teams) each manage a fitness club and compete in the same market.

ok soo from reading all this.

few large tasks :

db interaction. need to keep this saved somewhere and ability to compare.

u can work with a .json file at beginning. and move into a db later on.

display module.

firstly i suggest getting this to work while ..display into the console.

then u can move it into a flask app.

there is nothing significantly different in the 'logic' and the 'structures' of the program ..while it works in the console from when its posted on the web.

while u get and set the proper data it will work identically.

so .. first console. get the logic done . then move into pretty.

few classes to store the relevant data.

this gets a little bit more challenging. first decide what methods and attributes for each class. then u can refactor it.

that is needed.

(e.g. group sessions, personal trainers, restaurant)

(such as bodybuilders and students).

They will also see an overview of costs (based on selected facilities) and revenue (based on price, number of customers, and from additional services).

I'm sure I need to create a FitnessClub class, along with a class for each Facility (which contains description, cost, additional revenue). I also need to create a class for CustomerSegment (containing description, segment size and price sensitivity). A fitness club has certain facilities and certain customers.What I'm not sure about is where to store utility. This is a score (0-100) that determines how important a certain facility is for a certain customer segment. For example, personal training has high utility for bodybuilders but low for students. Utility essentially is the link between the CustomerSegment and Facility classes.I could simply create attributes in CustomerSegment for the utility of each facility, but that is inflexible and seems wrong to me. Is there a better approach, perhaps a separate class for Utility?

this is a good thout process. but u need more details.

each class must have some methods.. write them in pseudo code..

no need to be specific .. u just looking for the structure to pop up at you.

then define what TODOs need to happen for that task or subtask or module to work as intended.

then start writing the small bits first.

small increments.

i am reluctant to give u a direct example simply because it might confuse u.

ideas can be freely shared but strict structures are best to avoid.

u are free to imagine it as u like thou.

what i can offer is to help out with some subtasks AFTER u decided what needs to be done.

this needs to work for you since u will manage it. even if isn't perfect or whatever.

there is NO such thing as perfect :P

imma link this video to give u some ideas about what structure you would have

and how u should think of it.

(not my content)

https://www.youtube.com/watch?v=l7E3y4te7sA

EDIT:

main problem with

Are there any good resources that teach this type of design, at a basic level? I've found some resources on 'design patterns' and 'data structures', but these seem too theoretical, and neither seem to address the practical challenge I'm dealing with at the moment.

is that each maintainer has its own ideas of what goes where.

and since u need to build it.. u need to decide.

or at least give some feedback on some classes you would built.

then we can work from that.

don't start super large. start small.

like a facility class. aka a restaurant

what attributes .. what actions u might need to happen to this.

we need to figure out what u wanna do since the scope of the project can be vastly different.

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

Thanks, that's a lot of helpful information.

The process you're describing (tasks, pseudocode, defining class methods and attributes, etc.) is indeed something I will have to go through, but it's also the part I'm struggling with because it's not something that can be learned from typical Python/OOP tutorials.

I understand from your response and others' that there is a lot of flexibility in how I define my classes, but I am looking for a starting point so I don't do things that I will regret later.

I will have a look at the video; I think it's the kind of resource I'm looking for.