digitalmars.D - Writing game engine in C++, considering switching to D
- Will Cassella (61/61) Feb 18 2015 Hi,
- ketmar (23/25) Feb 18 2015 do you really expecting the answer "no, stay with C++" in newsgroup that...
- Iain Buclaw via Digitalmars-d (5/7) Feb 18 2015 GDC and LDC are able to produce any code. It's the runtime that may
- ketmar (2/9) Feb 18 2015 ARM is at least tested... well, for some extent. ;-)=
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (7/12) Feb 18 2015 Actually, you can have both. Apparently the Windows installer for
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (8/14) Feb 18 2015 Maybe you should consider creating D-bindings for your C++ engine
- Will Cassella (4/4) Feb 18 2015 Thanks for the replies, everyone!
- Manu via Digitalmars-d (11/15) Feb 18 2015 I've used D alongside C++ code in games for a few years,
- francesco.cattoglio (18/22) Feb 20 2015 My 2 cents would be: start with a toy project that stresses a bit
- John Colvin (4/6) Feb 20 2015 Really? I don't see this in my projects. The GC stops the world,
- ponce (5/11) Feb 20 2015 Not a race.
- francesco.cattoglio (8/20) Feb 20 2015 Exactly. Unless you do some special work yourself, you can't call
- John Colvin (7/19) Feb 20 2015 Hmm, yeah you're right. That would explain some of my weirder
- ponce (13/17) Feb 20 2015 I'm sorry but there is two problems with your solution:
- ponce (2/4) Feb 20 2015 s/with/wish
- ketmar (4/28) Feb 20 2015 the funny thing is that destructor can be called while another thread is...
- John Colvin (4/23) Feb 21 2015 The OS X documentation makes it seem possible:
Hi, I have been working on a neat little game engine in C++ for the past year or so, and while C++ has served me well in the past, there are some points where its just awful to write. While I certainly can't call myself a master of C++, there's very little about the language that I am not familiar with, and I'd like to try something new. Since I am writing this engine just for fun and experience and C++ game engines have been done to death, a D game engine would make for an interesting project as well as providing great experience with system/application oriented programming. One of the main differences it seems between D and C++ is that the D compiler actually tries to be your friend by avoiding all the header/preprocessor/forward-declaration madness. I actually don't mind the syntax of C++ for the most part, but there are some cases where it just wants to make you tear your eyes out so you don't have to look at it anymore (ie, the '.template MemberName<T>()' syntax for calling dependant member functions on templated variables. I understand why its necessary, but its still ugly as hell. I also think that forward-declarations are hideous devil-spawn and have no reason to exist in 2015). I like that D has a garbage collector, because while I intend to utilize RAII heavily in lower-level portions of code, having a native garbage collector to handle higher-level aspects (ie gameplay) would be extremely helpful. That's not to say I don't have concerns about switching to D, and so I'm outlining them below: Pros: - Prettier code (this is actually a very big plus for me, I'm almost OCD about the cleanliness of my code) - Modules: Less frustration with the compiler, faster compile times - Larger standard library. I hate it when C++ people complain about "non-utility" features for the standard library. You don't it. - Garbage collection. Garbage collection allows you to focus on algorithms, not management, so I don't understand why some people are so vehemntly opposed to it. Cons (I'm not very experienced with D so these may be inaccurate): - Not as easy to get up and running (I haven't gotten DMD to work with VisualD yet, even though they both appear to be set up correctly. There may be an easy fix, but it doesn't exactly inspire confidence). PHP may be an awful language, but you can't deny that its incredibly easy to get up and running on a web server - and there's a lot of appeal to that. - DLLs. C++ DLLs/SOs are pretty simple for the most part, and don't require your code to really know that it's being referenced through a DLL. I really don't want to have to write dllmain and .def files for my DLLs. - Portability (?) While I'm not currently targeting more exotic platforms like PS4 or XBone or Android or the iPhone or even asm.js, I would like to keep those options open. I don't know how portable D is towards more gated platforms like those, so if anyone can clarify on this I'd appreciate it. - Library support. This may become a non-issue, as Ds support of C libraries seems pretty solid, and it sounds like further support for C++ is coming. Anyway, if anyone here can give me advice on whether I should transition or not, I'd appreciate it. Thanks!
Feb 18 2015
On Wed, 18 Feb 2015 20:29:33 +0000, Will Cassella wrote:Anyway, if anyone here can give me advice on whether I should transition or not, I'd appreciate it.do you really expecting the answer "no, stay with C++" in newsgroup that=20 is dedicated to D language? ;-) as for some of your answer... using DMD from command line is dead easy=20 both on GNU/Linux and on windows. you may miss visual studio integration=20 and debugging, though. me not. ;-) GNU/Linux (and FreeBSD) .so support seems to work good, we can even use=20 libphobos as shared library. it's still not possible to use libphobos as=20 separate DLL on windows, AFAIK. yet you can write self-contained DLLs;=20 alas, they will not share GC (so you can't transfer dynamically allocated=20 heap object from one DLL to another). GDC compiler is able to produce ARM code (and maybe LDC too, i don't=20 know), and i don't know about druntime porting status. yet there is some=20 work done, and i believe that we will have more of that. i don't think=20 that DMD will support ARMs in nearest future, as it requires completely=20 new codegen for that. so if you aiming at portability, you'd better test=20 your code with LDC/GDC (which usually one version behind the current DMD). as for the answer... writing such thing in D will be fun. and many things=20 may change in the future (full support for windows DLLs, better ARM/ android support, ownership and better controlled memory management,=20 etc.). i think that D is at least worth trying. you can always fallback=20 to "better C++" mode and write the missing parts yourself (and this will=20 be fun too).=
Feb 18 2015
On 18 February 2015 at 20:48, ketmar via Digitalmars-d <digitalmars-d puremagic.com> wrote:GDC compiler is able to produce ARM code (and maybe LDC too, i don't know),GDC and LDC are able to produce any code. It's the runtime that may just need extra porting love. :) Iain.
Feb 18 2015
On Wed, 18 Feb 2015 21:24:42 +0000, Iain Buclaw via Digitalmars-d wrote:On 18 February 2015 at 20:48, ketmar via Digitalmars-d <digitalmars-d puremagic.com> wrote:ARM is at least tested... well, for some extent. ;-)=GDC compiler is able to produce ARM code (and maybe LDC too, i don't know),=20 GDC and LDC are able to produce any code. It's the runtime that may just need extra porting love. :)
Feb 18 2015
On Wednesday, 18 February 2015 at 20:48:07 UTC, ketmar wrote:as for some of your answer... using DMD from command line is dead easy both on GNU/Linux and on windows. you may miss visual studio integration and debugging, though.Actually, you can have both. Apparently the Windows installer for DMD installs VisualD and during a segfault in a raytracer, I noticed it asked me if I wanted to debug. I had no idea what it would do, and I was rather annoyed when Visual Studio started up, but it pointed me to the line that failed. And I was just using command line dmd... I was very impressed. ~.~
Feb 18 2015
On Wednesday, 18 February 2015 at 20:29:34 UTC, Will Cassella wrote:Hi, I have been working on a neat little game engine in C++ for the past year or so, and while C++ has served me well in the past, there are some points where its just awful to write.Maybe you should consider creating D-bindings for your C++ engine and write a small game for it in D before you start porting?Anyway, if anyone here can give me advice on whether I should transition or not, I'd appreciate it.If your goal is to have fun I suggest you write something in D rather than port existing code. Otherwise you most likely will end up with "why is this hard in D" rather than "this is much more fun in D".
Feb 18 2015
Thanks for the replies, everyone! I think I'll try my hand at writing bindings for my existing game engine, as Grøstad suggested - that way I can gradually transition the codebase to D if I like what I see.
Feb 18 2015
On 19 February 2015 at 12:08, Will Cassella via Digitalmars-d <digitalmars-d puremagic.com> wrote:Thanks for the replies, everyone! I think I'll try my hand at writing bindings for my existing game engine, as Grøstad suggested - that way I can gradually transition the codebase to D if I like what I see.I've used D alongside C++ code in games for a few years, professionally, and in my own toy projects, including on the console platforms you expressed a concern for. You might want to take a look at my engine + bindings: https://github.com/TurkeyMan/fuji/tree/master/dist/include/d2/fuji You can do some cool stuff in D that is impossible in C++. vertex.d for instance demonstrates some interesting opportunities to make the bindings far nicer in D, even though it's just a front-end for a C++ engine.
Feb 18 2015
On Thursday, 19 February 2015 at 02:08:39 UTC, Will Cassella wrote:Thanks for the replies, everyone! I think I'll try my hand at writing bindings for my existing game engine, as Grøstad suggested - that way I can gradually transition the codebase to D if I like what I see.My 2 cents would be: start with a toy project that stresses a bit resource management (the toy project might as well be the rendering part of your existing engine). The only part of D I really don't like is non-deterministic resource destruction, because it can be really painful when it comes to stuff like OpenGL resources (e.g: if the GC calls any OpenGL function, you get a "nice" crash since OpenGL is not multithread-aware by default). IMO the first thing you should do, is trying to see if you are able to manage all your critical resources (including OpenGL objects) by using D structs coupled with Unique! and RefCounted! templates you can find in std.typecons module. I highly suggest you to do that, because that is the worst hurdle I had to face during any kind of D + OpenGL development. If you understand how to get stuff done right, you are set, and the rest of the work will be painless and fun.
Feb 20 2015
On Friday, 20 February 2015 at 09:57:48 UTC, francesco.cattoglio wrote:(e.g: if the GC calls any OpenGL function, you get a "nice" crash since OpenGL is not multithread-aware by default).Really? I don't see this in my projects. The GC stops the world, so there shouldn't be any races.
Feb 20 2015
On Friday, 20 February 2015 at 13:04:51 UTC, John Colvin wrote:On Friday, 20 February 2015 at 09:57:48 UTC, francesco.cattoglio wrote:Not a race. An OpenGL contect can only active in one thread at once. If the GC calls a destructor from a thread which doesn't have that context active, it will probably crash.(e.g: if the GC calls any OpenGL function, you get a "nice" crash since OpenGL is not multithread-aware by default).Really? I don't see this in my projects. The GC stops the world, so there shouldn't be any races.
Feb 20 2015
On Friday, 20 February 2015 at 13:44:04 UTC, ponce wrote:On Friday, 20 February 2015 at 13:04:51 UTC, John Colvin wrote:Exactly. Unless you do some special work yourself, you can't call OpenGL function from a different thread. It's not a real D problem, in fact, D is probably doing the right thing when it comes to Thread Local Storage and such. It is more of an OpenGL limitation. This is also the reason I can't wait to see OpenGL Next, since there were also promises of "far better multithread support".On Friday, 20 February 2015 at 09:57:48 UTC, francesco.cattoglio wrote:Not a race. An OpenGL contect can only active in one thread at once. If the GC calls a destructor from a thread which doesn't have that context active, it will probably crash.(e.g: if the GC calls any OpenGL function, you get a "nice" crash since OpenGL is not multithread-aware by default).Really? I don't see this in my projects. The GC stops the world, so there shouldn't be any races.
Feb 20 2015
On Friday, 20 February 2015 at 13:44:04 UTC, ponce wrote:On Friday, 20 February 2015 at 13:04:51 UTC, John Colvin wrote:Hmm, yeah you're right. That would explain some of my weirder crashes! However, if you make the context current in the GC thread that's cleaning up, then you should be fine. There's nothing wrong with having the same context current in multiple threads as long as you don't access it concurrently.On Friday, 20 February 2015 at 09:57:48 UTC, francesco.cattoglio wrote:Not a race. An OpenGL contect can only active in one thread at once. If the GC calls a destructor from a thread which doesn't have that context active, it will probably crash.(e.g: if the GC calls any OpenGL function, you get a "nice" crash since OpenGL is not multithread-aware by default).Really? I don't see this in my projects. The GC stops the world, so there shouldn't be any races.
Feb 20 2015
On Friday, 20 February 2015 at 15:26:02 UTC, John Colvin wrote:However, if you make the context current in the GC thread that's cleaning up, then you should be fine. There's nothing wrong with having the same context current in multiple threads as long as you don't access it concurrently.I'm sorry but there is two problems with your solution: - first an OpenGL context cannot be bound to more than one thread simultaneously https://msdn.microsoft.com/en-us/library/windows/desktop/dd374387%28v=vs.85%29.aspx "A rendering context can be current to only one thread at a time." Looks odd since compute APIs do not have this limitation. - At the point where destructors are called by the GC, all other threads have been resumed. http://dlang.org/garbage.html So concurrent OpenGL calls may happen for the same context which is forbidden. Really such ressources should not be freed by the GC, and I with it would not call destructors at all.
Feb 20 2015
On Friday, 20 February 2015 at 17:49:22 UTC, ponce wrote:Really such ressources should not be freed by the GC, and I with it would not call destructors at all.s/with/wish
Feb 20 2015
On Fri, 20 Feb 2015 17:49:21 +0000, ponce wrote:On Friday, 20 February 2015 at 15:26:02 UTC, John Colvin wrote:28v=3Dvs.85%29.aspxHowever, if you make the context current in the GC thread that's cleaning up, then you should be fine. There's nothing wrong with having the same context current in multiple threads as long as you don't access it concurrently.=20 I'm sorry but there is two problems with your solution: =20 - first an OpenGL context cannot be bound to more than one thread simultaneously =20 https://msdn.microsoft.com/en-us/library/windows/desktop/dd374387%"A rendering context can be current to only one thread at a time." =20 Looks odd since compute APIs do not have this limitation. =20 - At the point where destructors are called by the GC, all other threads have been resumed. http://dlang.org/garbage.html So concurrent OpenGL calls may happen for the same context which is forbidden. =20 =20 Really such ressources should not be freed by the GC, and I with it would not call destructors at all.the funny thing is that destructor can be called while another thread is=20 *inside* OpenGL call. is starts to be funniest with each post.=
Feb 20 2015
On Friday, 20 February 2015 at 17:49:22 UTC, ponce wrote:On Friday, 20 February 2015 at 15:26:02 UTC, John Colvin wrote:The OS X documentation makes it seem possible: https://developer.apple.com/library/mac/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_threading/opengl_threading.htmlHowever, if you make the context current in the GC thread that's cleaning up, then you should be fine. There's nothing wrong with having the same context current in multiple threads as long as you don't access it concurrently.I'm sorry but there is two problems with your solution: - first an OpenGL context cannot be bound to more than one thread simultaneously https://msdn.microsoft.com/en-us/library/windows/desktop/dd374387%28v=vs.85%29.aspx "A rendering context can be current to only one thread at a time." Looks odd since compute APIs do not have this limitation.- At the point where destructors are called by the GC, all other threads have been resumed. http://dlang.org/garbage.html So concurrent OpenGL calls may happen for the same context which is forbidden. Really such ressources should not be freed by the GC, and I with it would not call destructors at all.Ah, yes, you're right.
Feb 21 2015