Jump to content
  • Advertisement

hyyou

Member
  • Content Count

    59
  • Joined

  • Last visited

Posts posted by hyyou


  1. On 5/29/2019 at 3:36 PM, NeoBrea said:

    we primarily use Substance Painter

    Thank, NeoBrea.  I just watched some VDO ; Substance Paint is so cool.  Now, I has more options, yea. 

    Look like drawing texture in Photoshop is wrong to begin with, but every approach has its own downfall.

    I just need to select the least painful way.  😁


  2. Thank a lot, lawnjelly and Rutin.

    Ptex is interesting!  Thank for the Disney link.  I just notice there is Ptex tool in Maya.

    On 5/12/2019 at 7:37 PM, lawnjelly said:

    ... I know true artists have a greater tendency to faff and can never commit to a final version. ...

    It is exactly what I am afraid of.

    On 5/12/2019 at 8:09 PM, Rutin said:

    Just don't put yourself in this scenario to begin with. Plan better. 

    That is too hard for me.  I am a programmer - I love to refactor things too often. :D 

    I will try to use procedural texture more.


  3. If a 3D shape (e.g. in Maya/Blender) is edited (e.g. extrude), the underlying UV often should be edited as well.

    The UV editing is useful - to make a triangle occupy enough texture pixel, and make texturing artist work easier.

    However, it is a tedious and very repetitive process.   

    Fortunately, Maya can automatically update UV and the underlying texture.

    (^ reference : https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2018/ENU/Maya-Modeling/files/GUID-6AB281B4-1653-4CC5-B4D4-A87516261F2E-htm.html  )

    But, what if the texture is created by Photoshop? 

    I don't think Maya will automatically hack into my ".psd" file.  Thus, my original Photoshop file will be deprecated/obsoleted.

    Question: 

    • What is your workflow when editing a shape? 
    • As an artist, do you feel tedious that UV and/or underlying image have to be edited as well? 
    • How do you solve it?

    I am new to 3D modeling.


  4. 10 hours ago, ahmadierfan99 said:

    2. How did you budget your "subsystem's updates"?

    If you code it yourself, the value is easy to guess.     

    For example, if physics engine's update usually takes 2-3 ms in current version of my software, it is reasonable to create an assert fail / warning if it will start to takes 6 ms in future versions.     

    Another example : In my situation, it is reasonable to put that a graphic engine should take no more than 40% of overall game.    

    Drastically (but not unfortunately), it is an art.  I may want to be on a safe-side for an expensive system and put a low threshold number that will warn fast, or I may feel lucky and use a CPU% number = twice of the version that everything looks perfectly fine.   The numbers can also be changed later.

    My values are based on feeling, approximation, experiment and experience .... like ingredient ratio I used when cook food.

    Taste it ... ahh, I mean test it and you will find a figure that you are satisfied with ... I start to be hungry.  

     


  5. I have a game loop in Entity-Component-System architecture (heavily simplified) :-

    spawn some enemy Turret, only in some timesteps;
    every Turret : try to shoot -> create new Bullet();
    every Bullet : destroy itself if lifeTime = 0;
    every Turret : destroy itself if hp = 0;
    entity_component_system->cleanUpAsNeed();

    It works, but to make it complete, I am supposed to delete entity at the last time step myself.

    Thus, I add many condition involving ☁lastFrame☁ :-

    if(!☁lastFrame☁ ) spawn some enemy Turret, only in some timesteps;
    if(!☁lastFrame☁) every Turret : try to shoot -> create new Bullet();
    every Bullet : destroy itself if (lifeTime = 0 || ☁lastFrame☁);
    every Turret : destroy itself if (hp = 0 || ☁lastFrame☁);
    entity_component_system->cleanUpAsNeed();

    It works but it is very dirty and error-prone.

    I imagine that this will also happen when room/scene changes.

    How to solve it elegantly?

    • How do good games solve this problem typically?
    • Are there any related "design pattern" I should read?
    • Is it already OK, i.e. am I too nervous?

    Some days, I had nightmare because of it .... 

    ... a nightmare that my code become ☁lastFrame☁-flavor spaghetti.

     


  6. Thank.  

    As a follow-up question, assume a below situation :-

    • Mr.B1,B2,B3,..., and Mr.B1000 signs contract to use a game engine from Mr.C.
    • In the contract, Mr.C get 10% of revenue of every game that Mr.Bx developed using the game engine. 
    • Mr.C send header files and .lib to every Mr.B via email.
    • Some Bs successfully deployed the game and paid C, but some Bs abandoned and used other engines instead.
    • However, B1 is different from other Bs.
    • Using C's game engine, B1 has developed a game without any collaborator.
    • (^ Thus evidence is very hard to find.)
    • After finishing the game, Mr.B1 wanted to cheat. 
    • Mr.B1 obfuscated C's header and .lib, and sell a game using the engine without paying C.
    • Furthermore, Mr.B1 accidentally leaked C's obfuscated game engine in the internet. 
    • A random Mr.D found the copy. 
    • Mr.D knew that it is actually C's, but decided to use it.  It is free.

    How can C detect such case?   It is practically impossible to detect, right? 

    Reason :-

    • C can't access to source of every game in the market, including B1's game and D's game.
    • Suppose that C can, there are a lot of game sold every day!
    • If C's engine is also open-sourced (not free; it is like some contract of Unity/Unreal; easier to obfuscate), possibility to detect is almost zero.  Correct?

  7. Questions :-

    • To sell a C++ game library/framework/engine, does it usually have to be open-sourced? 
    • For a C++ template class (real template), it is quite hard not to be open-sourced, correct?
    • If it is open-sourced, how to protect the copyright?
    • How to enforce people to just use it, but not copy?
    • ... I think it is practically very hard, because people can see the source code, and "rewrite" it.
    • Does a shop like Unity's asset store make thing safer?  If so, how?

    Arrogant assumption :-

    • The game library/framework/engine is high-quality, well-documented, and it would be marvellously sell well.
    • Besides some free libraries like Bullet and Ogre, it is developed all by myself.
    • The library/framework/engine is not bound to any legal obligation (e.g. the most restriction is MIT).

    I have these questions after reading a news  :-

    • Muhagames develop a game named Thea Awakening (C#).
    • The company use its own Honey Hex Framework (C#) as a library to develop the game.
    • The company sell Honey Hex Framework via Unity's asset store to boost its financial position.

    There are also others old examples e.g. Unity itself or Unreal, which is now open-source ... How do they protect it?

    Actually, I don't plan to sell any library. I am just curious.


  8. I am trying to encapsulate a Physics Engine (to support fracturing).

    I want to know whether my below semantic is bad smell.

    [Approach 1] My current design is :-

    • Programmer can create 2 types of Physics body  : Parent, and Child
    • Parent is a body that can't have any shape or mass, but can contain some Parents or Children.
    • Child is a body that can't contain any other physic body, it always has shape and mass.

    For the implementation :-

    image.png.00ac54151646247dd3c9754e97f02128.png

    • Both Parent and Child are inherite d from a class PhysicBody.
    • PhysicBody has some fields.  One of them is mass, as an example.
    • Mass of a Parent is the total mass of every children.
    • Mass of a Child is the mass of itself.

    Suppose that I want to simulate a jar that can explode into several pieces. I will :-

    • Create a Parent named x
    • Create many Child that denote fractures e.g. y1 y2 y3.
    • x.add(y1);   x.add(y2);   x.add(y3);
    • The steps are very similar to BulletPhysics's.

    So far, it works well in all demos.    Coding is easy and fun.  

    Today, I want to implement a tank like this :-

    image.png.80748d14049ce4b3a61cf4d61fa650cc.png (a crappy tank shown in top-view)

    Here is how it can be created :-

    • x is a Child : x = createCube();
    • y is a Child : y = createSphere(); 
    • z is a Child : z = createCylinder();
    • p is a Parent : p.add(x);   p.add(y);   p.add(z);

    It works, but I think it is counter-intuitive :-

    • The tank is p which is an relatively (too) abstract physic body.

    [Approach 2] Thus, I plan to make it like :-

    • x = createCube()
    • y = createSphere();  x.add(y);
    • z = createCylinder(); z.add(y);

    The new sematic demand me to re-design Physics class, e.g. to be :-

    image.png.3949b206e4fabd8422693cc0e002a906.png

    Old parent and child will become the same type - all of them can now has shape, mass and contain children!

    image.png.dc784bc081a2eaa68405395e22dfc315.png

    I think it would work well, but I am still too scared.

    Question

    • Is it make sense to allow non-empty physic body to contain some other physic bodies?
    • Are Approach 1 and Approach 2 bad designs? 
    • Can Approach 2 be considered an improvement?
    • Did you spot something (potentially) wrong?  How to improve it?
    • Am I a problem myself?

     


  9. I mean ... Do you want a thing like this :-  ?

    box2djs.png

    If so, use an external physic engine (e.g. Box2D) would probably be more suitable.

    If you just want a thing like :- 

    minigame.png

    It is not so hard to write physic engine yourself.  (But I will still use Box2D for this case.)

    Just a random concern : AABB is not the hardest part of a general-purpose Physics engine.

    On 10/16/2017 at 6:07 PM, Angelic Ice said:

    By transformation-matrix I rather meant a way to transform my 3d cubes to the 2d images, I read about isometric projection and will probably use that.

    There are a lot of different way to do it. 

    It depends on format of your 3D transform and 2D transform ... and your taste.  :)

    First, let try your approach.    It is not hard.   You probably don't need any transform matrix to do that.  

    If you face any specific difficulty about it, feel free to ask more.

     


  10. It doesn't sound bad.    Ray-cast is not so hard to code either - I believe it is a correct approach..

    Is it your own game engine, and what is the physics engine that you selected? 

    Will you implement the Physics yourself?  .... Beware that if you happen to need proper collision response (bouncing cube , not snap to grid), it can take a lot of time and there are a lot of problems on the ways.

    On 10/14/2017 at 3:52 AM, Angelic Ice said:

    what transformation-matrix should be used for this case?

    I am not sure what you mean.   Is 4x4 matrix OK for you?


  11. Thank you everyone for many useful advises. xDxD

    On 10/2/2017 at 5:29 PM, Bregma said:

    Short answer to your original question: if it works and lets you finish the game, it's an acceptable design.

    Thank.  It is my "default" mindset.  xD

    On 10/2/2017 at 5:42 PM, Hodgman said:

    struct Rocket { Ptr<RigidBody> physics;... };

    I had implemented like this.  It is very easy to understand and debug.

    However, in some rare cases (10% for me), the deletion is required to be delayed.   

    For Bullet physics engine, it is the best to invoke collision callback in a batch manner.  

    - update game logic
    --- MARK delete a rocket
    - propagate the MARK to physic object
    - update physic
    --- collision callback 
       -> discover that the manifold between ...
           ... physic object p1-vs-p2 is no longer exist
       -> invoke Physic::collisionEnd(p1->userData,p2->userData)
    - delete every thing that was MARK-ed

    I believe that the correct approach is to delay to deletion of everything.  Otherwise, the p1 can be a dangling pointer.  It is also very handy to know for sure that p1->userData (which is Rocket instance) is not a dangling pointer.

    Thus, I adopt the "delay deletion" practice into everything.

    An alternative simpler approach is to let a system that handle rocket 1.broadcast and 2.invoke object deletion manually (like your example), but  I prefer a more automatic way.

    I am not sure how game engine should support ownership relation that need the delay. I may think too much. 

    14 hours ago, Zipster said:

    On the other hand, what's stopping two entities from having a third shared entity in both of their 'ownees' vectors, i.e. shared ownership?   ... ... What ownership semantics do you want?

    The question makes me reconsider about many things.  Thank.

    I am using semantic like this.  It has run-time assertion.  I am OK about it, but not sure if it is good :-

    relation_ownership->add(rocket, physicTriangle);
    relation_ownership->add(rocket, graphicWing);
    relation_ownership->add(rocket, barrier);
    relation_ownership->add(barrier, graphicLightSphere);

    I try to avoid share_pointer, because it is quite notorious - hard to debug / circle reference / slow.   I also don't need it because I know the clear ownership.

     

     


  12. 38 minutes ago, 0r0d said:

    Unless there's more complexity than what you're describing, I'm not sure why you dont just use smart pointers and let those deal with your object lifetime management (std::shared_ptr, std::weak_ptr).  It would be easier and less bug-prone than what you're doing now.

    Also, what's the point of having a component that has to be in every single entity?  Why not just put that functionality into the entity?

    Thank 0r0d.   I agree std::shared_ptr and std::weak_ptr are less error-prone.

    I didn't push the functionality to the entity because I am still too scared by this idea.

    There are a few cases that delete-flagging is more useful.

    First Reason : safer callback

    Suppose that :-

    • A rocket E1 owns a physic body E2.
    • The physic body E2 owns a Bullet physic internal entity E3.

    In a std::unique_ptr-style : a user delete a rocket -> E1 E2 and E3 will be deleted immediately (in reverse order).  

    After E3 is deleted, the Bullet physic engine will still has a dangling pointer to the physic body (btRigidBody).   It is quite hard to workaround this issue.  Collision callback (collision-end) will be a mess.

    2nd Reason : more multi-threading friendly

    By using flag, every entity is ensured to exist until the end of time-step.   Component iterator is easier to implement and require less mutex lock.

    For me, such assumption make various parts of gameplay easier to code.

    3rd Reason : cache friendly (not sure)

    With flagging, deleting is executed as batch.

     


  13. In my Entity-Component-System, every entity has Com_OwnerShip component.

    Com_OwnerShip = can own [0,∞) entity / can be owned by [0,1] entity

    For example :-

    • a rocket OWN 1 physic object  + 3 graphic object
    • a rope OWN 10 physic object  + 10 graphic object
    • a physic object OWN 1 Bullet(R) physic internal object
    • a game chunk OWN 16*16*16 blocks

    Here is a way to implement it (can be optimized further):-

    class Com_OwnerShip{
        std::vector<Com_OwnerShip*> ownees;
        Com_OwnerShip* owners;
    };

    At the end of every time step, I list every owner that was marked as to be destroyed, then mark all corresponding ownee entities as to be destroyed.   The process is propagative.     Then, I delete all "to be destroyed" entity in a batch-style.

    I have used it in a few prototypes and always find that it is very convenient.

    However, I feel that it is probably a bad practice. 

    • It probably share the disadvantage of Base_Game_object in OOP. (?)
    • It costs a little more memory, not modular, too wildcard, too "duck-typing".
    • It is a dirty-design (?).
    • Nonetheless, it is better than Strong-Pointer (std::unique_ptr) because I can control entity/component deletion very easily.

    Is it a good practice?     What are alternative approaches?   Am I too nervous?

     


  14. 15 hours ago, Juliean said:

    ... but instead implemented those systems separately

    Thank Julien. 

    In a more real case, I structure it like this :-

    rocket = HP + physic_owner + graphic_owner + ....
    Physic body = physic_ownee + bulletBodyAndShape_holder 
             + cache_physicAttr(pos,v,gravity,mass,mask) + ...
    Graphic body = graphic_ownee 
             + ogreBody_holder (Ogre2.1 graphic body)
             + cache_renderAttribute(pos,blend_mode,layer) 
             + mesh_owner
    mesh = mesh_ownee + filename 
            + ogreMeshPtr(point to vertex buffer)

    The physic_owner / graphic_owner / physic_ownee / graphic_ownee  are just attach-point.  

    If I want to create a rocket, I tend to create 1 rocket entity attach to 2-3 new physic body, 2-3 new graphic body.     The graphic body attach to a shared mesh.   Thus, for a single rocket, I create around 5-7 entities.

    I copied the idea from https://gamedev.stackexchange.com/questions/31888/in-an-entity-component-system-engine-how-do-i-deal-with-groups-of-dependent-ent , not sure if it smells. ...  

    For me, it works pretty good, but I may overlook something.

    P.S. Your comment in another topic of mine boosted my engine's overall performance by 5%. Thank a lot.

    7 hours ago, Zipster said:

    Don't think of data as a "point of communication"

    That is enlightening, thank.

    @0r0d  You are right. I have edited the post :)


  15. I encapsulated Physics and Graphics with ECS successfully.

    Here is a simplified version :-

    Physics Rigid Body = Physic_MassAndInertia + Physic_Transform + Physic_Shape
    Graphic Polygon Body = Graphic_Transform + Graphic_Mesh

    I usually set their transform via :-

    findService<Service_PhysicTransform>()->setPosition(physicEntity,somePos);
    findService<Service_GraphicTransform>()->setPosition(graphicEntity,somePos);

    It works so nice, and there is no problem in practice, because I always know its "type" (physic/graphic).  

    However, I notice that Physic_Transform and Graphic_Transfrom are very similar and duplicate.

    For the sake of good practice and maintainability, I consider to group them into Generic_Transform.

    findService<Service_Transform>()->setPosition(anyEntity,somePos);  //cool

    However, there is a little difficulty.  The physic transformation is quite complex for a child inside a compound body.

    Assume that a physic body B is a child of a compound body C.   In this case, B's transformation component currently has no meaning (by design).

    If I want to set the child transformation setTransformation(B,(x,y,45deg)), my current physic engine will not set the B's transformation directly - it will set C's transformation that make B's position match (x,y,45deg).

    image.png.8d081eca5b014314aee226fc7564697d.png

    Thus, it is not so practical to group them, except I code it like (ugly and worse performance):-

    class Service_Transform{
        public: void setPosition(Entity B,Vec2 pos){
            bool checkIsPhysic = .... //check if B is physic
            if(checkIsPhysic){//physic
                Entity compound = .... //find C
                ComponentPtr<Transform> cCompound = compound.get<Transform>();
                cCompound->pos=pos*someValue; //calculate some transformation for C
            }else{//graphic
                ComponentPtr<Transform> cTransform=B.get<Transform>();
                cTransform->pos=pos;
            }
        }
    }

    Should I group them  into 1 type of component?  

    I probably should not group them because its meaning and related implementation are very different, but I feel guilty ... I may miss something.

    Advice about other things are also appreciated.  Thanks.

    Edit: Hmm... I start to think that grouping component is OK, but I should still use 2 function (from different service/system).

    Edit2: fix some code (pointed out by 0r0d, thank)

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!