Trying to figure out a flexible solution to a "loot database"

Started by
13 comments, last by kburkhart84 6 years, 9 months ago

Thanks for all the feedback, for some direct responses:

On 7/7/2017 at 4:31 PM, Khatharr said:

Yea, I am familiar with over engineering and am definitely guilty of doing that from time to time in my day job but under engineering is something that can also lead to bad things like a system that requires a lot of effort to work it or major / total rewrites. Just trying to find a good balance for my initial implementation so that whichever way I go over (which I am sure I will), it might be an easier refactor later down that road if that needs to happen.

9 hours ago, Xai said:

Rutin's answer is how Bethesda handles this with the fallout and skyrim engines ... just loot at:  http://www.ign.com/wikis/fallout-3/Item_Codes for an example. Everything's "item id" is just a 32 bit integer, which they write as 8 HEX digits (0-9 or A-F) so that you can recognize they are a game id at a glance.

I know about how game I have played in the past do handles thing like this however I am know that games like startbound has a string id or string to int id mapping (since you can do things like `/spawnitem wheat` in their in-game console) and pretty sure rim world is also similar based on the modding docs (http://rimworldwiki.com/wiki/Modding_Tutorials/Weapons) where none of the items seem to have an int or hex based id (closes thing that looks unique is `defName` which is a string).

---

I did some performance testing with a database of about 9000 base items loaded and when attempting to just use an int id in code to access data 10000 times, it took `0.00005` seconds and when when using a dictionary to get the int id, it takes `0.005` seconds. So while it is certainly a lot slower (by a factor of 100), I think this is an extreme case and I can't see any real reason I would ever need to try to access more then 100 items at a time (which is still an extreme case I think) so I think I am going to go with this pattern for the time being. I am always doing the conversion from string to int as the first thing and then using the int going forward so I am minimizing the amount of string -> int conversions.

Advertisement

Understand...you are using C# with Unity.  A thing you can do is make a simple class(not derived from MonoBehaviour).  Name it ItemStrings or something similar that you'll remember easily when typing code.  Add static variables to your class(type is whatever id you are using for your main loot table, an int for example).  The variable names have to be easy to remember, and since they are variable names(not strings), can't have spaces, but could have underscores.  The way you go about naming them is up to you.  I like the idea of naming "big to small" so I could have AXE_BASIC, AXE_BETTER, AXE_GODLY, etc... so anytime you want to get the id for an axe, you can type ItemStrings.AXE_ and intellisense would list all the axes you have defined as static variables of that class.

The only real catch to this is that for this convenience, you pay a bit of a price when creating all the loot, etc...  It has to be defined ahead of time in code, not in external files(so it isn't something that can be modded later, don't know if you want mods for your game).  The reason is that as far as I know, there is no way to add static variables to a class at run time(which would be required if you loaded external files in or something).  Also, each time you added a loot to the loot table, you'd need to add a static int to the class as well.

But, if you can work with the catches, I like this solution a lot.  Anytime you are coding things, such as which items an enemy carries, you can easily use the class and static variables to easily get the ids of the items, and also get assistance from intellisense in the process.



@kburkhart84 Yea, having intellisense support would be nice and while my expectation of even releasing this game are somewhat low (since I am really just doing this as I enjoy coding and enjoy gaming and this combines both of those), I would like to not restriction myself from not allowing modding plus I prefer this method for my own development as adding a piece of loot is as simple add an items to the json file and nothing more. I also don't have to worry about the order of the items with dynamically generating my string -> id mapper as with a class the manually sets the ids, if I remove an item in the middle of the list, all the ids afterwards would get messed up. I am sure there are ways to work around that (using an enum might work) but dynamically generating the mapper makes it so I don't have to do anything special for it and I can organize my files any way I want, change the loading order, etc. without much worry.

Hey, I understand.  That's why I specifically mentioned the 'gotchas' with my method.  I like my method, but it doesn't work for every scenario.

In your case, I don't think using enums would work either, as those work similar to my method and get defined at compile time.  I'm no C# expert though, so maybe there is a way to get them going at runtime.

My thoughts though...how important is the performance of this particular piece of code.  A data structure(dictionary, list, etc...) that is accessed by an index is faster than one accessed by string(with string compare), but does that speed matter here?  This may be a case of where you should use whatever is more convenient because the speed wouldn't matter anyway.



This topic is closed to new replies.

Advertisement