Page 5 of 5

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 27 Mar 2012, 17:15
by StefanP.MUC
Ah, you were faster with replying than I did my edit. Added the same question for level:
Does a level make sense for non-Creatures? It's currently only used for Creatures and I can't imagine any case where non-Creatures could have a level.

I think it would be better to use exp and level only for Creatures. And if later evolving of buildings is needed then we can introduce some kind of "upgradeStage" ("wooden tower -> stone tower -> canon tower" as an arbitrary example).

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 27 Mar 2012, 17:24
by oln
Yeah, that sounds like a good idea.

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 27 Mar 2012, 18:58
by svenskmand
StefanP.MUC {l Wrote}:Yeah, I know. But when using interfaces we have to implement the same code several times. Every subclass then needs to implement it's own get/setName(), get/setPosition(), get/setLevel() ... functions, for example.
The whole refactoring process was started with the intention to avoid these kind of code duplication. If we now start to re-implement these functions we wouldn't have to start the refactoring in the first place...

If you use the Strategy pattern, I think you can avoid much of the code duplication, and at the same time avoid having multiple inheritance. Then the implementations can also be varied slightly by simple inheriting from an existing strategy and change some of its code.

StefanP.MUC {l Wrote}:Let's make a table of what object types we have and what properties they need, including possible use cases:

Creature
Attackable - Yes.
Movable - Yes.
Active - Yes, but currently has its own doTurn(), could be replaced/renamed by doUpkeep()

Trap
Attackable - Yes.
Movable - Probably. Ideas: Mimics. Something like the Stomps from Super Mario (stone blocks that move back and forth on a fixed way)
Active - Yes.

Room and RoomObject
Attackable - Yes.
Movable - No. Maybe RoomObject moving on the Room, but generally not, I believe.
Active - Yes.

Tile
Attackable - Probably. Digging/Mining a wall/gold could be handled like attacking.
Movable - No.
Active - Probably. Ideas: Lava tiles maybe shoot out a fireball. Tiles that have a Geyser on them. Mana sources.

Weapon
Attackable - Probably. Ideas: Creatures can be disarmed if the enemy attacks the weapon instead of the holder. Destroyable weapons.
Movable - Probably. Ideas: self-returning throwable spears or axes.
Active - Probably. Ideas: Guns or similar need to reload. Magical weapons that need to recover after using their special feature (e.g. magical wands).

MissileObject
Attackable - Probably. Ideas: Cancel/weaken a fireball with water. Fast creatures could redirect arrows by hitting them.
Movable - Yes.
Active - Yes.

Conclusions:
  • Probably everything can be attacked. So merging GameEntity with AttackableEntity should be fine, flag "isAttackable" is provided for non-default cases.
  • Probably everything can be active. So merging GameEntity with ActiveEntity should be fine, flag "isActive" is provided for non-default cases..
  • Movable has the biggest uncertainty. Rooms, RoomObjects and Tiles are fully static, some other things probably, too. Merging this is not logical. But how to handle actions like "change position/move"? The property "position" is common to all objects, but the class MovableEntity would have no access to it then.
Maybe making GameEntity a big class handling and providing attacking, moving and activity and solving the individual property availability by flags (simple bools) is really the best solution to get a clear structure. This would also be the most easy way to get scripting done, I think.

This would lead to
{l Code}: {l Select All Code}
           GameEntity
               |
   --------------------------------------------
   |           |          |        |          |
Creature    Building    Weapon    Tile    MissileObject
               |
           --------
           |      |
          Room   Trap
//And somewhere RoomObject, either also a Building or directly a GameEntity


Any opinions on this?

Very nice idea :)

StefanP.MUC {l Wrote}:Ah, you were faster with replying than I did my edit. Added the same question for level:
Does a level make sense for non-Creatures? It's currently only used for Creatures and I can't imagine any case where non-Creatures could have a level.

I think it would be better to use exp and level only for Creatures. And if later evolving of buildings is needed then we can introduce some kind of "upgradeStage" ("wooden tower -> stone tower -> canon tower" as an arbitrary example).

Agreed!

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 27 Mar 2012, 19:53
by StefanP.MUC
The Strategy pattern is new to me. But after the first look it looks rather complex for our game. After all, the amount of classes and code we have is not very much, compared to large scale projects. So, not sure if it would be worth the effort (especially now after we already started the big refactoring and proceeded very much).

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 27 Mar 2012, 21:29
by oln
Agreed. After analysing the problem, it seems that we won't need a separate attackable-interface, so the problem is solved. Maybe the strategy pattern could come in handy in other parts of the code.

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 28 Mar 2012, 10:43
by StefanP.MUC
Just finished to merge all the create/destroyMesh() and deleteYourself() methods into GameEntity. The object specific code that is stil lleft in there is taken care of in a switch with regard to the ObjectType.
So, for future changes to the mesh creating/deleting and render queuing we only need to change it at one single place (when introducing the deletion queue or something). However, some specific rooms still have their own mesh functions overloaded.

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 28 Mar 2012, 11:01
by oln
Nice work!

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 28 Mar 2012, 11:07
by StefanP.MUC
Also the inheritance graphs are getting prettier. :D No more line-crossing. I think as a next step I'll try to get the common stuff from Movable into GameEntity.

GameEntity.png

Re: Brainstorming: refactoring classes/inheritances

PostPosted: 28 Mar 2012, 12:33
by svenskmand
StefanP.MUC {l Wrote}:The Strategy pattern is new to me. But after the first look it looks rather complex for our game. After all, the amount of classes and code we have is not very much, compared to large scale projects. So, not sure if it would be worth the effort (especially now after we already started the big refactoring and proceeded very much).

When ever I write any code at all, I always end up using the Strategy Pattern somewhere. I can be used for both small and big things. It is very handy, so it is good always to have it in mind when coding.

Nice work :)