Jump to content
  • entries
    44
  • comments
    143
  • views
    52555

Using a Metadata Database

Sign in to follow this  
Eck

1138 views

Hey everyone - long time no post. Sorry about that. :) I landed my dream job over a year ago and have been pretty busy since then. I'm working at Harebrained Schemes on the new turn-based Battletech game. The last one was over 20 years ago! :D Come check it out at:
http://battletechgame.com/

Today I'm going to talk a little bit about a metadata database (That's really fun to say btw) and how you might use it in your projects.

Database_Schema.thumb.png.2a40803e78f0d626311f12467a77a6e4.png

What is a metadata database?

Let's start with a couple of definitions. Metadata is just data about other data. And a database is just a structured way of storing and accessing data. So... a metadata database is a structured way of storing and accessing data about other data... Is your mind blown yet?

Why use a metadata database?

I'm going to look at our units for this example. We have a bunch of units with lots of data stored in separate files. Our unit metadata contains things like the filename, the type of unit: mech, vehicle, turret - and tags that describe the kind of unit that it is: medium, sniper, jump_capable. Instead of hard coding our unit spawn points to a specific unit, we configure the spawn point to ask for a unit with the tags "mech" and "medium" to change things up a bit. Without a metadata database, we'd have to load up every single unitdef into memory, and then loop through all of the data to build a list of the units that match, then select a random entry. With a MDDB, we can write a query that returns the list of units that qualify without having to load every single file and load the unit that we need to spawn.

Also, once you put this type of data in a database, you can start writing sql queries to easily get at information. How many maps implement a particular encounter? How many contracts are written for the Escort contract type. Are there any events that can't be triggered because they rely on tags that are never awarded.

Some Library Options

We're using C# and Unity for our project, and these are the main tools we're using for our SQL needs.

Some TagSet Query Code

Here's some C# I wrote that builds a dynamic bit of sql based on the number of required tags and excluded tags. It wasn't trivial so I figured I'd share it. One requirement I'm not completely happy with is that the tags you ask for have to be in the database. At the start of the function I insert the ones that weren't present. It made the sql a little bit cleaner to look at and get right.  For our needs it's not a big deal because we'll only be asking for tags that we care about, but if an end user is typing in random stuff you'll want a slightly different approach.

Also I made one change to the Schema since after the graphic was made. I dropped the TagID and just use Name as the primary key. TagSetTag then drops its TagID column and gets a TagName column to point to Tag. I recommend that datamodel instead of the one shown, but our fans made the graphic for the data model and I didn't have a way of updating it easily. :) The code presented matches the old way.

public static List<TagSet_MDD> GetTagSetWithRequiredTags(this MetadataDatabase mdd, TagSetType tagSetType, TagSet requiredTags, TagSet excludedTags)
{
    // Get the tag rows for the specified tags so we can get their database ids.
    List<Tag_MDD> requiredTagRows = GetOrCreateTagsInTagSet(mdd, requiredTags);
    List<Tag_MDD> excludedTagRows = GetOrCreateTagsInTagSet(mdd, excludedTags);

    // Here's what the query will look like for 2 requried tags and 1 excluded tag
    /*
    select
        ts.*
    from TagSet as ts
        -- Required Tags
        inner join TagSetTag as tst0
            on ts.TagSetID = rtst0.TagSetID
        inner join TagSetTag as tst1
            on ts.TagSetID = rtst1.TagSetID
        -- Excluded tags
        left join TagSetTag as etst0
            on ts.TagSetID = etst0.TagSetID
            and etst0.TagID='tag id 3'
    where
        rtst0.TagID = 'tag id 1'
        and rtst1.TagID = 'tag id 2'
        and etst0.TagID is null
    */

    string queryText = "SELECT ts.* FROM TagSet ts ";
    string joinText = string.Empty;
    string whereClause = string.Format("WHERE ts.TagSetTypeId = {0} ", (int)tagSetType);

    // Join to one instance of TagSetTag for each required tag.
    for (int i = 0; i < requiredTagRows.Count; ++i)
    {
        joinText += string.Format(GTSWRT_RequiredInnerJoinFormat, i);
        whereClause += string.Format(GTSWRT_RequiredWhereClauseFormat, i, requiredTagRows[i].TagID);
    }

    // Join to one instance of TagSetTag for each excluded tag
    for (int i = 0; i < excludedTagRows.Count; ++i)
    {
        joinText += string.Format(GTSWRT_ExcludedLeftJoinFormat, i, excludedTagRows[i].TagID);
        whereClause += string.Format(GTSWRT_ExcludedWhereClauseFormat, i);
    }

    // Assemble the query text and return the results.
    queryText = queryText + joinText + whereClause;

    List<TagSet_MDD> tagSetList = mdd.Query<TagSet_MDD>(queryText).ToList();

    return tagSetList;
}

 

Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By Rio Lloyd
      Hey all!
      we are a team of 3 looking for more members, 
      we are making an isometrical Survival RPG.
      we are looking For Members who can make low poly 3D artists who can do character models, environments, tools and more.
       
      if interested and want to know more email me at rioishere14@gmail.com
    • By nxrighthere
      BenchmarkNet is a console application for testing the reliable UDP networking solutions.
      Features:
      Asynchronous simulation of a large number of clients Stable under high loads Simple and flexible simulation setup Detailed session information Multi-process instances Supported networking libraries:
      ENet UNet LiteNetLib Lidgren MiniUDP Hazel Photon Neutrino DarkRift More information and source code on GitHub.
      You can find the latest benchmark results on the wiki page.
       
    • By trapazza
      I'm trying to add some details like grass, rocks, trees, etc. to my little procedurally-generated planet. The meshes for the terrain are created from a spherified cube which is split in chunks (chunked LOD).
      To do this I've wrote a geometry shader that takes a mesh as input and uses its vertex positions as locations where the patches of grass will be placed (as textured quads).
      For an infinite flat world (not spherical) I'd use the terrain mesh as input to the geometry shader, but I've found that this won't work well on a sphere, since the vertex density is not homogeneous across the surface.
      So the main question would be: How to create a point cloud for each terrain chunk whose points were equally distributed across the chunk?
      Note: I've seen some examples where these points are calculated from intersecting a massive rain of totally random perpendicular rays from above... but I found this solution overkill, to say the least.
      Another related question would be: Is there something better/faster than the geometry shader approach, maybe using compute shaders and instancing?
    • By FedGuard
      Hello all,
       
      I would like to start off with thanking you all for this community. Without fora like these to assist people the already hard journey to making an own game would be exponentially more difficult. Next I would like to apologize for the long post, in advance...
      I am contemplating making a game. There, now that's out of the way, maybe some further details might be handy.
      I am not some youngster (no offence) with dreams of breaking into the industry, I am 38, have a full-time job, a wife, kid and dog so I think I am not even considered indie? However I recently found myself with additional time on my hands and decided I would try my hand at making a game.Why? Well mostly because I would like to contribute something, also because I think I have a project worth making (and of course some extra income wouldn't hurt either to be honest). The first thing I realized was, I have absolutely no relevant skill or experience. Hmm; ok, never mind, we can overcome that, right?
      I have spent a few months "researching",meaning looking at YouTube channels, reading articles and fora. Needless to say, I am more confused now than when I started. I also bought some courses (Blender, Unity, C#) and set out to make my ideas more concrete.
      I quickly discovered, I am definitely not an artist... So I decided, though I do plan to continue learning the art side eventually, I would focus on the design and development phase first. The idea being, if it takes me a year or more solely learning stuff and taking courses without actually working on my game, I would become demoralized and the risk of quitting would increase.
      So I thought I would:
      1: Keep following the courses Unity and C# while starting on the actual game development as the courses and my knowledge progress.
      2: Acquire some artwork to help me get a connection with the game and main character, and have something to helm keep me motivated. (I already did some contacting and realized this will not be cheap...). Also try to have the main character model so I can use it to start testing the initial character and game mechanics. For this I have my first concrete question. I already learned that outsourcing this will easily run up in the high hundreds or thousands of dollars... (lowest offer so far being 220 USD) I am therefore playing with the idea of purchasing https://assetstore.unity.com/packages/3d/animations/medieval-animations-mega-pack-12141 with the intention of then have an artist alter and/or add to the animations (it is for a Roman character so some shield animations are not going to work the same way.). This way I could start  with the basic character mechanics. Is this a good idea, waste of money,...? Any suggestions? I then have a related but separate question. Is it a good idea to buy Playmaker (or some other similar software I haven't yet heard of like RPGAIO), and using this for initial build, then changing/adding code as the need arises?
      3.Get a playable initial level ready as a rough demo and then starting to look for artist for level design and character/prop creation.
      ...
       
      I would really appreciate some input from more experienced people, and especially answers to my questions. Of course any advice is extremely welcome.
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!