Jump to content
  • Advertisement

jlyco

Member
  • Content Count

    5
  • Joined

  • Last visited

Community Reputation

114 Neutral

About jlyco

  • Rank
    Newbie
  1.   Heh, yeh I just sketched that out quickly...was just revelling in the ease of access to those nested variables, y'know?         True, I was thinking about using structs here. Since I've decided to place the functions elsewhere GameData may aswell be a struct. I'll likely make a GameEngine class which owns the GameData and operates on it, and owns some other helpful objects of its own.         Good tip... I'd always try to make sure to be very careful to preserve the invariants on a case-by-case basis within whatever function, like making sure a player's money doesn't go below zero etc.         I guess another reason people advise against public variables because it will be harder to track bugs, because there are more access points to the data. While this is true, in this case the game logic & data will be all contained in GameEngine and I can restrict access to that from the rest of the game code, so bugs in the logic shouldn't be too hard to track IMO.   Thanks again for taking the time to give input, it's very helpful.
  2.   True, that's a pretty good description. I asked that question on SO and got a pretty good answer as well: http://stackoverflow.com/questions/34022697/terminology-for-class-objects-related-by-composition
  3. Thanks for the reassurance! I guess when designing a modular composition-hierarchy for a complex object, there sometimes is no easy answer like you say. The contained sub-objects and functions will just have too many intertwined dependencies to split them in a nice way. Broadening the access is never good but can't really be helped. To me it's still better than storing references to the required data or passing lots of parameters around. I guess the most important thing is that the code works and is reasonably clean, not that it's a flawless example of OOP design ;D
  4. Thanks for your post, it was very helpful. Always good to see how other people approach a problem.     Ah, so in this case, board and freeParkingMoney would be public members? To me that seems fine, though I keep reading how having public variables / getters in a class would be bad design.   (I am not sure what terminology to use in C++ for composition... ie. if A has a member B, how to describe their relationship? All the suitable words like parent, child, root, base, sub-object, they all seem to be used to imply inheritance, haha. I'll say B is a sub-object and A is the root object).   Anyway, it seems perfectly fine for me to allow GameData to publically access its sub-objects, and their sub-objects, or indeed any data contained within it, directly. Though it definitely seems to be frowned upon. It would just be so much easier. I mean, the whole buyDeed function could be written like: void buyDeed(ID deedID, GameData gameData) { auto &activePlayer = gameData.players.find(gameData.activePlayer); auto &playerDeeds = activePlayer.ownedDeeds; auto &bankDeeds = gameData.board.bank.ownedDeeds; auto &deedToMove = bankDeeds.find(deedID); auto &playerMoney = activePlayer.money; if ( playerMoney > deedToMove.cost() ) { transferDeed(deedID, playerDeeds, bankDeeds); playerMoney -= deedToMove.cost(); } } I can only imagine what a mess that would be using best-practices and private data, if each sub-object could only access its own data. I'd need to write a load of member functions in each sub-class and pass through them all. And I'd need to pass as a parameter the required data so the function at the bottom has it. TBH there'd be a load of getters/setters anyway, so the members may aswell be all public. They are all sub-objects related to the root class of GameData anyway, it's not like i'm exposing them to the rest of the game code.   What does everyone else think?
  5. I'm pretty new to gamedev and I'm starting to make more complex games, but handling the growing amount of data, classes and functions, while still trying to use best design-practices, is proving tricky! Hypothetically, say I want to make a version of the board game "monopoly". In very pseudo-code (I'm using C++ but this probably applies to other languages), I'd try to model the data showing the current state of the game like this:   class Board { private: container<Square> squares; //board locations to land on. Square is a base class //from which classes like Property, Station inherit container<ChanceCard> chanceCards; container<CommChestCard> commChestCards; Bank bank; //to begin, bank owns all Deed objects, which are linked to Property squares unsigned freeParkingMoney; //amount of money in the center of the board //that you win by landing on free parking //etc.. }; class Player { private: string name; unsigned money; Token token; //hat, iron, shoe ... container<Deed> ownedDeeds; //etc }; class GameData { private: Board board; container<Player> players; Dice dice; Player* activePlayer; }; Rather than having a huge class with all the states in, GameData, I've tried to use modularity and break things up into sub-parts, using composition. (There are some missing class definitions of course, this is just a sketch.) This is all separate from the game's rendering / state stack / gameloop / input handling etc. The problem with this comes when a player wants to take some action in the game. For example, say I wanted the current player to buy a property deed using the function buyDeed().     How does it access all the data it needs? I have reduced the size & responsibility of the GameData class and made everything more modular. But on the flip side, the data is spread all over the place and hard to connect together. buyDeed() would need access to GameData::board, and then Board::bank, and then Bank::deeds. Then it would hand over ownership of that deed and give it to the active player, and have the player pay for it, which requires access to GameData::activePlayer, and Player::ownedDeeds and Player::money. I'm not sure how to address this - I could make a lot of the data global/static/public, which is generally considered bad design. Or store a reference/pointer to each dependent object in each class - which tightly couples all my classes.         2.    Where should the function go? Because the function would act on a lot of data in several different class scopes, it isn't clear where to define the function. I could pass the dependencies along through member functions in each class, so each class operates on its own data, using pass-through functions - but that would quickly lead to spaghetti code I think, and it would be hard to track the program flow. Or have the logic in a separate GameEngine class that can modify GameData - that would be nice and separate, but I get back to how GameEngine accesses the data. I've tried reading up on game design patterns, like dependency injection, or components etc. But most articles focus on decoupling the rendering / physics / input in games, not amongst the actual game data in a composition-style design. So I'd be interested in how more experienced gamedevs would go about approaching this. Or, if the design is just in general bad, how you would fix it? Thanks!   [edit: typo]
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!