bullen
|
 |
«
Posted
2017-03-25 19:10:47 » |
|
So I'm thinking about building this C++ engine, but I really don't like working in C++/C, so I'm thinking of having the core engine be C++ and then you script the game in Java very similar to Unity but with the rendering thread in C++. Has anything like this been done before. Also do you know if there are many other small open source game engines like this one out there: http://www.gameplay3d.io
|
|
|
|
DrHalfway
|
 |
«
Reply #1 - Posted
2017-03-25 20:59:26 » |
|
Use a language you are comfortable with. You won't gain any immediate advantage just because you use C/C++. There will be some hurdles and problems that you will need to solve.
|
|
|
|
Cero
|
 |
«
Reply #2 - Posted
2017-03-26 17:08:27 » |
|
Don't.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
nsigma
|
 |
«
Reply #3 - Posted
2017-03-27 10:18:24 » |
|
You won't gain any immediate advantage just because you use C/C++.
Well, you'll probably gain an immediate disadvantage!  Yes, well written C/C++ might outperform Java, but you've got to get there first - it's easy to write C/C++ that underperforms Java. And GC is probably not as much of an issue as you think it is. As for "script" in Java ... 
|
Praxis LIVE - hybrid visual IDE for (live) creative coding
|
|
|
kappa
|
 |
«
Reply #4 - Posted
2017-03-27 11:37:21 » |
|
The issue of Java's GC overhead has been around for a long time, any stuttering in game is usually automatically blamed on it (even though it might be something else). However recently there was a really interesting draft JEP for adding an option in the JVM to turn it off (i.e. allocation only GC). This could be particularly interesting option for games as it could be used to test if any lag is being caused by the GC or where your code does not produce any garbage.
|
|
|
|
princec
|
 |
«
Reply #5 - Posted
2017-03-27 12:57:37 » |
|
Well, I can halve my frame rate just by turning on G1GC... it does indeed still have noticeable irritating effects when you start really pushing things a bit. Cas 
|
|
|
|
nsigma
|
 |
«
Reply #6 - Posted
2017-03-27 13:14:53 » |
|
Well, I can halve my frame rate just by turning on G1GC...
Anyone can halve the rate of anything by turning on G1GC  Seriously, I hope they improve things a lot by the time Java 9 is out the door.
|
Praxis LIVE - hybrid visual IDE for (live) creative coding
|
|
|
bullen
|
 |
«
Reply #7 - Posted
2017-03-31 20:30:27 » |
|
Ok, so I figure I will make the rendering in C++ and only interact with it asynchronously from Java. That way I can avoid the GC pause but still hot-deploy changes directly into the running engine saving alot of development time. And I need the performance of C++ because I want to build a VR MMO. I already have the collada to OpenGL skinned mesh C++ code almost done (it works with a perfect example animation, but not with a real human made animation because there are bones that are unused and such)... So the usage would look something like: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Meadow extends Game { Animal fox; public void init() { fox = new Animal("model/fox.dae", "texture/fox.tga"); scene.add(fox); camera.distance(3f); camera.position(fox); camera.rotation(mouse.rotation()); } public void tick() { if(key.up() && fox.velocity().x == 0) { fox.velocity().x = 1; } if(!key.up() && fox.velocity().x != 0) { fox.velocity().x = 0; } } } |
And the C++ thread would just render automatically. So basically a very high level control game engine from the Java perspective. I'll see where the physics will happen, probably in Java first, then I'll move it when/if it becomes too slow. So atleast the system will use 3 cores since it will have 3 threads interacting asynchronously. Java -> Physics -> Rendering
|
|
|
|
bullen
|
 |
«
Reply #8 - Posted
2019-03-19 11:02:28 » |
|
Some progress has been made:
|
|
|
|
VaTTeRGeR
|
 |
«
Reply #9 - Posted
2019-03-19 11:32:36 » |
|
Looks good  Has it paid off performance wise? I wanna see some stress tests 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
bullen
|
 |
«
Reply #10 - Posted
2019-03-19 13:39:12 » |
|
Performance is just one reason.
More important are:
1) Portability: I realized that if you limit your Java code to the exposed C++ library; a equivalent of Unitys C#2CPP would be really trivial to make. This way you can hot-deploy code with Java during development (see 2) and then release binaries for all platforms without bloat.
2) GC and single threading: I'm still convinced that the biggest flaw in Unity is that the same thread that renders also executes the MonoBehaviours! You need an async. API between render thread and game scripting thread! I'm unsure how/if it will work but I'm going to try it in C++ first and then if it works well enough I'll add a Java server with a JNI interface for hot-deployment of game code which will allow <1 second turnaround even after the game is released with a lot of resources, at which point Unity becomes unusable.
So the point is not to avoid the GC stutter, but rather allow for a better programmer (and later content creator) workflow even after you add alot of content (code)!
Today we don't build games and then throw them away, we build games that last/are maintained/improved for decades... eventually we will build games/worlds that never die because peak Moore's law makes return on new hardware marginal!
Projects are more probable to fail because of technical debt and slow iteration times rather than obsolete technology.
|
|
|
|
h.pernpeintner
|
 |
«
Reply #11 - Posted
2019-03-20 15:11:14 » |
|
Hmmm. I'm not sure I got all arguments here. And I'm not an advocate for using jvm for games (although I'm doing it exclusively myself), but I think you can get rid of all the negative things that were mentioned here.
* GC: You can make your engine garbeless. It's hard, it's easier with C++ because you can make and reuse your own heap, but it's doable. Lack of value types is an issue, but can be avoided with object pooling and/or excessive ByteBuffer usage. * Hot reloading: There's a ton of mechanisms to load, compile, run code during runtime. Most certainly not with zero garbage, but I doubt it's toooooo important for example for a game editor. For runtime, all the assets can be compiled and packaged at build time. * Portability: I don't think there's a big difference, but with C++ you need to cross compile, so it could be a disadvantage. * Maybe totally personally biased, but weaving two platforms together is almost never a lot of fun, so staying either completely C++ or completely Java/JVM seems to be more fun and less overhead.
EDIT: I may not have the best implementation but my hobby engine (quite advanced) uses triple buffering for renderstate, where the state is mostly backed by either copyable objects or ByteBuffers... the renderer runs in its own loop completely independent, passes said ByteBuffers to OpenGL (or your favourite API) and never allocates anything. Of course only possible if you model you renderstate in a way that is mostly mutable/reusing memory.
|
|
|
|
princec
|
 |
«
Reply #12 - Posted
2019-03-20 15:40:20 » |
|
What @h.pernpeintner said. I see virtually no advantage to using C++ in games regarding performance because frankly I'm not at the level of being able to push a AAA-agenda graphics pipeline full o' graphics. At the level we're operating at, there is no noticeable difference in performance between C++ and Java but we don't half get stuff working a lot faster. GC is only an issue when you screw up in some spectacular way (haha, remember once upon a time how Java2D would create tons of contexts that had finalizers in that would eventually stop a game's main rendering loop while they got cleared...). Interfacing between C++ and Java is fraught with hassle and irritation and almost never pays off. Cas 
|
|
|
|
|
princec
|
 |
«
Reply #14 - Posted
2019-11-17 11:02:23 » |
|
Yes, but what have you actually tested there? http://www.youtube.com/v/hraOubmmBK0?version=3&hl=en_US&start=There are 16,000 bots in this scene, which is being rendered at 60fps, though obviously a couple of hundred are actually visibly rendered in the display. The terrain alone is 8 million triangles. The particles all bounce off the terrain, voxel-perfect. It's all pure Java. Unity is itself written in C++. The scripting component is generally only a trivial part of a frame's rendering time. Cas 
|
|
|
|
princec
|
 |
«
Reply #15 - Posted
2019-11-17 11:04:51 » |
|
Also, the benchmark figures they gave for Unity there are for it running on an iPhone 6!Cas 
|
|
|
|
bullen
|
 |
«
Reply #16 - Posted
2019-11-17 13:15:29 » |
|
Ah, that explains part of their bad numbers, still my engine is probably one order of magnitude better.
That Java thing does not render individually (skinnable, animated and controllable) physics enanbled entities right? A couple of hundred is not impressive at all. I can't see the movie because flash does not work on my phone.
Terrain can be one draw call, the challenge is animated skin meshes with bone matrix multiplications that need to be cache friendly and SIMD calculated.
I'm going to use (Joint Parallel) Java on the server and C+ (C syntax compiled wit gcc) on the client.
The character has 48 bones and 2500 triangles, I have inlined the bone rotations and I'm completely blow away by the performance.
I think there is a part of the bigger picture that gets lost in the bragging race. When your client uses 200-300 watt that means adoption kills the planet, PUBG with one million concurrent players uses 1/100 of the three gorges dam!
My engine can run a MMO on a raspberry pi zero at 1 watt! Thats 1 MW instead of 200-300 MW, more than two orders of magnitude.
People will learn to respect orders of magnitudes now that they will turn against us instead of working for us.
So now I'm not going to add a scripting layer, keeping it simple is first priority.
|
|
|
|
princec
|
 |
«
Reply #17 - Posted
2019-11-17 15:05:48 » |
|
https://youtu.be/hraOubmmBK0 to watch it on Youtube. With all 16,000 robots on the screen simultaneously walking about, it drops to 30fps... meh. Cas 
|
|
|
|
bullen
|
 |
«
Reply #18 - Posted
2019-11-17 15:46:32 » |
|
(only a couple of hundred visible) - are you animating the bots that are not visible?
On my animated .gif many of the 3000 are past the drawing distance but I'm still calculating the bone rotations on the CPU.
|
|
|
|
princec
|
 |
«
Reply #19 - Posted
2019-11-17 16:38:50 » |
|
Yes, the invisible ones are also animated. Point is though that the GPU is the limiting factor here, not Java: my GPU is jammed at 100% with just a couple of hundred droids, leaving the CPU with plenty of spare cycles. C++ is rarely worth the effort for the amateur game developer! Just about any other slightly higher level language will hugely increase productivity and rarely contribute a terrible decrease to subjective quality of the finished article. Cas 
|
|
|
|
bullen
|
 |
«
Reply #20 - Posted
2019-11-20 06:51:47 » |
|
How many triangles/bones does your character have?
Mine has 2500/38, I'm not choked on my GPU (1050Ti, I haven't checked, how does one even check that?) but it runs pretty hot.
Are your bots instanced? If not, they probably should be.
|
|
|
|
princec
|
 |
«
Reply #21 - Posted
2019-11-20 09:04:21 » |
|
Yes, they're instanced (the terrain of course is not which makes up the vast bulk of the rendering). Can't remember how many polys there are but they're properly optimised. I've only got a 960. Cas 
|
|
|
|
bullen
|
 |
«
Reply #22 - Posted
2019-11-20 14:04:10 » |
|
Well, then you are comparing apples and oranges.
My characters are non-instanced: so they can look different, have different animations and be controlled by a separate player in a physical world. Try to make that in Java I can promise you wont be able to run 3000 at 60 FPS.
Instanced stuff is very hard to make interesting for game play since the position is stored in textures on the GPU and interaction with CPU code is hard. It becomes a visual treat who's effects doesn't last very long, just like VR.
Though I guess we'll finally see tomorrow when Valve "unveils" (whatever that means, release in 2022?) their flagship VR title.
Disclaimer: I have DK1, DK2 and Vive; so I really really hope I'm wrong.
|
|
|
|
princec
|
 |
«
Reply #23 - Posted
2019-11-20 17:33:39 » |
|
But what part of it couldn't be done in Java exactly? I've not generally experienced vastly slower performance in Java than C++ in straightforward compute tasks. Cas 
|
|
|
|
bullen
|
 |
«
Reply #24 - Posted
2019-11-20 17:56:05 » |
|
Speed, you cannot get the matrix multiplications to perform fast enough. So you're wasting electricity and you cannot scale gameplay. Look at Zelda BotW f.ex. there is never more than 10 animated characters on screen at any single point of the game, that's because they are only pulling 5W and they are not using my Park engine! 
|
|
|
|
VaTTeRGeR
|
 |
«
Reply #25 - Posted
2019-11-20 19:21:35 » |
|
The main problem of Java IMHO is that when handling composite data you're mostly bound to using objects, which has a memory and compute overhead, i would love to have something like C-structs in Java. Just found this here, it explains the problem briefly and offers a solution: https://tehleo.github.io/junion/Didn't try it yet but it looks interesting. Why isn't there already something like this in Hotspot, shouldn't it be able to recognize when you're using an object as a stupid data container?
|
|
|
|
KaiHH
|
 |
«
Reply #26 - Posted
2019-11-20 19:30:53 » |
|
Such an optimization exists for ages and the JIT will eliminate object allocations and decompose an object into its fields whenever the object does not escape the "inline scope" which the JVM uses to optimize a method call stack and performs escape analysis with. If you have relatively tight loops, not too deep call stacks and no allocated object escapes then it is very likely that no object allocation is actually happening. JITWatch provides more insights into this. However, since this relies on the inlining and escape analysis to work it out automatically and your object not escaping, it is prone to fail in some circumstances - simply because your method size or call stack size exceeds some arbitrary limit and the JIT then just saying "nope". Project Valhalla will solve this once and for all with Value Types, requiring the programmer to hint to the JVM that he/she does not care about object identity. I do agree with @bullen, that the lack of SIMD and a few other missing CPU intrinsics is a big point in performance. Together with the arbitrary inlining thresholds in the JVM (which can be configured, though) giving you totally unpredictable runtime behaviour.
|
|
|
|
VaTTeRGeR
|
 |
«
Reply #27 - Posted
2019-11-20 19:48:13 » |
|
Such an optimization exists for ages Yes, but that is definitely not what i described, this optimization you mentioned only affects local throwaway objects but not large persistent object arrays if i understand you correctly. I'll have to wait for project Valhalla i guess.
|
|
|
|
KaiHH
|
 |
«
Reply #28 - Posted
2019-11-20 19:52:52 » |
|
Yes, but that is definitely not what i described, this optimization you mentioned only affects local throwaway objects but not large persistent object arrays if i understand you correctly. I'll have to wait for project Valhalla i guess.
Ah, yes, I see. I misunderstood you there, I guess.
|
|
|
|
princec
|
 |
«
Reply #29 - Posted
2019-11-20 22:29:27 » |
|
Valhalla is the game-changer in high-performance Java computing. It's a shame it's taking so long. Cas 
|
|
|
|
|