views:

84

answers:

3

Here's the lowdown of the situation. I am creating a role-playing game with PHP. The combat system consists of the various buffs and debuffs. The combat is likely to take several turns (it's against an AI).

I am of two mind about ensuring the correctness of the player's data (buffs and debuffs expire over time. A +5 strength buff may last for only 1 turn). I could

1) Go through a character init sequence which fetch the user's data and changes to his data from items, equipments, passive skills, and then add in the buff, which is stored in session. If the buff exists, I apply it. If not, it's gone. This way the correctness of the data is ensured at the cost of performance...I assume.

2) Store the entire character data in session, and update the buffs. When the buffs is active, I add the modifiers, if the debuff/buff is gone, I have to remember to 'roll-back' or clean-up whatever effects the buff have. I am assuming this is less taxing on DB but will be difficult to ensure correctness as there may be so many different type of buffs.

So in terms of

a) database overhead b) maintainability of the combat system c) industry practises on such cases,

how does the 2 solutions fare? Are there more which I don't know about? I was thinking of using a subscriber pattern to implement #2, but as the web is stateless that seems to add more overhead.

A: 

How extensive is the character data? Would it be viable to simply store all of the character's stats and items in the session? If so you could get the best of both worlds.

Amber
The stats are quite bulky, at least > 30 attributes (most hidden from the player; just used for internal calculation). The real question is if I cache the character data, I have to apply a 'de-init()' to the cache data when a buff/debuff goes away. Whereas if I use solution #1 and re-calculate the character's stat from DB (based on EQ, etc.), I don't have to de-init a buff.
Extrakun
+3  A: 

I'm pulling the Knuth out: "Premature optimization is the root of all evil."

You don't know what the actual performance impact of this design decision is and you're in the middle of development. Without actual data it's impossible to tell if this will be a bottleneck in the future, there may be something else that is causing your app to be 10X slower than it should that you don't even know.

Measure. Test. Use Real World Data. Optimize.

Mike Buckbee
+2  A: 

I'm going to go with "neither" here, and tell you the approach I would take.

I can assume that because of your question, you're obviously planning on having some decent traffic and want to make sure your application performs under load. That being said, you should remember the nature of sessions here. If you ever need to cluster your front end by adding multiple web servers to spread out the load, then PHP's normal file-based session handling becomes relatively useless, as you can't ensure that a web visitor will hit the same front-end server all the time (well, you probably can, but it would be difficult). Storing to cookie might not be the best bet either if you're storing game states, as you might have more than 4Kb of data.

So the next step after that is to move your sessions to a central point with a new handler, which is generally your database. Any database gains you've made by storing to session have an offset now, as you still need to hit the database. It might not be quite as expensive, but it's not ideal. Basically, you're just bundling up data and re-writing it in a different form.

The scalability pattern I would follow here would be closest to your #1. Initially, rebuild the buffs each time and ensure data correctness. Use sessions to alleviate some performance, but don't rely on them heavily. When you start encountering performance issues, you'll have several options. In likely order of preference, they will be:

  • Install and use memcached. Instead of caching to sessions, cache to memory! Much faster, and a much better performance gain.
  • Separate the database and the web server onto different servers.
  • As you continue to grow, change your session handler to be database-oriented, and add more web front-ends
zombat