Domain-Driven (Game) Design
Naming and terminology of a game (and other applications) follows a convention (depending on its genre).
Objects are typically expressed by nouns (N) like: Health and Player, Item, Inventory, House, Room, Location.
Methods are typically expressed by verbs (V) like: refill, regenerate, store, add, move, enter, etc.
Depending on the narrative (story / theme) of your game these terms may vary. Same applies for designing other (business-)applications, where terminology is driven by the subject / domain and it's language used locally (by users).
Language from the context provided (narrative)
From what you mentioned in the question:
- player (N, actor)
- player's house (N, location)
- store (V) item (N) to inventory (N, has items)
- refill (V) health (N, points) of player (N)
Following from what you mentioned in the question's comment:
Interaction between Player and PlayersHouse
- user can trigger the Player to purchase (V) an upgrade (A) of its owned PlayersHouse (N)
If Player has enough stones (stones for next upgrade) and money (price for next upgrade), then PlayerHouse will be upgraded.
After the first upgrade these values will become bigger.
There should be a check in the beginning of the upgrade method, if the Player has:
- enough amount of (resources for upgrading)
- and enough money
Properties of Player
- house (N, associated state: exactly 1 unique PlayersHouse) owned by each player
- stones (N, countable) required for next upgrade
- money (N, countable) required for next upgrade
Properties of PlayerHouse
- defence (N, points) increases 1 by each upgrade
- rooms (N, countable) increases 1 by each upgrade
Properties of UpgradeLevel:
Note: I added this object or noun (N) to save the state of upgrades separately.
- upgrade experience (N, points) increases 100 by upgrade
- amount/cost/price of next upgrade:
- money (N, countable, see Player's money) increases 100 by upgrade
- stones (N, countable, see Player's stones) increases 100 by upgrade
Operations on UpgradeLevel:
- increase-level, level-up (V) will increase each of its properties (experience, money, stones) by 100
Operations on Player
- purchase an upgrade (V) or build-up (V) their house (O)
Operations on PlayerHouse
- upgrade or build-up (V) to next level (associated state of the house)
Design of classes
Note: For simplicity I would recommend to start with the class
design. A next iteration could make these classes extensible (Open-Closed principle in SOLID). This can be achieved (as other answer suggests) by making them implement interface
s. Interfaces act as contract which defines the interaction between two or more classes. We say they become "loosely-coupled" which means the dependency between them is weakened/reduced. Less dependency means more freedom for evolution in the future (e.g. other upgrades of other objects, etc.).
Player
class Player {
// properties that define state or association
final PlayersHouse house = new PlayersHouse(); // each player starts with his own new unique house
// below could also be stored as items in Player's inventory
Integer stones;
Integer money;
// operations/methods
public void refillHealth() {
this.healhPoints += house.drawRegnerationHealthPoints();
}
public void buyHouseUpgrage() { // or "buildUpHouse"
var spendAll = new Amount(this.money, this.stones);
if ( house.upgradeAvailableFor(spendAll) ) {
house.buyUpgrade(spendAll); // or buildUp or addExperience
}
}
}
Player's House
class PlayersHouse {
private static final int REGENERATION_HP = 100;
final Inventory inventory = new Inventory(); // initial empty collection of items
// all initial with 0
Integer healthPoints; // like a tank
Integer rooms
Integer defencePoints; // assumed to defend the house (not player if outside)
public boolean store(Item item) {
return inventory.add(item);
}
public int drawRegenerationHealhPoints() {
if (this.healthPoints() <= REGENERATION_HP) {
return this.healthPoints();
}
this.healthPoints -= REGENERATION_HP;
return REGENERATION_HP;
}
public boolean upgradeAvailableFor(UpgradeAmount amount) {
return amount.compare(this.nextUpgrade.getPrice()) > 0;
}
public void buyUpgrade(UpgradeAmount amount) {
if (!upgradeAvailableFor(amount)) {
throw new Exception("Upgrade costs " + this.nextUpgradePrice);
}
amount.minus(this.nextUpgrade.getPrice());
this.rooms++;
this.defencePoints++
this.nextUpgrade.levelUp();
}
}
Left out
Some classes and fine-grained design as well further interactions I left up to you:
- Amount (as cost for building up(grade) the house of the player)
- next Upgrade Level (to raise and increase, the first time and later, the difficulty & gain of an upgrade)
Analyze interactions & terminology
When nouns (N) and verbs (V) have been defined, and your objects have been designed with state and behavior, you can start to analyze and design their interaction.
Some of these interactions will ask a questions to define the relation and cooperation between classes or interfaces:
- "upgrade" asks for a narrative: where does it come from (e.g. can the player purchase an upgrade ?)
- "stones" asks for the verb: How many stones build a new room (role/purpose) ?
- "experience" asks for the trigger: When does it level up?