Extending Mojo3D

Home Forums Monkey 2 Programming Help Extending Mojo3D

Tagged: ,

This topic contains 26 replies, has 3 voices, and was last updated by  nerobot 1 week, 2 days ago.

Viewing 12 posts - 16 through 27 (of 27 total)
  • Author
    Posts
  • #10338

    Ethernaut
    Participant

    Challenge accepted! 🙂 (will take a while, though, I’m really slow)
    I don’t think GetComponentBox will be that useful, I put it there just in case I need it for now. Also need to rename it to GetEntityBox…

    >>I’m interested in how you will override them?

    Mostly I won’t! The plan is to leave the Mojo3D Entity subclasses alone, and add as much new functionality as possible through components only. I don’t think I’ll even add virtual classes on EntityBox, all the events will be called on the components. But you’re right, we’ll see, I may have to change a lot as I port my old projects.

    #10358

    Mark Sibly
    Keymaster

    Actually, I quite like the ComponentBox idea – it does provide a way to add fields to a class via class extension anyway.

    One think I have added to Entity that may be of use here is:

    Very simple, but I think it should be very useful.

    I am using this to store the RigidBody for an entity in the entity itself (similar to a component I guess). To date, while you have been able to do ‘rigidBody.Entity’, you haven’t been able to do the opposite, ie: ‘entity.RigidBody’. Since I want to keep physics in an optional module, Entity may not necesarilly know about RigidBody. I didn’t want to go for a full blown Component system here, because I haven’t need it – everything works except for entity.RigidBody and this fixes that.

    But the dynamic property stuff is also there for general use and it would be entirely possible to use it for a ComponentBox, eg:

    This is, of course if you *really* want to use Entity as *the* GameObject type. I’m not sure this is a such good idea, but I think I’m basically just gonna sit this one out and watch what you come up with as I don’t have a lot of experience here.

    Another thing with the component virtual methods, with the ComponentBox approach it ‘s kind of a non-issue in a way. For example:

    Therefore, calling entity.Update() will call all virtual Component.OnUpdate methods. You can’t override Entity.Update, but the point here is to not have to extend Entity anyway, but use Component instead, right?

    Another thing that may help is the ‘signals’ in Entity, ie:

    These are ‘hooked’ by RigidBody and could be by ComponentBox too, eg:

    Again though, this assume Entity *is* your GameObject which for some reason makes me hella nervous…but please ignore me as this is well outside my comfort zone.

    Very keen to see what you come up with!

    #10360

    nerobot
    Participant

    DynamicProperty looks good. And I like entity’s signals, it may helps to wrap entity into gameobject if we want to provide public gameObject.Entity property to work directly with entity. But need to add many signals in this case, like Moved, Rotated, Scaled.

    #10361

    Mark Sibly
    Keymaster

    I don’t know if I’lll be adding Moved/Rotated/Scaled signals. I think (a bit like Layout) changes to entity matrices are much better dealt with in one ‘hit’ in one phase. It can take game logic several moves/rotates etc to update an entity, and if each step triggers an OnMove (and possibly child OnMove recursively etc) it can add up.

    Entity does in fact have a (currently hidden) Seq:Int property that is incremented when entity matrix is modified. This is actually used by physics to update bullet data if necessary just before World.Update(). A game engine could do the same.

    I think this is partly why I’m nervous about using Entity as GameObject. There is not real control over what can be done to the entity – it’s kind of like having a public field. Unless I add a signal to *every* setter and potentially modifying method, there is just no sane way to tell what has been done to the entity.

    On the other hand, if all operations go through a GameObject or Component wrapper and the underling enties are private fields, the wrapper knows exactly what’s going on, fire off signals, call virtual methods and generally do whatever it needs to do. It can ‘redesign’ the entity API, add new methods, hide unwanted ones etc. Yes, there’s a fair bit of crappy work involved, but the win is 100% control over the underlying entity.

    #10363

    Mark Sibly
    Keymaster

    Ok, I’ve hacked up yet another approach to all this. This attempts to duplicate unity’s system in that matrix/hierarchy are stored in a Transform component that is present in all game objects. It implements the transform component using a dummy entity. Any camera, light and model etc components use this dummy entity as a parent for their internal mojo3d entties.

    The actualy entities involved are *never* publicly available so there’s no chance of the hierarchy being broken/rearranged behind your back or any other other weirdness happending. Also, I’ve added signals for ALL property setters just for the hell of it.

    It doesn’t look too bad to me. There’s a certain amount of work involved adding wrappers for everything, but there aren’t that many entities so IMO it’s doable. Transform will probbly be the trickiest as that’s how you move things around etc. But lots of that stuff is in an extension class that can be copied/pasted too.

    The coolest thing about this IMO is that GameObject/Component are 100% ‘clean code’. There are no dependancies on how mojo3d or Entity works (or doesn’t!).

    #10366

    nerobot
    Participant

    Wow, cool! 🙂

    One thing I dislike here – using component string name. In my code above I achived this by Typeof().Name, because you can take a mistake in string but not in type name.

    cam=GetComponent<Camera>()

    Afaik, in unity you can’t directly create components, them exists attached to gameobject only. Private / internal constructor is here.

    When we call gameObject.AddComponent () we get new instance.

    In monkey we can also declare private constructor and call virtual protected OnCreate method.

     

    My undone approach is here: https://bitbucket.org/nerobot/cluequa2d

    I think my core code (GameObject, Component, Behaviour) is good enough. 🙂

    #10371

    Ethernaut
    Participant

    I like this a lot!

    But doesn’t the GameObject approach mean you have to wrap all the functionality in the Entity subclasses? What I like about using Entity “directly” is that the box class makes very little assumptions about the Entity class, and simply provides access to the functionality not present in Mojo3D.

    In other words, even if Mojo3D changes a lot, it would still be easy to adapt the component system to work, while eliminating the “why did you change it, Mark?” type of whining! 😉

    One thing I dislike here – using component string name

    I definitely want to implement your reflection method when my brain recovers from being fried after taking care of a toddler during the day and learning to use Houdini at night… 🙂

    One question though… doesn’t that mean using reflection allows you only one type of component per Entity? Using string means you can possibly name them differently.

    One of the components types I like using a lot is a “Modifier” component. It simply changes another entity’s “Stats” component on collision. For instance, a bullet can have two Modifier components, one that subtracts -10 from a “shield” stat, and one that checks for the shield, and and subtracts X from health depending on how much shield you have.

    While you can have a single Modifier component that does more than one thing, it was really fun to keep those components as simple and small as possible, and control game logic by adding more than one when necessary. I don’t know, I’ll think about it.

    (if you’re concerned about performance when creating that many components, I made a while ago a single stage 2D side scrolling shooter test using this philosophy, and it had hundreds of entities. The update loop, not including rendering,  was still a fraction of a millisecond!)

    Cheers!

    #10372

    Mark Sibly
    Keymaster

    One thing I dislike here – using component string name. In my code above I achived this by Typeof().Name, because you can take a mistake in string but not in type name.

    I didn’t put much thought into how the actual component system should work, and that ‘s sort of the point – having ‘clean’ GameObject and Component classes means you can do whatever you want, however you want.

    But doesn’t the GameObject approach mean you have to wrap all the functionality in the Entity subclasses?

    Yes it does, and it’s up to you to decide if that’s an acceptable amount of work. But it *does* give you 100% control over access to entities, so you can fire off callbacks and invoke signals etc whenever you want etc. You can also mess with parameters, or even prevent properties being modified or methods being called at all. It’s a form of Proxy object I guess, and is really the only way I can think of to gain 100% control over an object.

    A ‘halfway’ solution to this would be to add Entity:Camera, Entity:Light, Entity:Model properties to components to return underlying entities, so people could access component entities directly. This would save you writing all the ‘wrapper’ properties/methods, but again, you lose a degree  of control over things this way, as you have NO IDEA how the entity could potential be modified. But its really up to you how big a deal that is. The above is just an example of IMO a 100% safe/clean approach.

    #10374

    Ethernaut
    Participant

    Thanks, I think I have plenty to digest now. Will keep my progress posted!

    #10376

    Mark Sibly
    Keymaster

    And just to confuse things a bit more, here’s another approach!

    This is a bit of a compromise in that it doesn’t store entities in components, but stores a single entity per gameobject (which is effectively its ‘transform’ too) that you can access directly. This means a gameobject can’t have both a camera and a light component – it must have one or the other. You can think of a gameobject’s entity as a sort of special case component.

    It doesn’t bother managing a hierarchy – gameobjects are just stored in a linear stack. You can of course parent gameobject entities to each other though, much like Transform above.

    Again, the implementation of components here isn’t really important, I’m more trying to think out how mojo3d can be interfaced with.

    #10381

    nerobot
    Participant

    This is a bit of a compromise in that it doesn’t store entities in components, but stores a single entity per gameobject (which is effectively its ‘transform’ too) that you can access directly.

    As a variant. But storing (wrapping) entities in components allow us easilly replace mojo3d.entity with any other and our system will still work because we work with components not with raw entities.

    This means a gameobject can’t have both a camera and a light component – it must have one or the other.

    I checked it – unity3d allow us to place light and camera into single gameObject. So you can do it if you wish (although it’s looks abnormal way).

    #10384

    nerobot
    Participant

    As for me, component-based approach can be presented as a custom module – internal or 3d party.

Viewing 12 posts - 16 through 27 (of 27 total)

You must be logged in to reply to this topic.