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 15 posts - 1 through 15 (of 27 total)
  • Author
    Posts
  • #10297

    Ethernaut
    Participant

    I recently started to build my own Component system “on top” of Mojo3D, so that I could have objects with components, a design that I really like, where each component can have events like “OnUpdate”, “OnDraw( canvas )”, but also more gameplay specific things like “OnCollision” or even “OnPause” and “OnInteract”, etc.

    Since I didn’t want to modify Mojo3D, I wrapped its Entity class in my own class, GameObj, that contained the components , and had “OnStuff” events of its own as well. So far so good. I could create my own objects, add any kind of Mojo3D entities (Model, Sprite, Camera, etc.) to each one, add components that did stuff, and life was good for a while.

    Then as I moved forward, I noticed I was having to wrap a lot of things, like having my own scenes on top of Mojo3D scenes, my own parent/child hierarchy that in turn managed Mojo3D’s, etc. Things started to get messy and annoying to deal with.

    Not being a real programmer, I wanted to ask the real ones their thoughts on this problem. Should I:

    • Stop whining, deal with it and wrap everything like a champ!
    • Fork Monkey2 and create a new branch just to modify Mojo3D (adding things like Component Stacks, some Virtual Methods, etc)? Seems like this would work fine, until I want to share this with other people, then I’d have to ask them to install this modified version of Mojo3D, which sounds messy to me. I like having as little dependencies as possible. Or…
    • Beg Mark please please pretty please to implement some sort of basic, but extendable, component system in Mojo3D’s entities? Seems like he’s got a lot to do on his hands already.

    Cheers!

    #10303

    nerobot
    Participant

    I also like component-based system and even started to do similar ‘framework’ for 2d, almost unity3d-clone by concept / structure / naming.

    But I left / freeze this project.

    The most difficult thing for me was coordinate processing – each GameObject can have it’s own scale and rotation and children hierarchy. And we should to calculate local and global values, matrix matrix matrix. 🙂

    I can help to concrete problems. Looks like if you complete your wrapper – you can easily add new features. And you can start with minimal functional and extend it as needed.

    #10304

    Mark Sibly
    Keymaster

    I have no desire to turn mojo3d into a component system, it’s very lightweight and I like it like that.

    I’m not even 100% what you’re try to achieve here anyway. Do you want to make Entity final and implement cameras, lights, models, etc via components instead of subclassing? The way Unity does it, even entity transform is not part of entity – you want to do this too?

    #10305

    Ethernaut
    Participant

    it’s very lightweight and I like it like that

    Me too! I love how fast it is, which is why I didn’t want to modify anything, and want to add my gameplay stuff “on top”.

    My primary focus is mostly on adding gameplay via components, so the unity “everything is a component” is not necessary (although I have to admit I like it a lot). Then you can basically create game logic by loading .json files that specify new entities, then their components (i.e. Inventory, Stats, etc.), then just the component values that differ from the default.

    I also like making the components work via “OnStuff” events, it’s really easy to wrap your head around code written like that for me.

    Currently I have a GameObj class, and since it can contain any Mojo3D entity, I can turn a GameObj into anything. But I have to have components for all that, like a “LoadModel” or “LoadSprite” component that only kicks in at the game start, loads the Mojo3D entity into the “_entity” field, then does nothing else, while the gameplay components generally work on every frame. It works, but I was wondering if I’m going down a road full of unnecessary pain, that’s all.

    Prior to Mojo3D I actually had a pretty neat, functioning 2D entity/component system that I started way back with Monkey-X, but it was taking me a long time dealing with all the transformations (with hierarchies), collisions, any math stuff, etc. So I’d rather not deal with that!

    #10306

    Mark Sibly
    Keymaster

    Currently I have a GameObj class, and since it can contain any Mojo3D entity, I can turn a GameObj into anything. But I have to have components for all that, like a “LoadModel” or “LoadSprite” component that only kicks in at the game start.

    I have no idea what you’re talking about here sorry! What exactly would you like done to mojo3d?

    I’m certainly into exploring ideas here, and I think there may be some overlap with several problems I’m yet to solve, but I just want to make sure we’re on the same page. From the above, it sounds more to me like you’re talking about a ‘scripting’ system what with all the loading going on!

    Perhaps post some hypothetical sample code, ‘making up’ any methods you’d like to see added?

    #10307

    Ethernaut
    Participant

    Also, I have to ask: would it be a good idea for Class Extensions to allow adding fields and virtual methods? Because that would essentially solve my problem… I’d be able to extend “Entity” by adding a Component Stack, some “OnStuff” virtual methods, and not that much else, and all classes that inherit Entity would inherit those changes! The rest is done by the SceneView class, which knows how to handle use extra fields and methods (by calling “OnUpdate” every frame, for instance).

    But I’m pretty sure there’s some Computer Science reason why it shouldn’t be done like that, isn’t there?

    #10308

    Mark Sibly
    Keymaster

    would it be a good idea for Class Extensions to allow adding fields and virtual methods?

    It’d be brilliant! However, it’s also  pretty much impossible in a compiled language like monkey2. Adding fields changes the size of the object and adding virtual methods changes the size of the virtual function table. Both need to be fixed for ‘New’ to work. Offsets of fields/methods would also clash like crazy between modules. This is only really possible in a dynamic language like python/javascript etc.

    #10309

    nerobot
    Participant

    As for me – GameObject is a core object which don’t extends any base class. It contains components and allow us some manipulating by setting layer and enabled properties, as well as providing OnStuff callbacks. In my framework I add OnStuff callbacks to MonkeyBehaviour class to left gameObject as simple as possible.

    Then you create any components like

    Mesh, Sprite, etc (not LoadMesh, LoadSprite)

    And then add it into game object. To simplify process you can write helper functions like

    In my framework I extends Behaviour class for scriptable, that contains ‘enabled’ property.

    (need to add repository to rely on code)

    #10310

    nerobot
    Participant

    Inside of your components you can store ‘raw’ monkey2 entities / parts. And manage them under the hood. 🙂

    #10312

    Ethernaut
    Participant

    Here’s my work in progress… like I said, this is working, but it’s getting messy. I wanted tips on how to better design something like this: https://github.com/DoctorWhoof/game3d

    This is the base GameObj class that holds the components and the Mojo3D entity. You can see a bunch of virtual methods near the bottom. Most of those don’t do anything yet, but they worked well in my old Monkey-X 2D entity system, and I’m still porting it to Monkey2 / 3D.
    https://github.com/DoctorWhoof/game3d/blob/master/core/gameobj.monkey2

    You can look at this example for a very simple test use (no gameplay yet, just some basic components):
    https://github.com/DoctorWhoof/game3d/blob/master/_examples/view/game3dview.monkey2

    The “Sprite Component” is not a good example of a component, as it simply creates a Mojo3D Sprite and associates it with the GameObj that can actually contain the components. However, GameObjects that don’t render to the 3D scene don’t have Mojo3D entities, and can simply use components that draw directly to the canvas, for example.

    #10313

    nerobot
    Participant
    1. GameObj name sounds not good for me, GameObject is better
    2. GameObj have a few public global stringmaps – not good, user can clear them in any program place
    3. For adding and getting components you are using Name property, I do like that in monkey-x, but mx2 allow us to do it more clean way – using reflection:

    XXX_Bridge_YYY classes is a little magic to get acces to protected field, it allow me set protected fields and provide read-only public properties to end user (I’ll write a post about that).

    My rule is – hide under the hood as more logic as possible, stay public for really needed things.

    Also in my framework I deny directly creation of components – constructor is protected. Because I need to set it protected field _gameObject in creation time. In your code user can set null to someComponent.gameObj field and get memory access violation.

    #10321

    Ethernaut
    Participant

    After thinking about this a little longer, I think I found a pretty good solution!

    • Created an Entity extension that adds methods like AddComponent, GetComponent, etc.
    • Created a “helper” class, ComponentBox, that holds the components and any useful extra functionality I want Entities to hold, like having an internal time offset.
    • ComponentBox keeps track of which box is associated with which entity, and makes sure everything runs according to plan, i.e. If a component calls Entity.Move, internally it’s actually calling _box._entity.Move, so it can act as if it belongs to the Entity.

    Here’s the (still work in progress) modified version, with examples:
    https://github.com/DoctorWhoof/game3d/tree/dev

    And here’s a sample code from the repo:

     

    but mx2 allow us to do it more clean way – using reflection

    That’s cool, thanks! I always wondered if I could do GetComponent<Class> with reflection, just like in Unity. Would it add overhead compared with getting it from a String Map? It can run on every frame on several hundreds of objects,  so I think it’s important to pick the fastest way.

    #10328

    nerobot
    Participant

    Would it add overhead compared with getting it from a String Map?

    AFAIK name of type is a minimal reflection part that directly return precompiled string.

    What is inside of Typeof I don’t know.

    It can run on every frame on several hundreds of objects,  so I think it’s important to pick the fastest way.

    Using GetComponent () inside of loops is a bad idea. You can store (cache) needed components in a private filds of objects which should use them.

     

    I dislike idea with external box container. 🙂

    #10331

    Ethernaut
    Participant

    I dislike idea with external box container.

    I totally get what you’re saying, but it solved the problem of creating duplicate structures just to hold the GameObjects, since they were the “core” objects, instead of the Mojo3D entities. I had to create their own Scene class, their own Parenting system, etc. and keep those and Mojo3D’s systems in sync. Kind of a pain.

    I think the new system works really well for the end user, since they never have to even know about the EntityBox class (I renamed it from ComponentBox, made more sense to me). This is what I was looking for, keeping Mojo3D simple but with the added functionality of components.

    Cheers!

    #10332

    nerobot
    Participant

    Ok, try it in real project to know is it good enough.

    I think the new system works really well for the end user, since they never have to even know about the EntityBox class

    This time it’s FALSE:

    • you add public method GetComponentBox:EntityBox() to Entity
    • all your virtual OnStuff methods are inside of EntityBox – maybe you didn’t done with that part yet, I’m interested in how you will override them?
Viewing 15 posts - 1 through 15 (of 27 total)

You must be logged in to reply to this topic.