2
\$\begingroup\$

I have a webgame written in PHP and using MariaDB for the database. I'm currently looking into ways of improving core systems.

One example would be items. Currently, there is a table data_items that lists all of the items, what category they fall into, their sale value, description, icon and so on. There is then an inventory table with foreign keys referencing users and data_items, and a quantity column. Simple, and it works.

However, some items have effects. Actually most of them do.

Currently effects are implemented in one of two ways.

  1. The item is requested specifically by the code. For example, a particular feature requires a particular item, so that item is loaded up, its quantity is checked in the player's inventory, and the code proceeds if the user has the item. This is fine.

  2. The item's properties are checked. For items in the "Consumables" category, there's currently a switch statement that provides different effects based on the item in question. This is horrible.

I'm considering the idea of having a class for each item. The class can then have methods such as isConsumable(), consume(), and whatever else may be needed as applicable to each item.

Should I still have the database? I assume so. There are cases when items need to be searched, eg. by category, for showing the player's inventory. In a case like this, where there are upwards of 800 items at this point, I wouldn't want to have to load 800 classes.

What kind of combination of things should I be aiming for here? Maybe have an item "prototype" that just holds data, which can be used when enumerating the items for the inventory? Then, when the item is actually used for something, check for its specific class and only load it at that point? I think that makes sense, but any advice on this matter would be very helpful indeed.

I'm facing a similar problem for the creatures within the game. Most of them have nothing special to them, so the database works fine. But some have different images based on certain factors. One in particular can be customised to have whichever pair of colours the user chooses. These are currently all handled by switch statements in the getImage() method of the generic creature object. Should this be split into classes for each (of the 1200+) creatures?

\$\endgroup\$
  • \$\begingroup\$ In addition to Philipp's answer, I know some games use scripts for some behaviours... Scripts can be stored in a DB. \$\endgroup\$ – Vaillancourt Mar 24 '19 at 0:01
2
\$\begingroup\$

Having a class for items is a good idea, but it is rarely useful to have a class for each item. When entities in a game differ by their values and not their behavior, then it is usually better to implement them as instances of the same class which differ by their data. The only case where you need to create new classes inheriting from Item is when you have items which have unique game mechanics. And even then it might be advisable to implement that mechanic somewhere else and just add some kind of tag to the item data which tells the game to use that special mechanic.

Regarding the question if you should keep item types in the database or not: I haven't worked with PHP in a very long time, and back then it was difficult to share data between requests without taking a detour through a database. But if it is possible now then I would avoid reading the data about the item types from the database and keep them in memory instead. The reason is that you are dealing with data which changes very rarely (whenever you release an update) but which is required very frequently. That means it is data which should be read at server startup and then stay in memory for fast access.

\$\endgroup\$
  • \$\begingroup\$ Sounds like I should keep doing what I am at the moment, but maybe move the "consume item" code into a separate area rather than having the item describe how it is consumed. As far as memory goes, I do have Memcached saving a lot of the unchanging data, so that's all good :) \$\endgroup\$ – Niet the Dark Absol Feb 21 '19 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.