• Create Account

## Am I Over Thinking This ?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

14 replies to this topic

### #1Code Fox  GDNet+

3039
Like
1Likes
Like

Posted 01 March 2014 - 02:58 PM

I have been working on a parent class that will handle every interactive item that will be generated on the map, however I think I may be "over thinking" this a bit too much - or maybe I am not abstracting it enough.

This class will handle trees, rocks, plants, and mining nodes - what do you think ?


public abstract class InteractiveObject {
static String defaul1 = "Error";
static String defaul2 = "E";
static int defaul3 = -1;

String name;
String type;
String inspect;
String skill;
String tool_required;
int tool_quality;
int tool_damage;
int skill_level;
int health;
int regen;
int experance;
int rarity; // Chance to spawn on map ( x in 10000 )
String[] state = new String[2];
//LootNode loot;

public InteractiveObject(){
name = defaul1;
type = defaul1;
inspect = defaul1;
skill = defaul1;
tool_required = defaul1;
tool_quality = defaul3;
tool_damage = defaul3;
skill_level = defaul3;
health = defaul3;
regen = defaul3;
experance = defaul3;
rarity = defaul3;
state[0] = defaul2;
state[1] = defaul2;
//loot = new LootNode(defaul1);
}

public String getName(){return name;}
public String getType(){return type;}
public String getInspect(){return inspect;}
public String getSkill(){return skill;}
public int getSkillLevel(){return skill_level;}
public int getHealth(){return health;}
public int getRegenerationRate(){return regen;}
public int getExperance(){return experance;}
public int getRarity(){return rarity;}
public String[] getStates(){return state;}

}



I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

### #2TheChubu  Members

8954
Like
8Likes
Like

Posted 01 March 2014 - 04:10 PM

POPULAR

I wouldn't use the ammount of Strings you're using.

I'm guessing here since I can barely know what you're doing here but probably "type",  "skill", "tool_required", "inspect" and "state" can be represented by enums, tag classes, int indices, or whatever else you can come up with that doesn't requires a character-per-character comparison every time you want to do something useful with it.

Probably someone with more actual game programming can help you with the abstractions.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

### #3Alpheus  GDNet+

6806
Like
5Likes
Like

Posted 01 March 2014 - 05:50 PM

POPULAR

I don't think trees and rocks should have tool_quality and tool_damage. Therefore, I think your catch-all class needs to be pared down a bit. My first thought is to have a smaller base class and use inheritance for things like (trees, rocks), (saw, drill), (engineer, miner), etc. But since I'm thinking inheritance and I know the better answer will involve composition, I think my answer will stop here. Someone more qualified will have to help you.

External Articulation of Concepts Materializes Innate Knowledge of One's Craft and Science

Super Mario Bros clone tutorial written in XNA 4.0 [MonoGame, ANX, and MonoXNA] by Scott Haley

If you have found any of the posts helpful, please show your appreciation by clicking the up arrow on those posts

Spoiler

### #4frob  Moderators

41249
Like
5Likes
Like

Posted 01 March 2014 - 07:04 PM

POPULAR

Yeah, like the above I'd say you've got a pretty strong example of SRP violations.

I'm guessing you have game objects -- trees, rocks, mining nodes.
I'm guessing your game objects have an interface that exposes available interactions; presumably they take an actor (the avatar doing something) and object to interact with. Personally I like when game objects have GetInteractions() and GetDebugInteractions(), both returning (potentially empty) collections of interaction objects or pointers.

From there, I would build an abstract base class, perhaps "IMineable" or "ICanQuarry" or something, that exposes the minimal set of shared functionality to be quarried, maybe listing the tool needed to quarry it, the animation to play, and associated sound clips.

Then put them all together in a new interaction. The interaction requires an actor and an ICanQuarry object, if either is missing return instantly. Then the interaction verifies that the actor has the requisite tools, possibly obtaining them or aborting, and also getting to the right spot on the quarry-able object. Then you play the animation, generate whatever got quarried as new objects, and finish the interaction.

Of course at that point you need to define what it means to be an interaction object, probably a rather large base class with interaction names, hover-over tooltips, an interaction queuing and continuation system, interaction priorities and early cancellation handling, and so on. But that is another task.

Now everything follows SRP and DI and other good programming acronyms, and you can extend it with new quarry-able objects, new quarried objects, and new interactions in the future.

Edited by frob, 01 March 2014 - 07:09 PM.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #5Code Fox  GDNet+

3039
Like
3Likes
Like

Posted 01 March 2014 - 07:14 PM

Yes all those items can be interacted with by a player if they have the correct tool, and skill level.

If you want to see something scary, here is the class that uses the parent class . I'm going to have to decide on how to detangle all this stuff. ( this is what my current map gen uses to produce a map )

import java.util.ArrayList;
import java.util.List;

public class EnvObjects{
// Trees
InteractiveObject pine_tree;
InteractiveObject oak_tree;
List<InteractiveObject> tree_list = new ArrayList<InteractiveObject>();
// Rocks
InteractiveObject sand_stone;
InteractiveObject chert_stone;
List<InteractiveObject> stone_list = new ArrayList<InteractiveObject>();
// Mining Nodes
InteractiveObject copper_node;
InteractiveObject iron_node;
List<InteractiveObject> mining_node_list = new ArrayList<InteractiveObject>();
// Plants
InteractiveObject grass_plant;
InteractiveObject mushroom_plant;
List<InteractiveObject> plant_list = new ArrayList<InteractiveObject>();
// \\

public EnvObjects(){

//
//====
//Trees
//===
//

pine_tree = new InteractiveObject();
pine_tree.name = "Pine Tree";
pine_tree.type = "Tree";
pine_tree.inspect = "A pine tree.";
pine_tree.skill = "Wood Cutting";
pine_tree.tool_required = "Axe";
pine_tree.tool_quality = 1;
pine_tree.tool_damage = 5;
pine_tree.skill_level = 1;
pine_tree.health = 100;
pine_tree.regen = 300;
pine_tree.experance = 5;
pine_tree.current_state = 0;
pine_tree.rarity = 100;
pine_tree.state[0] = "T";
pine_tree.state[1] = "t";

oak_tree = new InteractiveObject();
oak_tree.name = "Oak Tree";
oak_tree.type = "Tree";
oak_tree.inspect = "An oak tree.";
oak_tree.skill = "Wood Cutting";
oak_tree.tool_required = "Axe";
oak_tree.tool_quality = 1;
oak_tree.tool_damage = 5;
oak_tree.skill_level = 1;
oak_tree.health = 100;
oak_tree.regen = 300;
oak_tree.experance = 5;
oak_tree.current_state = 0;
oak_tree.rarity = 100;
oak_tree.state[0] = "T";
oak_tree.state[1] = "t";

//
//====
//Rocks
//===
//

sand_stone = new InteractiveObject();
sand_stone.name = "Sand Stone";
sand_stone.type = "Rock";
sand_stone.inspect = "A bit of sandstone.";
sand_stone.skill = "Mining";
sand_stone.tool_required = "Pick Axe";
sand_stone.tool_quality = 1;
sand_stone.tool_damage = 5;
sand_stone.skill_level = 1;
sand_stone.health = 100;
sand_stone.regen = 300;
sand_stone.experance = 5;
sand_stone.current_state = 0;
sand_stone.rarity = 900;
sand_stone.state[0] = "R";
sand_stone.state[1] = "r";

chert_stone = new InteractiveObject();
chert_stone.name = "Chert";
chert_stone.type = "Rock";
chert_stone.inspect = "A bit of chert.";
chert_stone.skill = "Mining";
chert_stone.tool_required = "Pick Axe";
chert_stone.tool_quality = 1;
chert_stone.tool_damage = 5;
chert_stone.skill_level = 1;
chert_stone.health = 100;
chert_stone.regen = 300;
chert_stone.experance = 5;
chert_stone.current_state = 0;
chert_stone.rarity = 200;
chert_stone.state[0] = "R";
chert_stone.state[1] = "r";

//
//====
//Mining Nodes
//===
//

copper_node = new InteractiveObject();
copper_node.name = "Copper Node";
copper_node.type = "Mining Node";
copper_node.inspect = "I can get copper from here.";
copper_node.skill = "Mining";
copper_node.tool_required = "Pick Axe";
copper_node.tool_quality = 1;
copper_node.tool_damage = 5;
copper_node.skill_level = 1;
copper_node.health = 100;
copper_node.regen = 300;
copper_node.experance = 5;
copper_node.current_state = 0;
copper_node.rarity = 300;
copper_node.state[0] = "M";
copper_node.state[1] = "m";

iron_node = new InteractiveObject();
iron_node.name = "Iron Node";
iron_node.type = "Mining Node";
iron_node.inspect = "I can get iron from here.";
iron_node.skill = "Mining";
iron_node.tool_required = "Pick Axe";
iron_node.tool_quality = 1;
iron_node.tool_damage = 5;
iron_node.skill_level = 1;
iron_node.health = 100;
iron_node.regen = 300;
iron_node.experance = 5;
iron_node.current_state = 0;
iron_node.rarity = 400;
iron_node.state[0] = "M";
iron_node.state[1] = "m";

//
//====
//Plants
//===
//

grass_plant = new InteractiveObject();
grass_plant.name = "Grass Tuff";
grass_plant.type = "Plant";
grass_plant.inspect = "Grass - Mooooo !.";
grass_plant.skill = "Farming";
grass_plant.tool_required = "Shears";
grass_plant.tool_quality = 1;
grass_plant.tool_damage = 5;
grass_plant.skill_level = 1;
grass_plant.health = 100;
grass_plant.regen = 300;
grass_plant.experance = 5;
grass_plant.current_state = 0;
grass_plant.rarity = 600;
grass_plant.state[0] = "P";
grass_plant.state[1] = "p";

mushroom_plant = new InteractiveObject();
mushroom_plant.name = "Mushroom";
mushroom_plant.type = "Plant";
mushroom_plant.skill = "Farming";
mushroom_plant.tool_required = "Shears";
mushroom_plant.tool_quality = 1;
mushroom_plant.tool_damage = 5;
mushroom_plant.skill_level = 1;
mushroom_plant.health = 100;
mushroom_plant.regen = 300;
mushroom_plant.experance = 5;
mushroom_plant.current_state = 0;
mushroom_plant.rarity = 100;
mushroom_plant.state[0] = "P";
mushroom_plant.state[1] = "p";

//
// End
//

}
public void say(String x){
System.out.println(x);
}

public List<InteractiveObject> getTrees(){ return tree_list;}
public List<InteractiveObject> getRocks(){ return stone_list;}
public List<InteractiveObject> getMiningNodes(){ return mining_node_list;}
public List<InteractiveObject> getPlants(){ return plant_list;}

}


Edited by Shippou, 01 March 2014 - 07:16 PM.

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

### #6frob  Moderators

41249
Like
6Likes
Like

Posted 01 March 2014 - 07:36 PM

POPULAR

Well, I suppose hard-coding everything is an option.

Most games use a data-driven approach with map editors and tools to save the map data to a file and load files at runtime. They list all game objects and expose some data. There isn't really any special handling, just a big collection of objects. Your way works for small games.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #7Pink Horror  Members

2459
Like
3Likes
Like

Posted 01 March 2014 - 08:53 PM

Well, I suppose hard-coding everything is an option.

Most games use a data-driven approach with map editors and tools to save the map data to a file and load files at runtime. They list all game objects and expose some data. There isn't really any special handling, just a big collection of objects. Your way works for small games.

The good thing is, storing all the data in some sort of structure is the first step towards using a data file instead of hard-coding everything. Hopefully, many of the methods in this game will just work on InteractiveObjects or whatever without needing to know where they came from. It's better than data hard-coded into an if or switch statement.

### #8Norman Barrows  Members

6291
Like
1Likes
Like

Posted 02 March 2014 - 09:39 PM

1. people other than the coders can change the data.

2. no re-compile required when you change the data.

the slick way to do it is to alt-tab out of the game, edit the data file, then use a menu pick in the game to re-load the data file without quitting the game. or better yet, build the data  file editor into the game itself - but this might be overkill, depending on the game and the complexity of the data.  constant values for object type definitions like you're dealing with can easily be handled with a simple text file.  for something more complex like a heightmap, an internal or external editor would probably be called for.

as for the "all-in-one"  objecttype struct, i often debate this issue myself when starting a new title.  all in one is appealing in its perceived simplicity, but can be inefficient in terms of memory usage, cache friendliness, etc. due to unused variables.

some unused variables are ok. but its usually better to divvy things up into groups with similar sets of variables.

composition and components can reduce / eliminate unused variables, by giving you multiple simple struct types to work with.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

### #9Norman Barrows  Members

6291
Like
0Likes
Like

Posted 02 March 2014 - 09:41 PM

and definitely use #defined constants or enums instead of strings where possible. much faster. note that enums may have some type checking overhead that #defined constants don't have.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

### #10Tutorial Doctor  Members

2564
Like
0Likes
Like

Posted 02 March 2014 - 10:04 PM

Your class will end up being much bigger than that. The class would end up being a  World Class in that case.

You have the world, and then you have things in the world. Those things can be sectioned off into different classes. You have the class of Humans and the class of Fish, and the class of trees. Each class is, in its own respect, is very detailed. You have so many different kinds of trees, with various unique properties.

Now, you have one class handling rocks and trees and plants and... get the point?

If you break down your classes and use inheritance for certain things, then it will make adding to the class easier in the long run. Also, your classes would be more re-usable for future things.

Perhaps you want trees in your next game, but not rocks?

Edited by Tutorial Doctor, 02 March 2014 - 10:06 PM.

They call me the Tutorial Doctor.

### #11Pink Horror  Members

2459
Like
0Likes
Like

Posted 02 March 2014 - 11:20 PM

Your class will end up being much bigger than that. The class would end up being a  World Class in that case.

You have the world, and then you have things in the world. Those things can be sectioned off into different classes. You have the class of Humans and the class of Fish, and the class of trees. Each class is, in its own respect, is very detailed. You have so many different kinds of trees, with various unique properties.

I don't really enjoy extreme programming, but it has one principle I stick to: "You aren't gonna need it." http://en.wikipedia.org/wiki/You_aren't_gonna_need_it

Basically, don't add features for the future. Add features and refactor for the present. This rock/tree thing is a great example. If I made a game, at the beginning, there's probably not really any difference between a rock and a tree. They're both just parts of the scenery - two immobile objects with different 3D representations but the same code. So why should I make a Rock class and a Tree class right at the beginning? Maybe I'll be able to mine rocks and chop down trees, but that could also just start out as different values in a couple of variables - which tool type works, what material comes out, etc. - exactly like the OP describes. We could argue about data types and minor details but the general idea is there. Why make two classes? It doesn't gain me anything for the present.

If it gets to the point where there are differences between rocks and trees, they can be refactored into two separate classes. There's not much point in doing it earlier.

Perhaps you want trees in your next game, but not rocks?

Maybe I want traffic cones and mailboxes in my next game, and the generic InteractiveObject would work for those just fine by itself.

Edited by jbadams, 04 March 2014 - 03:16 AM.

### #12Tutorial Doctor  Members

2564
Like
0Likes
Like

Posted 03 March 2014 - 09:54 AM

They're both just parts of the scenery - two immobile objects with different 3D representations but the same code. So why should I make a Rock class and a Tree class right at the beginning?

Good point, if that is the case, certainly they can go to one class. But then why are mining nodes apart of that same class? In the class you see all sorts of properties and stuff. If rocks and trees are not using any of those properties, then perhaps they should be separated out.

There would be one class for "Scenery Objects" and another for objects that can be interacted with. If they can be interacted with in the same manner (as in something like minecraft) then again, they could be in the same class. And I guess the mining node would fit if it is interacting with the rocks and trees. I guess it depends on the game.

Edited by Tutorial Doctor, 03 March 2014 - 09:56 AM.

They call me the Tutorial Doctor.

### #13LennyLen  Members

5406
Like
0Likes
Like

Posted 03 March 2014 - 03:20 PM

I don't really enjoy extreme programming, but it has one principle I stick to: "You aren't gonna need it." http://en.wikipedia.org/wiki/You_aren't_gonna_need_it

I've fixed the link for you: You Aren't Gonna Need It

Edited by jbadams, 04 March 2014 - 03:17 AM.

### #14Lactose!  GDNet+

9620
Like
0Likes
Like

Posted 03 March 2014 - 03:28 PM

I don't really enjoy extreme programming, but it has one principle I stick to: "You aren't gonna need it." http://en.wikipedia.org/wiki/You_aren't_gonna_need_it

I've fixed the link for you:

Not quite...

The apostrophe breaks the link, even when using the forum's Link button. Using an alternative link works:

Otherwise, typing it in manually you can make it work, though:

[ url = http//etc ] Clicky[ / url]

Clicky

Hello to all my stalkers.

### #15LennyLen  Members

5406
Like
0Likes
Like

Posted 03 March 2014 - 03:31 PM

Hmmm, odd.  It was working before I clicked post.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.