Search Unity

Assets [InfinityPBR.com] Alpha: Master Class System (Free during Alpha/Beta)

Discussion in 'Works In Progress - Archive' started by infinitypbr, Jan 13, 2018.

  1. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    WIP Mega Thread

    Hey all,

    I've been working on this thing I call the "Master Class System". I started to make my game, a 1st person RPG, and realized that I didn't want to script all the classes manually. I figured there could be a way to set the default values and all the class structure in a more easy-to-user manner. For the past maybe 12 months I've been working on this on and off.

    It's in alpha right now. It works, can be used to make games, but could probably be much much better.

    I'm hoping some of you may be interested in helping me make it better. I am by no means a great coder. But I think I've made something of value.

    What it does
    You create your classes using drop downs and buttons, adding variables, types, and linking them all together. There's a Table Editor as well, so that you can quickly and easily populate table values, like Stats or other information.

    When you're ready, click the button and all your classes will be exported for you, and you'll be ready to start coding your game. If you need to make changes, make them in the editor, then re-export the classes, and your changes will be there.

    I made a sort of rambling demo here:



    Please download the unity package below, and let me know what I can do to make this better! There's definitely a few things I feel could be better -- there's a lot of boilerplate code that I repeat for each type, and I swear there should be an easier way to do that, to loop through all available types...but I haven't figured it out yet. Maybe you could?

    Thanks, and enjoy!

    LATEST VERSION:
    http://www.infinitypbr.com/files/masterclasssystem_alpha6.unitypackage
     
    Last edited: Mar 18, 2018
  2. Neviah

    Neviah

    Joined:
    Dec 1, 2016
    Posts:
    235
    Does this handle skills too? I don't see why it wouldn't, just want to make sure. I've been looking for a sort of skill system.
     
    infinitypbr likes this.
  3. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    First small bit of feedback: use namespaces. PlayMaker was choking on your Strings class.

    Second bit, I think the reason you have so many classes is because the classes structured like "DataInts" could be a single generic class.
    Code (CSharp):
    1. public class Data<T>
    2. {
    3.  
    4.     public string name;                             // Human Readable name
    5.     public string dataName;                         // Data List we're referencing
    6.     public List<T> value = new List<T>();                       // The value List
    7.  
    8.     [HideInInspector]
    9.     public string updateName = "";
    10.     [HideInInspector]
    11.     public bool showList = false;
    12.     [HideInInspector]
    13.     public bool showThis = false;
    14.     [HideInInspector]
    15.     public bool storeInSaveFile = false;
    16.  
    17.     public Data()
    18.     {
    19.  
    20.     }
    21.  
    22.     public Data(string newName)
    23.     {
    24.         name = newName;
    25.     }
    26.  
    27.     public Data(string newName, string newDataName)
    28.     {
    29.         name = newName;
    30.         dataName = newDataName;
    31.     }
    32.  
    33.     public Data<T> Copy()
    34.     {
    35.         Data<T> copy = new Data<T>();
    36.         copy.name = this.name;
    37.         copy.dataName = this.dataName;
    38.         for (int i = 0; i < this.value.Count; i++)
    39.         {
    40.             copy.value.Add(this.value[i]);
    41.         }
    42.         return copy;
    43.     }
    44. }
     
    Last edited: Jan 13, 2018
    infinitypbr likes this.
  4. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    And honestly I think that's going to cut down your code by about 11-fold. You can create a nested loop of data types in the editor code instead of a separate loop for each data type.

    I need to add a potential caveat here. Unity's serialization system is...basic. I don't think serializing generics is an issue, but it might be. I finally gave up on Unity serialization this year because it was forcing me into some really bad practices.
     
    Last edited: Jan 13, 2018
    infinitypbr likes this.
  5. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Yes, as far as I can tell it should handle any concept at all.
     
  6. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Ok, new version linked up top, with "MCS" namespace, if I did it right :)

    I looked into generics, but wasn't able to figure it out before. I"ll have to look into it again. It did sound like what I was looking for, just couldn't get it working I guess.

    Do the exported classes need to be part of a namespace too?
     
  7. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    The exported classes do not need to be a part of a namespace since they are named by the user. However, since you're creating what is essentially a code generation tool, you might want to consider giving the user an option to specify a namespace.
     
    infinitypbr likes this.
  8. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    The code above should be enough to get started. Basically, a generic lets you defer type specification until implementation time. So, worst case, instead of all of these type-specific classes, you would just have that one.

    Then, in your code, instead of

    List<DataTexture2D> dataTexture2ds;

    you would have

    List<Data<Texture2D>> dataTexture2ds;

    The really sophisticated serialization of something like Odin Inspector lets you do even cooler things like specify derived types in the inspector. When you do that, you can take code reuse to a whole new level. If you ever want to see some of that, let me know and we can skype or zoom about it. Of course, for salable assets, you're stuck with Unity serialization.
     
    Neviah likes this.
  9. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Thanks -- I started, and got stuck. I've been battling the flu for 2 weeks, so I think maybe a 2nd look when things are less flu-y may be good. Doesn't help that I only look at this code every few weeks, so each time I have to figure out what I Was doing :)
     
    Neviah likes this.
  10. BackwoodsGaming

    BackwoodsGaming

    Joined:
    Jan 2, 2014
    Posts:
    2,229
    I have the same problem with everything I try to come back and start working on. It is almost like I have to teach myself all over again. Hope you get to feeling better soon.

    I've been following since you started this thread. The phrase "Master Class" is what sparked my attention and I started wondering about the possibility of it supporting sub classes/specialization classes. From what I've read so far, it doesn't seem to be part of the original intent. Feel free to correct me if I'm wrong. :) Maybe it will be something I can adapt down the road, if not.
     
  11. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    What do you mean by sub classes / specialization classes?
     
  12. BackwoodsGaming

    BackwoodsGaming

    Joined:
    Jan 2, 2014
    Posts:
    2,229
    I recall some games having something where you pick a main class and then after 10-15 levels, you can choose a sub-class/specialization. So if you start out as a mage, you might have something like elementalist, pscion, etc as different sub-classes or specializations down the line. A sub class may give options of choosing and switching between the subclasses, where a specialization might be the same thing but only allow one choice between the different options where all of the training from then on would be solely focused.

    I've seen it in quite a few different games but at the moment it has been so long since I've played any that I can't remember which ones they were. lol
     
  13. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Final fantasy 11 had sub classes...
     
  14. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Ah ok! Then yes :)

    I wasn't sure if it was a programming thing or not -- I'm aware I don't know everything, so "Sub class" could be a thing like "Class" is a thing in programming.

    In the demo, there are 32 classes, and each one has a "Single Custom Variable", which is a custom variable with a single value, called "Parent Class", type String. They also have a bool called "Base Class".

    The base classes will have that checked, and no Parent Class. The rest will have a Parent Class, and in the coding of the game, that's how I'll know if the user can get the next class.

    Screen Shot 2018-01-15 at 7.51.17 PM.png
     
    BackwoodsGaming and Neviah like this.
  15. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    Since you're making the code for the classes, you could probably use reflection to make that parent class a dropdown instead of an open string field. Less for a user to fat-finger.
     
    infinitypbr and Neviah like this.
  16. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Looks like I actually did the wrong type for that. It was supposed to be of "Classes" type with "Single" as the option, meaning just a single value from the "Classes" items.

    Adding new version below:
    Screen Shot 2018-01-16 at 12.45.56 PM.png

    And then it looks like this:
    Screen Shot 2018-01-16 at 12.46.11 PM.png
     
    BackwoodsGaming and Neviah like this.
  17. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    This is pretty cool, Andrew. It's kind of like nHibernate or Entity Framework. Nice job. I think genre-specific code generation tools are going to be really helpful for some people.
     
    infinitypbr likes this.
  18. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Did I paint myself into a box? I may have.

    PROBLEM: I want to save game data. ScriptableObjects can't be serialized. So the "Game" class, which is a scriptable object type, either can't be that, or I need another structure that can be serialized.

    POTENTIAL SOLUTION: I'm thinking maybe there should be two main classes, a "Data" one and a "Master" one. W/ the master being the scriptable object that holds all the static data such as "Hit points per level" and "Minutes per second" etc. Stuff that doesn't change and doesn't get saved (because it doesn't change).

    And a 2nd one "Data", that holds the actual data and can be serialized.

    Thoughts?
     
  19. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    I was certain scriptable objects could be serialized as .asset files. In fact, that's their primary purpose. Perhaps there is something in the Game class that is not serializable that you have have to explicitly mark as such. However, you can always serialize to Json or xml using .Net.
     
  20. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Maybe -- everything I've seen says scriptable objects can't be serialized, but I'm sure there'd be a way around it.

    I think the solution for this is to have a scriptable object for the "data" of the game -- the stuff that doesn't change. And then another script that holds the mutable data like locations of enemies, players stats etc. That would be serializable, it'd be on an object that can be loaded and DontDestroyOnLoad() etc. So I'll go with this angle for now, and see how it works.

    It'll need to build the script, then create a prefab with the script attached, and then populate the values with the default values. Starting stats, starting locations etc.
     
  21. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    http://www.infinitypbr.com/files/masterclasssystem_alpha3.unitypackage

    ---
    EDIT/UPDATE: I wonder if I even need this code. When I comment out part that runs the method, everything ends up the same, and it looks like it's all set. I still need to write the last part, which populates the data with the default data...but maybe I don't need this bit at all, and that's why it's causing an error.
    ---

    I'm going to have to sleep on this one. For some reason, the code below throws this error:

    NullReferenceException: Object reference not set to an instance of an object
    MasterExporterTrigger.GameSetupSpecialObjects () (at Assets/SFBayStudios/Master Class System/Editor/MasterExporterTrigger.cs:11711)


    Code (CSharp):
    1.         GameObject go = GameObject.Find("Game");
    2.         Game goComp = go.GetComponent<Game>();
    3.         goComp.main.data.vector2Test = new Vector2s("Vector2"); // THIS IS THE LINE THAT THROWS THE ERROR
    Thing is, it seems that the code is still running, and I can't figure out where the NullReferenceException is coming from. If you install the latest version and export the scripts, you should see the error in context. This part of the script is setting up populating the data in the "Game" object which shows up in your scene. This will be the object that you keep throughout the game that holds mutable data.

    It seems to be populating just fine, but there's this error. Any idea where it's coming from??
     
    Last edited: Jan 29, 2018
  22. Sovogal

    Sovogal

    Joined:
    Oct 15, 2016
    Posts:
    100
    Could you post up the repro steps or a scene that demos the issue? Based on the code, it could be that the "Game" game object doesn't have a Game component, or the Game component doesn't have a main object, or the main object doesn't have a data object.

    You can set a breakpoint in visual studio at that line to inspect the values of each object. Or you can Debug.log their values to see what they are.
     
  23. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    The version linked (#3), will reproduce it if you click the export button. I'm going to move forward with the population code, and see if maybe for whatever reason I don't actually need the step that was causing an issue.
     
  24. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    I've added these checks:

    Code (csharp):
    1.  Debug.Log(InSceneObject().name);
    2.         Debug.Log (InSceneObject ().main);
    3.         Debug.Log (InSceneObject ().main.data);
    4.         Debug.Log (InSceneObject ().main.data.name);
    It errors out looking for .main.data

    InSceneObject() returns the component that's attached to the in scene game object. So that part works. But somehow the component hasn't yet "registered" that main.data exists when it tries to run this part of the code. Visually you can see it in the inspector with the in game object selected.

    Somehow I need a check to make sure it exists. I'll see about adding that into the auto code.
     
  25. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    SOOOO CLOSE. But still a bug.

    http://www.infinitypbr.com/files/masterclasssystem_alpha4.unitypackage

    To reproduce, load the latest version linked above, and then click the "Export Classes" button.

    The Null Reference error is now on the first line:

    Code (csharp):
    1.  
    2. Debug.Log (InSceneObject ().player [0].skillClass.leather);
    3. InSceneObject ().player[0].skillClass.leather = "Novice";
    4.  
    The in scene object (called "Game", created during the export process), has player.skillClass.leather visible, but for some reason, the .leather part throws the null reference error.

    The problem from yesterday was actually the same type of thing. I'm not sure how I fixed it, but I did move the running of these bits of code until later in the process. I can't do that again for this, though, because this is the last step in the export process.

    Visually we can see the class exists, player.skillClasses.leather

    But somehow, it doesn't seem to exist in Unity. If you look at the code you'll see that I wait over 800 "Frames", and I even create and destroy another game object in the scene, thinking maybe the editor just needs more time to register the class structure. But that didn't seem to work.

    I'll have to sleep on it again. :(
     
  26. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    http://www.InfinityPBR.com/files/masterclasssystem_alpha5.unitypackage

    That one works! You know what the solution was? Just moving the order around. I moved the step that was before adding the component to right after it. They don't relate. So just switched them. And for whatever stupid reason, that fixed it.

    So now when you run the code and export classes, your scene will have an object called "Game" with a serializable component pre-populated with your starting data.

    Next step is to get the save code working, which I think is something everyone will sort of need. :)
     
  27. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    http://www.infinitypbr.com/files/masterclasssystem_alpha6.unitypackage <--- latest version that includes this demo scene thus far.

    I'm working on the demo, a 1st person RPG (aka the game I'd like to make), and I ran into a couple times when the "Master Class System" was nice and forgiving when I made mistakes. This video below shows one simple example, where I needed to add a boolean to the Player class structure to know if the player was a "Player" or a "Hireling". I could have done it by searching the name "Player 1" etc vs "Hireling 1" but I think the boolean is easier.

    So I added the boolean in the Master Class System, used the Table Editor to mark the four players as "Is Player", and re-exported the class. Fixed!

     
  28. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Another video, about 7 minutes long, showing a new checkbox I added to turn on/off saving an in-game value set as a "List" or not. It affects how the data is saved, and also how you can call it via code. There are use cases either way, so it'll be an important option to have.