How would YOU store and call hundreds of spells, items, and quests in an RPG?

Hi, I am new to Unity and in researching a good architecture to store and call these entities, I believe there are three options I can think of:

1) Database: World of Warcraft uses a database to store and call upon spells, quests, etc. for example.

2) Scriptable Objects:

3) And Prefabs(?):
Not quite sure about this one.

In terms of three criteria:

  • long-term maintainability
  • performance
  • ease of use

What would you guys go with?

Scriptable objects for spell effects.

Most spell effects can be reduced to a single base class (which stat is affected, how, is it permanent effect or timed, how does it scale, which particle system plays, etc).

WoW is probably not a good example, because they have bigger budget and team compared to you.

I store “quest” information in my game in a .csv file which is made in excel (or whatever the google free version online is called.)

The important thing for me is ease of iteration. I know I’ll need to play with the numbers a lot so this is the easiest way.

4 Likes

How is ScriptableObject’s scalability? Does it begin to suffer in the hundreds or thousands?

Slightly off-topic but did I post this in the right location? If a mod thinks this better fits Editor & General Support or Scripting, I would appreciate your help in moving it.

I actually make a tool for this. Links in my sig (Vault Core is the base version and the others are addons).

Using ScriptableObjects is a valid approach for even thousands of data points, you just need a nice interface (Vault) to manage and design them. They’re easy to edit, Unity already serializes it, and is static data in the build. Almost a no brainer for solo devs and a great choice for small teams.

This is the perfect example where I actually strongly recommend using some premade assets. At least partially. You don’t need to reinvent the wheel again.

  • You can easily build an RPG database editor with the great use of Odin.
  • If you don’t want the custom stuff, there is this. It even has sync options for Google Spreadsheets and MySQL (if you want to host your own database or you need to keep the data in the cloud for some reason)

Both of them offer ScriptableObject workflow with some tooling for convenience.

Wow, that is very interesting. Thanks for bringing these to my attention. Can you explain to me what is Odin Inspector? I actually do have it from a Humble Bundle sale not too long ago.

So you create ScriptableObjects and Odin Inspector makes it visually easy to edit? Or is it the other way around where Odin Inspector creates ScriptableObjects?

Odin inspector is a set of custom/improved inspectors and a bunch of attributes you can use to edit/change/improve editor behavior. Open it up in a new project and install the sample project, it is a basic RPG editor. You can gain some ideas how it is intended to be used.

Odin helps make the inspector work better, look better and serialize better. If you are using ScriptableObjects then they are already inspectable, which means Odin can make them pretty. It doesn’t create a database for your game. You would need a different tool or to roll your own solution for that.

ScriptableObjects are a completely different solution than databases right? There’s no merit to them co-existing since both solutions can directly rip out the necessary values for the functions, right?

7546828--932590--upload_2021-10-4_18-46-47.png

You can always have a database of scriptable objects, and you will probably need to should you go down that path.

The biggest benefit with them is the fact they’re more designed friendly compared to boring spreadsheets.

You can create very simple databases with Odin, which has a feature called GlobalConfig which is a pre-made scriptable object singleton of sorts, with which, for example, you could use to hold a dictionary of spell GUIDs and the spell SO’s themselves for the purposes of saving and loading.

Odin also has their OdinTreeMenu which is a godsend for editing large amounts of SO’s and other assets.

I’ll stop singing the praises of Odin now. :u

2 Likes

This, and for that matter you could use scripting objects to store the database while it is loaded and a traditional database like SQLite to store it on disk.

https://docs.unity3d.com/ScriptReference/ScriptableObject.CreateInstance.html

I’m truly not for/against any particular solution at the moment, just trying to learn and research the pros and cons of SO and DB.

In regards to SO, doesn’t it get overwhelming?

DB:

I still don’t quite get having BOTH SOs and DB. Can you guys explain a little bit more on that? I’m a bit nervous of it since it seems very layered and complex - a hit to maintainability and ease of use maybe?

Databases are just information, you can form them however you want. A database of SOs is great as it allows you to enjoy all of the benefits they afford in addition to housing simple data.

Databases look no different than your blob of SOs, but fortunately you don’t have to interface with the data that way if there’s a tool for it.

1 Like

If I stored them that way it would be overwhelming. With folders and intelligent naming though it becomes trivial.

So I understand there are preferences in user experience and familiarity but are there concrete technical (performance) differences between the three?

  1. SOs by itself
  2. A DB by itself
  3. A DB of SOs

Isn’t the most straight forward path the most performative and simple? In other words, having values directly pulled from either SOs or the DB is surely faster than nesting SOs (data storage) inside a DB (data storage) like nesting Russian dolls?

Thanks for the discussion, learning a lot of concepts today.

The example you presented is unusable.

A record of a single spell could go like this.

id: 123
stringId: CTHULHUS_HEAL_TOUCH
name: Cthulhu's healing touch.
icon: /assets/icons/icon147.asset
description: You feel the elder god tap gently into your mind. You're filled with terror. Your health recovers.
targetsStat: hp
baseDice: 1d6
scalesSinceLevel: 1
levelsPerIncrease: 1
increasePerLevel: 1d6
duration: 0
targets: Caster
castSound: /assets/sounds/spells/chthulhuFtagn.asset
onCastPrefab: /assets/particles/eldrtichCast.asset
continuousPrefab: NULL
castAnimationParam: Anim7

In thsi scenario, the record stores name, description, identifier, which stat is being targeted (hitpoints), how it starts scaling, how many levels it takes to increase the effect, how much the effect increases, how long it lasts (0 → instant), who it targets, which sound it plays on cast, which prefab it spawns on cast (vfx, particles), which prefab is attached to the player while it is active (none), and which animation sequence shoudl be played. Frankly, it could use few more entries.

It doesn’t matter how you’re going to store that. Scriptable object, database - doesn’t matter. You just need a way to pull this data and initialize the spell based on that.

Since you’re unsure what you’re trying to do, I’d recommend to play with scriptable objects first.

2 Likes

Plus labels, project search by type, name, fragment, and whatnot. Unity does have a lot of super-user-friendly feature which aren’t used by not-professionals because Brackey has never done a video on them…

IMO, never store the value data on Prefabs. Prefabs should only be used as instanced representation of the data in the scene/context. Even if I have one instance of a thing (IE: Main Character) then I still store values on Scriptable Object due to all the vast benefits (Easier to merge/track changes, runtime value tweaking, easier to swap for other setups, etc)

My general rule-of-thumb.

  • < 50: Scriptable Objects
  • Between 50 and 100: Scriptable Objects with some kind of ‘Item Database’ editor window for balancing values in unison.
  • 100: separate database and then import the data in (Possibly decanted into Scriptable Objects)

Of course; this all depends on your setup, knowledge and workflows. :slight_smile:

10 Likes

Excuse me I take offense to that.

Databases in general are just better practice. Even if you have a DB of scriptable objects. It is much easier to look over a DB to see an issue imho. When you start getting into 100’s of spells or abilities you need to start doing multiple DB’s that organize them based on class or type. This allows you to easily debug as well as make quick adjustments to every spell / ability of one type. While just getting into Unity again I have created about 10 separate DB’s over the years of spells and abilities with their effects, damage values, etc. It has been extremely nice to just to go in and add or remove a value based on how they are grouped.