What to Consider When Developing a Video Game
To make a video game of your own, you'll need a fun idea for a game, which is a big hurdle...
For further actions, you may consider blocking this person and/or reporting abuse
C++ is not cross-platform very much. Different compilers frequently generate binaries that work differently. And, you have to recompile your code for different platforms, while Java has cross-platform binaries by default.
Also, manual memory control is always a negative trait of C++, not a positive one. Manual memory control fails everywhere, comparing with garbage collector.
Interesting! This space has been very opinionated online. I kept reading how memory management in C++ helps with speed and performance. I have a background in JavaScript and am beginning my learning in C++. I also plan to learn C# and Java. From what I've read about Java, the cross-platform capabilities sound so convenient. Are you familiar with Java? Do you use it regularly? If so, what do you like about it?
Java memory allocation in fact is faster than C or C++ ones. I made benchmarks recently, and I am going to write an article about that. I used Java for two years in my personal projects, but last 6 months I use Clojure (Lisp on JVM), making my game.
If you know how to benchmark properly, you can find yourself, that modern Java is faster than C and C++, or equal. JIT compiler has much more freedom and information, than traditional static compilers.
The language is cross plateform. With the same source code you can build for windows, linux ARM, x86, etc... That's the definition of cross-plateform.
Garbage collector do the job until you face out of memory or performance issues.
When dealing with large data or performance critical application, like video games, you quickly end up fighting against the GC because it trigger at the wrong time, or too late, it fragment memory, etc...
In C++, deallocation is deterministic (at least virtually, in the end the system always decide when memory is actually freed). And using smart pointer, you no more care about manual deallocation.
It seems to me you are making up problems with GC.
Modern Java, Go and many other languages GC's don't fragment memory.
If you have such terrible problems with performance, maybe it is not GC?
I am tired of appeals to majority or popularity.
Show me real benchmarks, where C++ or C show at least 20% higher performance, so it would be reasonable to pay with time and safety developing games with those languages.
Typical GC issue: I have a C# wrapping over a C++ library. This C++ handle large dataset (like dozen of GB). But because of the way wrapping is done, the C# object is just an handle keeping the C++ object alive. From garbage collector point of view, this object is just a few byte in memory, so in very low priority to be garbaged collected.
So, when I'm sure no one use this object anymore, I have to manually call gc.collect(Forced); gc.WaitForPendingFinalizers(); and all the magical gc method to be sure memory is actually free. And even by doing so, there are still magical heuristic that will prevent GC to dispose this handle.
As Joel said:
joelonsoftware.com/2002/11/11/the-...
GC is an abstraction. It works well 99% of time, but as any abstraction, it will leak in corner cases.
C# has poor GC, and now I understand why you have such opinion about GC in general. C# provides ability to interoperate C++ with CLR, also C# objects may have destructors, what makes garbage collection much more complex, even when there are no objects with a destructor in the heap.
Though, good luck using C++ for making games. Having competitors struggling with C++ is a very good thing for everyone else
I see more studios struggling to adopt Rust than to code with C++.
Yes, Rust hysteria is a real thing.
When I say that C++ is bad, I don't say Rust is better.
I used to use C++ decades ago and came back to it 2 years back with Unreal, tbf Unreal has a big ecosystem, but it does make C++ work better for me. Given how successful Unreal games are, I don't think you can dismiss C++ like it's a joke, though; a lot of significant games have a combination of blueprints and C++ developed for them.
Bare metal allocations in C++ can improve performance; they just take a lot more thinking about. I'm good with game developers not caring and using something else that deals with it for you - I do most games in Unity GameObjects so I definitely fall in that camp for many projects. Unity has introduced DOTS to combat the performance of lower-level languages and the kind of designs that work well in them.
Bare metal allocations don't improve performance. Check it for yourself, compare with garbage collected languages, such as Java. Allocations there work faster for a reason. I am going to write an article about that (with benchmarks, of course), so you are welcome to read it in future.
In reality, C++ and C are not only slower (or same) with Java, Go, Lisp, but significantly less safe, less readable and less effective (we are talking here not about system programming, but about games)
Yes I've checked it for myself, garbage collection sweeps and allocation frequencies have big impacts in hard to fathom ways. There's a reason why most game engines are written in C++ - Unity and Unreal etc.
Mister, do you have exact benchmarks? Because I do.
github.com/Taqmuraz/alloc-table
And they show, that C and C++ are slower in memory allocation, than Java 17.
Yes, there are reasons, why most game engines written on C++, yes. But speed is not a reason.
Sure, list your benchmarks and their code and I'll figure out where you got it wrong :)
You have a link. I am open for any critics. More than that, I WANT you to show me if I am wrong. Please, e-mail me, if you find something. My e-mail you may find in my profile.
Checked your c++ code and I'm confused on why you would create a pointer on one line only to delete it two lines after.
You would never see anyone do this in real code because that's no what pointers are meant for. Pointers are for resources that need to be held for long periods through different scopes and gives you the control of when to delete it.
A garbage collector which Java uses on the other hand do not give you this freedom. Instead they choose specific times to collect and delete unused resources all at once which can create visible performance degradation for demanding applications and would be a nightmare for a game.
Rather than allocating and deleting a pointer on every loop iteration, you should either allocate it all at once as a pointer to an array or just use a plain old variable, keep in mind the default c++ allocator is slow compared to other allocation methods
Edit: Additionally java requires a virtual machine which basically makes it an interpreted language. For very demanding tasks, an interpreted language will never match the speed of a compiled language like c++.
I added that
delete
call only because without that C++ test cannot complete (out of memory). Table has results without thatdelete
call.Also, benchmark is a benchmark. It is not a program that does something useful. So, I would expect critics of measuring methods and results, not style.
UPDATE:
Actually, releasing memory exactly after you used it is a good thing in C and C++, it makes next allocation faster (benchmarked as well, though it is explained in specs).
If you're going to use a resource for 3 lines of code then don't use memory on the heap, use a normal variable. It's not about coding style it's about what the feature was designed for. There's limited value in the testing scenario itself
Also you should use std::Chrono for timing because sys/time has been known to be inconsistent on different platforms
First. I am testing heap memory allocation, so I allocate memory from the heap. Period.
Second. How much inconsistent sys/time is? Do you think that use of std::chrono would change results by at least 5%?
UPDATE
I really don't get it. Test clearly show, that C malloc is slower than java new[].
All point of the C test is to measure how much time does take malloc itself.
And you are saying something about malloc use cases. Did I say anything about use cases?
lol, first of all, benchmarking memory allocation does not equal to benchmarking manual or automatic memory management, it only benchmark a part of it, so your test result does not mean manual memory management is slower than managed ones.
secondly, I wonder what would be the reason for game engines mostly written in C++ when you claim that its slower, unreadable, unsafe, and inefficient
Starting conversation from "lol" does not make you look smart.
Memory management includes allocating, accessing and releasing memory. I proved that allocating and releasing memory is slower in C and C++, than in Java. So, you want to say, accessing memory in C or C++ is somehow faster or what?
Well, I also wonder, why people choose C++ in game industry. Though, appealing for its popularity is a dubious argument. Job market state, traditions, history, people's fallacies, many factors, and you must prove that speed is one of them.
Show me that speed you are talking about in actual benchmarks.
DDR4 peak bandwidth is ~20GB/s (crucial.com/support/memory-speeds-...).
In your "Person" benchmark, you do 1 billion allocation of int value, which is 4GB. This would require 4 / 20 = 200ms assuming peak bandwidth. But your java benchmark do it in ~30ms....
I'm quite sure in you example java doesn't really allocate the memory but optimize the code.
How did you build the C++ code ? Did you use -O3 to enable optimizations ?
Yes, I did use -O3. You can build yourself C, C++ and Java sources and run.
Also, Java specification is very strict about constructor calls. If it optimizes it somehow with no loss of side effects, that is an advantage as well.
Though I want to hear your ideas about how to detect and avoid JVM optimizations, if there are ones. Also, what will you say about Common Lisp arrays allocation? It is also faster than malloc in C, but Common Lisp runtime (SBCL) seem to be honest very much with memory allocation. Also, in the C test I allocate 4 bytes int arrays, while in the Common Lisp test are 8 bytes int arrays.
malloc is a direct call to system. You just cannot be faster than that, otherwise you don't actually do an allocation. It's like saying C++ is faster than assembly because your code was evaluated as compile time (using constexpr and other optim), compare to run time evaluation in assembly.
But yes, we understood, you don't like C++.
Seems you don't know how GC allocation works. Though it really does not call system to allocate memory, it has pre-allocated heap.
Yes, so you don't measure the same thing. gc use memory pool system, but when does this allocation occured ? Did you take it in accout in your benchmark ? I don't think so. According to your code, you don't measured startup time, just the time of
new int[i];
which probaly use free slot in gc memory pool, so no allocation.I could do the same thing in C++, create a custom allocator using a memory pool, and then measure time to get a free slot in this pool. And I'm quite sure it will be faster than java.
To be honnest, you also have to take in acount JVM startup time.
Here is a list of benchmark of java VS Cpp, and cpp outperform java in any of them:
programming-language-benchmarks.ve...
Sorry, I can't continue seriously talking with you.
Please, study theory about garbage collection.
And read again, what my point was.
Bye.
UPDATE
You seriously say "If I implement garbage collector in C++ it will be faster than traditional memory allocation in C++". Bravo, you proved my point.
Dude, seriously you better have a step back and reevaluate the way you communicate and your position in general.
I read some of your comment and it's distressing.
I've worked with juniors like you, that are assertive on everything and think they know better than a whole industry. The truth is that no one want to work with people like this.
For your own good, try to listen and trust other's people opinion, especially when they have 15/20 years xp in their field. And I'm taling about real expert, not some self proclaimed senior that did the same job for the last 20 years in the same small company.
I just hope you are a troll and not like that in real life, else you might have bad time building your career.
I can't stand how arrogant you are.
But here you have a point.
It is wrong to offend people while discussing programming things.
Come back when you have better arguments, and sorry for my rude behavior.
One thing, C# is not specific to Windows... I've been coding games in C# with Unity since 2011, and I've not had a Windows computer in all that time!
This indeed is true. It is not hard to make C# projects that are built entirely on Linux, that even cross-compile to different linux targets, and build with forward compile (native) code. The nuget infrastructure works the same on Linux. And one can even produce stand-alone binaries that work well with docker, too, that target alpine musl libc, and are often no worse in size than say golang binaries.
Linux choices for cross-platform front-end ui's may be more limited, but most games are scene renders on a window anyway. C# has peculiarities, but both C++ and C# are peculiarity by design ;). I do not talk much about C# simply because nobody asks me to produce things with C#. One could talk about F#, too, as it is a great example of what a properly expressed general purpose functional language can look like.
I must have read some inaccurate information about C#. I'll update my post. Thank you for your insight!
I noticed that a lot of people make this a assumption.
C# started off as a Microsoft's attempt to replace Java on Windows, so the assumption has a bit of truth in it. But indeed, C# is a perfectly multi-platform language nowadays, has been for more than a decade.
It's also a VM-based language, just like Java. It has less focus on the "compile once, run everywhere" idea, though - understandable as that idea didn't quite work for Java either. But if you feel like it, you can even spin up a .NET VM inside a browser and write a web app in C#.
Yeah, Unity even compiles IL back into C++ for a bunch of platforms.
Unity uses c# as a scripting language. It's still using c++ under the hood for the engine.
I think the title is wrong. People do not choose C++ for game development; engine creators choose the programming language people should use with their engines.
Exactly. Games using Unreal will be largely written in C++, games in Unity will be in C#, Godot games will be in Go, and RPGMaker in JS. Most studios aren't going to be creating a game engine from scratch.
I need to change that title for sure. It was an early inspiration for writing this article, and my opinion changed while researching, but I forgot to revise the title. Thank you for giving it a read! I am new to the space, and I've been writing articles to learn more and give me a reason to research areas I wouldn't normally spend a lot of time in.
2024 and people still think C# and .NET are specific to Windows when .NET Core was released in 2016.
I agree the main idea, which C++ give a better control on computer resources and hardware.
But I find Javascript option analysis very (very) short!
The given libraries are totally out of date, whereas there are powerfull alternatives today for 3D games like Babylon.js (just by Microsoft) or Three.js!
On other hand, even if C++ has still granularity advantages, new versions of theses above libraries bring now native GPU api control through WebGL, so I think we have to consider them more a little bit.
While Babylon and Three.js are great, they are not the best for intense graphical games. One is better off using WASM for massive multiplayer and intense graphical games. When speed and memory is not a concern, Babylon and Three.js are great
I am considering JavaScript more since I have a background in that language. I am learning C++ and used this article as an opportunity to learn more about it. Due to time constraints, I had to cut my research short on JavaScript, Python, and Lua. Perhaps in a future article, I'll dive deeper into JavaScript's use in the gaming world.
I did a bunch in PlayCanvas; it was fun and performant enough for a whole slew of games. Choosing probably depends on whether you want to learn C++ or you want to make games. If the latter, I'd recommend PlayCanvas or Babylon.js - if the former then as others have said, choose your engine and the language is chosen for you.
Lol what about .NET MAUI?
Because c++ have the opp
What particularly makes me laugh about all of the banter below is that so many of you go on about which language is faster, then declare a 4 byte integer to hold a simple flag. Instead of going on about which language is milliseconds faster, try writing tighter code, more efficient code. I see this happen all the time in (supposedly) high speed, timing critical business integrations.
This is the same argument as fat guys on bicycles trying to save an ounce or two of weight on their bicycle, when they could lose pounds of their own weight and save their money.
Maybe they don't want to admit that they invested so much effort learning one or two bad languages.
Seems to be easy – install both Java and C and do honest benchmarks.
No reply to my allegation your benchmark is fake? I mean it in good spirit. It's NOT an honest benchmark what you've posted because 1) calling Win32 VirtualAlloc under the hood is eventually necessary and 2) the JVM has already done this by tike you start measuring your Java benchmark performance, whereas your C++ version does not start able to access any already-OS- allocated memory.
Things I've found to be true with Java:
Yes, you can write once and have code run on Windows, iOS and Linux operating systems (and some others as well) but the user has have Java installed.
An alternative is to compile the Java code with a built-in, customized JVM. In this case, one needs a JVM for each OS, and it can be a bit of a task setting this up for each.
I found that there are some differences in the ratio between font sizes and pixels, for Windows vs iOS/Linux systems. For this, I've resorted to creating alternate sets of constants to be used with a given OS that pertain to the size of fields.
There are a couple Game Engines that primarily use Java: JMonkeyEngine and libjdx.
Personally, I dislike pointers. I find their use makes code more difficult to read and more prone to bugs. You may not have any problem with them.
For the most part, Java is very close C++ in terms of performance speed, and to me, easier to code with Java, and it is better adapted to multithreading and functional coding. But it's been a number of years since I checked out how these aspects are handled in C++. I assume there have been improvements.
I think it's a shame that the Java game engines didn't get the level of support similar to Unity or Unreal. IDK why, but it does seem that on a number of occasions Oracle decided to ignore requests by the Java gaming community to open up some aspects of the GPU and graphics in a way that would have allowed faster rendering. There are folks that have a better understanding of the history than I do.
Deceived OOP-cultist bro still hasn't realized that the Java version isn't actually newly allocating RAM from raw Win32 VirtualAlloc calls like the C++ version is, but that the bloated, slow, unnecessary Java virtual machine has already spent time to allocate these resources. I don't even need to look at the code to conclude this, because there's no way to actually get new heap memory besides making a syscall to OS functions, which is the same whether called from machine instructions compiled with C++ or machine instructions runtime on the fly submitted by the slow, gratuitous JVM. I studying this author's writings as he is following the extreme opposite programming philosophy spirit as me - watch Mike Acton 2014 presentation for a refutation of the OOP mindset religious deception.
If I receive a reply, I anticipate a gaslighting philosophical argument about definitions of memory allocation, rather than admitting that Java isn't faster than C++. I anticipate a false argument that, "JVM is already running by the time your program starts, so all allocation is as if new". No, because I could make a C++ program that reserves a huge int array on the heap from the OS up-front at initialization, and then calls a user-supplied compiled DLL function taking a pointer to "base into array scratch memory arena", and inside the function, do the same thing you did. What the C++ DLL would be doing is exactly what your Java version is doing - not actually calling OS to reserve more memory, but returning previously allocated pages - whereas your C++ test does not allocate from a language-created hidden reserve buffer implemented as an secret abstraction in the JVM, deceiving the programmer as in this case. I am so thankful to develop software in Pascal and C, where I know for each line pretty much exactly what actual assembly code will be actually executed. As Mike Acton brilliantly and pithily emphasizes, the hardware is the platform.
This interesting