Jump to content

Crazycarpet

Members
  • Posts

    283
  • Joined

  • Last visited

Posts posted by Crazycarpet

  1. They're just not updating OpenGL drivers to support new revisions of OpenGL past a certain one... I don't remember if that is 4.2, 4.3, 4.5 or what.

    Still, I doubt many people will follow this trend and if they do at least you will still have Vulkan. Shame Apple is only planning to support Metal, MoltenVK looks cool though.

    (I hear they're planning to make design and build their own processors too... ?)

  2. The executable in your game, the exe file, is built from the C++ source code found in "My Documents/Leadwerks/Projects/<My Project>/Source/". As you know in C++ you have both header files, ".h", and cpp files, ".cpp".

    Header files are generally for declarations. (They are where you tell the compiler what functions, classes, methods you are defining, but generally do not assign them a body.)

    C++ files are where you either write "static", or local code to the cpp file.... and/or more commonly. To use these functions, classes, and methods that you declared in your header file in some C++ file you must first: (The static keyword has different implications when used in class declarations, a tutorial can explain this just don't be confused if you come across it.)

    #include "MyHeaderFile.h"

    Be careful when you're including header files in header files, as sometimes this is good practice (I'm not going to go into detail), often times it can lead to circular dependencies.

    Again, I'm not going to go into detail on this but look into forward declarations, and when they're allowed.

     

    Long story short, the next time you build your project in Visual Studio, or whatever IDE you're using, assuming you've actually used the code you've added somewhere and brought the file into source control the next time you build your program it will be compiled into the executable.

    Confused where to start? main.cpp contains the programs entry point, but Josh has projects setup so App.h/App.cpp provide you with a very straight forward entry point for your game. I would recommend looking into some C++ tutorials because at first writing it can be frustrating, but once you learn about all the tools the language provides it is one of the most powerful languages out there. :)

    Interested in communications between C++ and Lua? check out the Lua C api for tutorials on how to use the stack to communicate between languages, it can be confusing at first but I assure you it's quite simple. Shoot me a PM, or add me on Steam if you need a hand or some examples with this. I also made an interesting tool that can help you take advantage of ToLua++ to automatically expose your C++ classes, variables, and functions to Lua. Add me on Steam if you'd like help setting up this program.

    I'm sorry this post isn't very descriptive, I wanted to try to explain the process and the most common "gotchas" simply without getting into a potentially confusing discussion bout the language itself.

    Some debugging tips for those pesky linker errors.

    1. Check for any declarations in header files that lack definitions. (Visual studio's intelli-sense will underline these declarations in green.)

        - A call to an undefined function will produce a linker error, though inteli-sense is usually good at telling you exactly what is wrong in this case.

    2. Check for circular dependencies.

    3. If you're using 3rd party libraries, check if you forgot to add the "lib" file to your project's "Linker--> Input" box in "Project Settings".

    Getting an error more-or-less explaining that a symbol is already defined in <>.obj?

    - Look into include guards!

    • Like 1
    • Thanks 2
    • Upvote 1
  3. I'm too lazy to write the code, but you could do a pick downwards to see if there's 30ft of no collisions (or at least to confirm the actor isn't touching the ground), then set a variable in your character, 'falling', to true and store their current y position... In your UpdateWorld loop for this actor check if the player is 'falling', subtract the actors starting 'y' position from when they were marked as 'falling' from the current 'y' position and if that difference is 30 ft or over kill em.

    Edit:
    - You should code an IsOnGround() method for your actor, and use that to set 'falling' to false in the UpdateWorld loop if they are marked as 'faliling' but IsOnGround() is true.

  4. Nice, I guess it makes sense they both return a function, I did not ever think that they would work together. Good to know.

    If std::bind is returning a std::function<void()>, it is likely you don't need to wrap the lambda in a call to std::bind() either. Keep in mind std::bind is for class members, not lambdas.

    • Like 1
  5. On 4/8/2018 at 3:02 AM, Josh said:

    I don't think there is any way to bind a member to be set to a value, without a setter function, but that's okay. This does what I need.

    You should just use a lambda expression?

    Color4 color(255, 0, 0, 255); // I forgot what structure LE's colors are.
    AddInstruction( [this, color]() { this->color = color; } );
    
    AddInstruction( [this]() { this->positiondata->Copy(); );
    
    // Or whatever youre doing for the function....

    It might pay off to just use lambdas and std::function.

    This is the most common practice for thread "job pools".

    It is likely to be more or less the exact same, they're both not pretty to read but using a lambda and it's capture list along with std::vector<std::function<void()>> to hold these functions gives you a lot more freedom in the long run.

    It is not going to limit you any more as in the lambda you can edit public member variables without a setter function, for private members you would still need a setter but that's obvious. For bind you need a setter regardless of if the member is public/private.

    I generally do a design similar to this: https://github.com/SaschaWillems/Vulkan/blob/master/base/threadpool.hpp

    Sascha released it under the MIT license, you should use it. It is more or less exactly what you need.

  6. 8 minutes ago, Josh said:

    I guess we are more advanced than CryEngine, in addition to having more users. And since you can disable occlusion culling on a per-camera basis, you can do this too.

    Lol, CryEngine just has the right idea that if you're only going to offer one of the two, view frustum culling makes more sense. Perfect world? offer both it'd like 20 lines of code to add it.

    Quote

    This is the exact same method Unreal Engine uses:

    The difference is Unreal Engine provides view frustum culling so you get most the performance gains even with culling disabled. It is an option, not the only solution.

     

    I really hope LE users are planning to make a ghost game, or this isn't going to work for them. :o

  7. Euler angles are obtained from the Quaternion as such:

    Vector3 Quaternion::GetEulerAngles() const {
    	float yy = y * y;
    	float t0 = -2.f * (x * z + w * y);
    	t0 = t0 > 1.f ? 1.f : t0;
    	t0 = t0 < -1.f ? -1.f : t0;
    
    	return Vector3(
    		Math::ToDegrees(std::asinf(t0)),
    		Math::ToDegrees(std::atan2(2.f * (x * y - w * z), -2.f * (yy + z * z) + 1.f)),
    		Math::ToDegrees(std::atan2(2.f * (y * z - w * x), -2.f * (x * x + yy) + 1.f))
    	);
    }

    So yeah, what Josh said. If you just simply incremented pitch, yaw, roll and that was it you'd experience gimble lock.

  8. I mean, it's not in Unity, UE4, or CryEngine. it seems like a big worry. I personally am not because I don't plan on making titles I want to sell with LE, but I feel it would dissuade many people from purchasing the engine... it's kind of a big issue. There are other ways to accomplish culling, and do it very quickly.. I don't think many AAA titles would do this (Aside from Wolfenstein II which was a mess, but they somehow combated this issue likely with portals), if any for this reason. Culling is an important optimization so simply "disabling" it isn't a great option, unless you have something like view frustum culling to fall-back on, at the minimum.

    Unity uses a complex algorithm, idk how it works they don't really say... but it's not asynchronous.

    UE4 simply uses the scene depth and the bounds of an object. (so more or less, view frustum culling.) (also synchronous)

    CryEngine simply uses frustum culling.

    I'm not trying to say you should model LE after those engines, LE is unique and great in it's own right. But theres a reason no AAA engines use this method, it's because it's ugly and it doesn't work! You can't call that behavior "working".

    b16846514f96315a2db0501afb434fb5662b9267

    Why is view frustum culling not favored? I guarantee you it's faster than iterating over ever pixel, bounding boxes and the view frustum already exist... not like you're allocating memory. And sure? what if an objects behind the wall? well... luckily the vertex shader will discard it after the depth test and it will never reach the rasterizer and therefore it'll never be an issue, performance wise. Sure beats the current method in the engine.

  9. That sounds very expensive, unless the culling shader doesn't have to create new wavefronts because the compiler can accomplish branch prediction and act on many pixels simultaneously, all you're guaranteeing is that it happens in linear time (again, unless branch-prediction happened.)... either way, even if it is faster, most people are going to have to disable culling because of this ugly situation, so in practice is it really "faster" if most people can't use it because it doesn't suite their needs?

    Even if you don't change this, it'd be nice to also have view frustum culling so you could quickly cancel out candidates that don't fit within your view frustum... then if they aren't in your view frustum you don't have to worry about going further with them because you already know that they aren't visible.

  10. 0.o That's kind of ugly, culling isn't very expensive of a process... maybe it'd be worth considering doing this on the CPU, of course on the main thread, in the future. Having to disable culling all together to prevent situations like this ultimately defeats any performance gains the odd user will see , because most will have to disable it.

    You will only see slightly less performance gains from the culling done synchronously... I'd bet the CPU culling on a decent sized scene would be negligible, almost immeasurable (I guess depending on the algorithm though). You could also eliminate things by distance, etc, make sure you eliminate them from this if they're hidden... try to "eliminate" the entity from having to go through culling in the first place and you'll probably not notice a difference overall.

    If it's simply view frustum culling using a matrix, this operation would be crazy fast no matter where you do it.

    I don't know how complex your culling algorithm is, are you just doing view frustum culling? either way the process should be fairly cheap... why not do it before the renderer draws each entity?

  11. https://www.lua.org/pil/24.html

     

    See lua_register, but keep in mind you have to wrap the functions you wish to expose in plain C.... ToLua++ is your best bet.

    https://bitbucket.org/Codeblockz/toluapkggenerator2

    If you can figure out how to use my above tool, it will help you a ton! It'll auto-generate your Lua bindings for anything commented with //lua including enumerations, classes, polymorphic classes, namespaces, etc...

    Keep in mind to expose a class and it's members you have to tag the class declaration too like so:

    class MyClass //lua
    {
      void MyExposedFunc(); //lua
      int myExposedVar; //lua
      void MyUnexposedFunc();
    }

    In Lua you would then do:

    local obj = MyClass()
    obj:MyExposedFunc()
    print(obj.myExposedVar)

    You do not have to tag namespaces with //lua however. I also wrote a C++ version of this I'm not planning on releasing publicly but if you need it I may be able to share it if you don't give it out.

    Also note that with namespaces the access is different like:

    namespace MyNamespace {
        void MyFunc(); //lua
    }

    Lua:

    MyNamespace.MyFunc()

    Note the '.' instead of ':' as namespaces are simply tables, where as classes are metatables.

  12. Gross, please don't go procedural. I would use plain C 100 pct of the time rather than C++ if I didn't want OOP.... If a user has problems grasping the concept of OOP they should spend some time learning the tools that each programming language provides before moving onto game development.... If you can't grasp the concept of OOP, you will never be able to make a game.. Simple as that.

    The concept of polymorphism is fairly simple, it is taught to first year computing students @ any university in North America and these classes are absolute jokes most students take to avoid having to take calculus. It would be a shame to see LE move away from object oriented programming.

    Not to mention Blitz isn't a great example to follow, considering it is not a very popular programming language to start with. It certainly isn't known for it's "smart" design choices.

    • Like 1
  13. Making an actual hole in the terrain would be getting pretty complicated. (if possible at all in Leadwerks.)

    However if you simply want to hide the terrain while you're in a "hole" you could simply have another World and use World::SetCurrent to switch to a terrain-less world.

    There was a thread a while back where people discussed the issues of trying to hide terrain via code, one issue being that if you disable collision on the terrain, all the entities in the world are going to fall! the other being that LE's renderer seems to forcefully draw the terrain regardless of whether or not it's hidden... now there are definitely ways to force it to not be rendered, but the world method is probably your best bet.

    • Upvote 1
  14. 14 hours ago, Einlander said:

    You simply send the key input and mouse input  to the server as you were thinking. The server does the setinput, gets the new location of the player and sends it to the client.

    That's not quite as simple as it is as this would cause a huge rubber banding effect due to the latency... this is where concepts such as client prediction, and server reconciliation come in. Essentially you make the client simulate his own movement as usual, and while the client receives movement "results" from the server (i.e: the end-position the server got after simulating the movement) you'd interpolate the client towards the servers result.

    Valve has some awesome write-ups on how they handle reconciliation/prediction and interpolation I suggest giving them a read!

    Another great article is http://www.gabrielgambetta.com/client-server-game-architecture.html

    20 hours ago, St0nedas said:

    Firstly, I'd like to point out the fact that I like how LE uses a simple "do it yourself" messaging system, as oppose to having that extra layer on top that does the job for you. Not only the more you do yourself the more you learn, but the control over it so much better if your trying to create something like an information bubble.

    I'm going to have to disagree with you there, I think you'd find you have much more freedom using raw ENet and writing your own high level functions over it as lots of the necessary things you'll need are hidden behind tons of abstractions in the Leadwerks networking library (which is really just ENet hidden behind simple abstractions). ENet is well documented... the Leadwerks abstractions are not, you're going to have a hell of a time figuring things out.

    IMO, most the features in Leadwerks were made with love & care, and well though-out... Networking in LE seems like it was mashed together over night with minimal thought put into it. :P

    20 hours ago, St0nedas said:

    Then you also have vehicle physics. I don't have a lot of experience with LE yet, so I'll also put forward this question - does the physics engine have any randomisation in it? Or, if I crashed one vehicle into another, at the exact same spot, same angle, exact same force, will it result in the exact same physical reaction each time? This knowledge would also help fill the gap.

    Newton Dynamics is a quite physically accurate physics engine (as far as physics engines go) they rarely use made-up numbers, every number in their physics equations are there for a reason and originated from something "real".

    However, like every other physics engine... Newton is non-deterministic... different FPUs handle the floating point numbers differently and can store them with different internal representations, leading to slightly off results. You can not rely on the fact that the outcome of this "crash" will be identical... however if the parameters that lead to the crash are as identical as they can be you can except a quite similar result which is where client prediction/reconciliation comes in. You know the result the client produces will be both smooth, and close to correct... so the reconciliation won't be very noticeable.

     

    Honestly, these topics can range from very simple to extremely advanced depending on if you care about cheaters (if not, just spam unreliable messages updating the clients position w/ the position they say they're at!)... Only advice I can give is start simple and then read articles like the ones from Valve, and the one I linked above and try your best to come up with a nice solution to keep entities in the world in sync without getting visible banding from the latency!

    I personally haven't been able to get smooth client prediction results with Leadwerks for some reason... most likely because I never understood how SetInputs worked correctly and gave up before learning more about the LE character controller. However I did come close! I think as of right now everyone is just using a unreliable channel to receive the position of players/vehicles from the client... and trusting that result. (This is dangerous however, because a client could make a teleport "hack" by sending a fake position to the server.)

    The reason people tend not to go in depth about these topics is because there's no "global solution" that'll work nicely for everyone... you have to decide what kind of game you want to make, and come up with a solution that's best for you!

  15. 11 minutes ago, jen said:

    That's stupidly complicated for a "simple and robust network communication layer". I have a perfectly working network system using a different library and I have no further interest in ENet, so I won't comment any further I'll leave it to you guys to sort your problem out.

    It's not really complicated... that's just kind of the point I was making, it's easy if you READ the enet documentation.. it's hard when it's hidden behind Leadwerks abstractions and undocumented...

    No flags = Unreliable, sequenced.

    Unsequenced flag = Unreliable, unsequenced.

    Reliable flag = Reliable, sequenced.
    The documentation makes it very clear.

    ENet is EXACTLY what it says it is, a low-level networking API... if you want to build a networking API into the engine it should be a higher-level design.

    • Upvote 1
×
×
  • Create New...