views:

32

answers:

1

I'm coming from a background developing business applications so am used to MVC/n-Tier development.

Most of my applications have an architecture something like this:

GUI -> BL (which deals with entities) -> DAL (SQL DB)

Now, I'd like to write something which is a cross between an interactive story and a simulation - There is a persistent "world" which allows you to affect objects/NPCs. The state of objects/NPCs changes over time (sometimes as a result of your actions) which affects options later on. Think Oblivion but on a far smaller scale with no combat

I know that this is a massive project and I'm aware that I won't be able to achieve anything like modern game complexity by myself - But that doesn't mean I shouldn't try :)

My question is this: What sort of architecture should I use?

I'm going to need a library of story elements - Characters (NPCs), locations, transportation mechanisms, objects, quests, etc. etc.

I'd naturally tend to store these in a SQL database and access them using the entity framework.

I then need to be able to perform actions/events against these elements. This is where I get unclear. My usual method would be to have (say) an NPCManager which would have methods to manipulate NPC entities - But this doesn't work well with polymorphism.

I imagine that I;m going to need to use inheritance (an interfaces) to handle all the functionality that each element will have. eg:

  • Element (Base object for story elements - equivalent to Object in .Net)
  • NPC (Inherits Element)
  • Guard (Inherits NPC)
  • MountedGuard (Inherits Guard)
  • etc...

I can then say:

  • All elements would have an id
  • All NPCs would have an id and a name
  • All Guards would have an id, name and allegiance
  • All MountedGuards would have an id, name, allegiance and mount

This doesn't seem to mesh well with the EF - eg I can't have a method of NPCManager.GiveClothing(NPC as NPC, ClothingItem as Clothing) - because passing it a MountedGuard will fail (specifically, the class will be treated as an NPC which has no meaning in terms of a database...)

It also feels like I should be having methods to deal with MountedGuards specifically on the MountedGuard object - not on a Guard or NPC manager.

Should I have a set of entities for storing information and a completely separate set of classes to represent the object data stored by the entities. eg:

Entities.MountedGuard
Elements.MountedGuard - same properties as Entities.MountedGuard but also has a `Dismount()` method which affects the associated entity?

so should I be using non-POCO entities? or no entities at all (in which case, how do I define the "world"? I definitely don't want to have to do it all in code)

At present, I'm not even considering how these elements will be displayed to the user - for the time being, simple text seems likely

If someone could please point me at an appropriate architecture or some good resources.

Many thanks

+1  A: 

My $0.02: you can have multiple inheritance strategies in entity framework, see here; this would allow you to model your domain pretty much however you want - I see especially Table-Per-Type (as opposed to table-per-concrete-type) being useful to you; this would mean that the inheritance structure in your code would be closely mirrored by the database in a pretty self-explanatory structure. Where you take it from there is up to you, but the point is you can then use pretty much the same strategies as you would with any object-oriented code.

Alex Paven
@Alex - Thanks, that looks like exactly what I need. Now I just need to figure out how to implement it using EF4 Code-Only :)
Basiclife
You're welcome! However, in researching this answer I came across this, which may or may not discourage you: http://samscode.com/index.php/2010/01/the-entity-framework-v1-and-v4-deal-breaker-tpt-inheritance/
Alex Paven
It's funny but I _knew_ I'd read something about inheritance being broken in EF - That's partially what prompted me to post the question but I couldn't find it myself so assumed I must've been imagining it... Guess not. In any case, thanks for the solution and heads up :)
Basiclife