View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# OO in a PHP/mySQL RPG Game

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.

11 replies to this topic

### #1pintee  Members

Posted 19 April 2013 - 06:43 PM

First off excuse the amount of acronyms in the title.

This is my first time posting on these forums and I was hoping some game dev. experts could answer my question.

I am in the process of learning PHP/mySQL and web development in general and I was wondering if OO in PHP fits into the equation(if it does at all). Can you do without OO or is it a necessity for what I'm trying to do? Is it more efficient to use OO?

At the moment I suspect that I can get away with using creating objects and classes and just do everything as tables in mySQL. For example this is my implementation of weapons in the game:

Select * from Characters ;

+----+------+-----
| id | name | ...
+----+------+-----
| 1 | Fred |
| 2 | Bob |
+----+------+

select * from WeaponTypes ;

+----+----------+--------+------------+-----
| id | name | damage | max_damage | ...
+----+----------+--------+------------+-----
| 33 | M1 rifle | 100 | 100 |
| 44 | stick | 5 | 8 |
+----+----------+--------+------------+

select * from Weapons ; (after a bit of game play)

+-----+---------------+--------+-----
| id | weaponType_id | damage | ...
+-----+---------------+--------+-----
| 555 | 33 | 80 |
| 666 | 44 | 8 |
+-----+---------------+--------+

select * from CharacterWeapons ;

+------+---------+-----------+-----
| id | char_id | weapon_id | ...
+------+---------+-----------+-----
| 7777 | 1 | 555 | <- Fred's got his "silghtly worn" M1
| 8888 | 2 | 666 | <- Bob's now got himself a pointed stick.
+------+---------+-----------+

A similar implementation could(I think) be used for enemies and items etc. So my question is how would you implement an OO version of the above in PHP and would it be more efficient? See here: http://stackoverflow.com/questions/3548253/should-i-use-multiple-classes-for-game

I hope my question makes sense...........and that I am posting in the right forum.

### #2LJ_1102  Members

Posted 19 April 2013 - 07:59 PM

Hello pintee!

Can you do without OO or is it a necessity for what I'm trying to do?

Even if not necessary i would highly recommend you to do it OO!

If you do it procedural your code will become unmaintainable in no time even for a "small" project.

Also OO is not avoidable in about any future programming, so the sooner you get into it the better.

Is it more efficient to use OO?

It totally is, if you go the procedural way you'll have a lot duplicate code in the end which leads to the before mentioned unmaintainable code.

Oh, and be sure to separate logic from storage in regards of database triggers and functions.

Have fun

Edited by LJ_1102, 19 April 2013 - 08:01 PM.

Jan F. Scheurer - CEO @ Xe-Development

### #3pintee  Members

Posted 20 April 2013 - 06:30 AM

OK. So OO is the way to go.

What I'm still confused about( even after looking at the stack overflow answer for ages ) is how the OO relates to the mySQL database, For example, how would a Weapon object relate to a row in the Weapons table?

Also, could you please elaborate on separating logic from storage( or some google keywords to search for so i can research it myself )?

Thanks again.

### #4pintee  Members

Posted 20 April 2013 - 07:34 AM

Ok so I've formed a notion of how php objects relate to the database in an RPG, inherent in the following code:

<?php
abstract class Character {

abstract public function Attack();

public $hp; public$mp;
public $attackPower; public function Setup($a, $b,$c) {
$this->hp = (int)$a;
$this->mp = (int)$b;
$this->attackPower = (int)$c;
}

}
?>

<?php

class Player extends Character {
public function __construct() {

// HERE YOU WOULD GET THE VALUES FROM A MYSQL TABLE(x, y ,z)
$this->Setup(x, y, z); } public function Attack() { //do something } } ?> Then you could have a function that inserts a new row into a table PLAYERINSTANCES for example, which would populate the row with the current hp, mp, and attackPower. Am I on the right track?? It feels like I'm missing something conceptually in regards to how OO and PHP relates back to the database...... . ### #5LJ_1102 Members Posted 20 April 2013 - 11:20 AM Hello pintee! You are right there is no "real" connection between your database and php, thats up to you. Typically you'll go and create a base class that can load stuff from your database by a given id. Let me outline such a class in here class DatabaseObject { public$data;
private $table; private$id;

function __construct ($id,$inject) {
$table = strtolower(get_class($this))
if (!$inject) {$this->id = $id; // build query string and load data from database } else if ($inject && is_array($id)) {$this->data = $id;$this->id = \$data['id'];
}
}

// Implement save and or delete method here as well
} 

and then you go ahead and inherit from that class. Naming your classes after you database tables.

Be sure to implement the above mentioned inject functionality since when you select like a list of monsters you dont want to query each single monster.

In regards to the separation of logic and storage I'm talking about database triggers and their use.

Triggers allow you to do specific actions on specific events on tables, f.e. you could create a trigger that when you update your weapons table and the updated weapon entry has 100 damage (so is broken) the weapon will be deleted.

This is not the best example but there are situations where triggers seem to make your life easier but in the end are worse since maybe you decide you want your weapons to be repairable, so you have to drop the trigger but when your projects becomes bigger you might forget about a trigger or you want to inject something in your database for testing but triggers are preventing you from that.

So what im trying to say by that is that you should take care that the storage does what it is supposed to, storing things and nothing more.

Thats why database triggers are mostly treated as bad practice.

Hope this was understandable :/

**EDIT**

Oh and when talking about bad practice, PHP has some magic functions that allow you to write getters and setters and other weird stuff,

while using getters and setters has its advantages you should not use PHPs magic functions for that, better use written class methods like f.E. getHealth().

Oh and if these posts are helpful to you please vote them up ;)

It feels like I'm missing something conceptually

i can recommend this book. But there is also plenty of material on the web about these.

Edited by LJ_1102, 20 April 2013 - 11:42 AM.

Jan F. Scheurer - CEO @ Xe-Development

Posted 21 April 2013 - 09:17 PM

Just wanted to quickly say, as one who has had a large amount of experience with large databases, as well as some decent PHP experience... I totally agree about not using the triggers to do so. However, I would recommend using stored procedures, and if you wanted to design portions of logic into the database, it could be beneficial if you ever wish to swap to a different language. Also, if it is a database driven game anyway stored procs should limit your hacking, as you can then limit the user levels, and do extra checks in the database directly. Beyond this, it uses less bandwidth...

An example includes: attackEnemy(weaponID, enemyID) - depending upon how you have it set up (if weapons are unique, will just need the weapon id, not the character id as well) can do a quick check of weapon experience, tack on more experience, damage the enemy (there is a random function in mysql), and level up the character as needed. You can even have this return all relevant information before your next attack.

So I would do something like the following (unable to directly check, as my mysql development computer is currently gone)

CREATE PROCEDURE attackEnemy(INT @weaponID, INT @enemyID)
DECLARE @characterID INT DEFAULT NULL;
DECLARE @killedEnemy BIT DEFAULT FALSE;

SET @characterID = (SELECT characterID FROM character_weapon WHERE weaponID = @weaponID LIMIT 1);

IF(@characterID IS NOT NULL) THEN
/* Character exists so can attack */

UPDATE enemy
SET enemy.hitpoints = enemy.hitPoints - (SELECT FLOOR(weapon.minDamage + RAND() * weapon.maxDamage) FROM weapon WHERE weaponID = @weaponID LIMIT 1) WHERE enemy.enemyID = @enemyID;

SET @killedEnemy = (SELECT CASE WHEN hitPoints > 0 THEN false ELSE true FROM enemy WHERE enemyID = @enemyID LIMIT 1);

IF(@killedEnemy) THEN

/*More logic here...*/

END IF;

END IF;

END;


...my brain is shutting down, and hates working outside of my IDE or with a real database to check against, so I will have to leave the rest.

Of course, there are ways to make a more complicated where statement and mega update that could take care of more in one statement instead of the ifs...

However, my experience with super large databases is, as long as you aren't running looping cursors, if you have to use the if statement then it is ok to do so.

But it would be better if you can put it all into one statement... maybe I will download the workbench and make a simple rpg setup and give a better example later.

Almost forgot to add, don't forget to select the enemy health or whatever else you may need at the end.

Edited by tisdadd, 21 April 2013 - 09:17 PM.

### #7LJ_1102  Members

Posted 22 April 2013 - 07:37 AM

In my opinion procedures should not be used to implement game logic.
First off its pretty uncomfortable to write or modify them, you would need to
drop/create or overwrite them all the time while you're developing and testing them.
Also i find sql syntax somewhat odd to write large portions of logic in it.

Performance wise its easily possible to create more load on the database then needed to do the same with php.
I'm assuming you'll have almost everything needed already queried in php for visualization and if its only to display the stats of character, weapon, monsters etc. so one attack would be just one update query in your database even less when you're using session storage or some other kind of temporary caching.

Dont get me wrong procedures have their use, but i think/assume when writing a game you'll need almost any affected data in application code too so having procedures change your datasets so you have to requery them isnt the best idea if your game is not beeing played on a sql client terminal session.

Edited by LJ_1102, 22 April 2013 - 09:13 AM.

Jan F. Scheurer - CEO @ Xe-Development

Posted 28 April 2013 - 12:12 AM

In my opinion procedures should not be used to implement game logic.
First off its pretty uncomfortable to write or modify them, you would need to
drop/create or overwrite them all the time while you're developing and testing them.
Also i find sql syntax somewhat odd to write large portions of logic in it.

Performance wise its easily possible to create more load on the database then needed to do the same with php.
I'm assuming you'll have almost everything needed already queried in php for visualization and if its only to display the stats of character, weapon, monsters etc. so one attack would be just one update query in your database even less when you're using session storage or some other kind of temporary caching.

Dont get me wrong procedures have their use, but i think/assume when writing a game you'll need almost any affected data in application code too so having procedures change your datasets so you have to requery them isnt the best idea if your game is not beeing played on a sql client terminal session.

I just want to really quickly say this in response... as long as you are not using loops, and can do enough logic inside of the stored procedure, it will be very beneficial if you are running a database based game... and unless you write incredibly horrible code that SQL cannot optimize over time it will not overtax the database if it wouldn't overtax the php server... assuming that you avoid loops... and your table doesn't incur a few million entries each day (historic data... takes a very long time to query when in the right company, and while it doesn't freeze the database if well written there is just so much of it).

That said, based off of a few conferences that I have went to, I have had much more experience with the pros and cons of stored procedures than all of the other php developers that were there (which made me really sad), and I can understand that it can indeed be very difficult to figure out how to properly make them. The if statements can be a bit much, and not sure how they tax mysql versus mssql...

What was said is correct, you could do it all in an update. However, for security purposes if nothing else I would put it into a stored procedure that performs the update.

Also wanted to note a few procedure practices that are a good standard for development and deployment.

Save each procedure to its own file (I use MySQL work bench with mysql, which makes it really easy to do such things, then can write a batch if needed to put out to a new server, or simply update). This way you have quick access, and can easily apply version control.

Use the DROP IF EXISTS procedure_name; statement at the beginning of your procedures, as it will make sure that you don't

Of course, every time you have something you think works you should put the new version into your version control.

If you follow those steps, procedure development/deployment is fairly simple...

However, i do understand what you are saying. I guess optimal deployment would depend upon how many times you may have to loop over data/how complicated changes you are making are. Also I had in my head a kind of form based game when I replied... but depending upon security requirements it may be best to use Ajax continuously and place extra security checks into the PHP, then not worry about those same checks in the database and only update the database at the end.

Correct me if I am wrong though, but if you wanted to make the game able to have user interactivity, wouldn't it need to keep the database updated constantly anyway for a database driven game? In my head I have a few [older] mmo games running in my head and can see the traffic flowing with small tables per section to quickly give the current data out. Even if you have a reasonably horrible database server, you should easily be able to have a table with 1000 rows of data or less going nearly instantaneously for database transport.... and I haven't done a lot of Ajax, so I may be wrong but it feels like it would be possible to keep the connection open and just have it continuously echo out an xml stream to keep up to date, while checking the database...

Hmmm....guess I have a new thing to try in my free time.

I just said 1000 rows above because it seems that initially the project may start with such a (relatively) small amount of data.

For me it just seems to make sense that if it isn't client side, then why shouldn't it be updated in a place where everyone in the game can access it as soon as possible. However, if it would be faster to do the PHP then an update statement then that would be the way to go. (Though update procedure for security still)

Just want to end my rambling with this: I feel that logic in sql is something that every programmer should have to learn, as it teaches you to think much differently and forces you to come up with algorithms that will perform without looping if you want your sql database to work well. There are some pretty crazy requirements that can occur, and creating a query that can complete them quickly and properly is something can force you to think outside the box, and improve your O time in the long run.

### #9LJ_1102  Members

Posted 29 April 2013 - 09:21 PM

unless you write incredibly horrible code that SQL cannot optimize over time it will not overtax the database if it wouldn't overtax the php server

i'm sure of that, i just meant that you'll produce "more load than needed", I'm totally your opinion that procedures are faster.

Assume the case of attacking an enemy, you have your procedure attack_enemy(playerid, enemyid) and in your procedure you're selecting the enemy and the players weapon, calculate hit chance, and then decrease the enemies health by a random value within a range and decrease the weapon health by a factor from the dealt damage.

So whats now?

In your php you need to requery the enemy data to check if he's dead or what health he has left, also you need to requery your weapons health so you can show the player the updated stats. Maybe you even got counter attack stuff going on, then you need to requery the player stats as well.

So you're running your procedure which is fast, then you need three select queries, at least two (one for the enemy stats, one on a view of the player containing its current weapon stats).

If you do it in php "only" you dont need to do any of that, you just do your thing and update the affected rows.

for security purposes if nothing else I would put it into a stored procedure that performs the update.

Prepared statements, are also a way to ensure security, sure you need the MySQLi extension for that but you could also enforce them in php itself by strict type casting and mysql_real_escape_string anyway.

MySQL work bench is a great tool and really eases mysql development.

But since the original poster seems to be a beginner i think its a bit over the top to directly start with procedures, and in my opinion SQL is kinda cumbersome to write large portions of logic in it even when you're used to it. Also PHP is more related to other programming languages that are used to create games than SQL, thats why i dont think that especially when you start you should go knee deep into sql since its so different than other languages.

Use the DROP IF EXISTS procedure_name; statement at the beginning of your procedures, as it will make sure that you don't

Still not faster than editing a php file, save it and press F5 in your browser ;)

and I haven't done a lot of Ajax, so I may be wrong but it feels like it would be possible to keep the connection open and just have it continuously echo out an xml stream to keep up to date, while checking the database...

Yes that's possible but not the ideal way. You would create a json interface using json_encode/json_encode and do event triggered requests.

If you need something "realtime" you would use websockets for that.

I feel that logic in sql is something that every programmer should have to learn, as it teaches you to think much differently and forces you to come up with algorithms that will perform without looping if you want your sql database to work well. There are some pretty crazy requirements that can occur, and creating a query that can complete them quickly and properly is something can force you to think outside the box, and improve your O time in the long run.

That is your opinion, i cant say that using/learning sql has really increased my skill in other languages or concepts.

Sure sql is a benefit since you can create and use database efficiently and also there is actually a place for a database in every game project.

Please dont take this as offense, its just my opinion, in no way i'm hating against sql.

Oh and btw. PostgreSQL ftw ;)

Edited by LJ_1102, 29 April 2013 - 09:23 PM.

Jan F. Scheurer - CEO @ Xe-Development

### #10BeerNutts  Members

Posted 30 April 2013 - 11:50 AM

Can you do without OO or is it a necessity for what I'm trying to do?

Even if not necessary i would highly recommend you to do it OO!

If you do it procedural your code will become unmaintainable in no time even for a "small" project.

Also OO is not avoidable in about any future programming, so the sooner you get into it the better.

>Is it more efficient to use OO?

It totally is, if you go the procedural way you'll have a lot duplicate code in the end which leads to the before mentioned unmaintainable code.

I'm going to have to disagree with your generalization of procedural programming.

Whether your code is OO or procedural makes no difference with regard to coding becoming unmaintainable.  OO code can become unmaintainable as easy as procedural code.

Also, you should not have duplicate code just because something is procedural; it's just as easy to have duplicate code writing OO.

OO has advantages, but the issues you listed are as common in OO as any other genre of code.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

### #11LJ_1102  Members

Posted 30 April 2013 - 05:36 PM

Maybe I'm overgeneralizing.

Still in my opinion procedural code becomes unmaintainable faster than OO code since you've a more dedicated file structure in OO for your classes which allows to have a better overview of your codebase whereas in procedural you try to group independent functions somehow and when the project gets larger you need a good IDE or search your ass off to find what you search for, or ... just write it again since the function you need differs a little from what already exists, somewhere, maybe.

Also new developers in a project will have a hard time to understand your function grouping into filenames, and you'll have to

remember where what function is to properly include the functions you need, just in case you dont want to include all your code in every file.

Jan F. Scheurer - CEO @ Xe-Development

### #12BeerNutts  Members

Posted 01 May 2013 - 07:59 AM

Maybe I'm overgeneralizing.

Still in my opinion procedural code becomes unmaintainable faster than OO code since you've a more dedicated file structure in OO for your classes which allows to have a better overview of your codebase whereas in procedural you try to group independent functions somehow and when the project gets larger you need a good IDE or search your ass off to find what you search for, or ... just write it again since the function you need differs a little from what already exists, somewhere, maybe.

Also new developers in a project will have a hard time to understand your function grouping into filenames, and you'll have to

remember where what function is to properly include the functions you need, just in case you dont want to include all your code in every file.

I don't feel like arguing, but bad code AND good code can and will happen with any coding genre.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

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.