www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - "I made a game using Rust"

reply JN <666total wp.pl> writes:
Interesting thread I got from Reddit, someone made a game for PC 
and mobiles fully in Rust.

https://michaelfairley.com/blog/i-made-a-game-in-rust/

"Last week, I released A Snake’s Tale on iOS, Android, Windows, 
Mac, and Linux.".

I wonder, would it be possible for D in the current state to 
achieve the same? I imagine iOS isn't possible yet and Android is 
just getting there?
May 10 2017
next sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 Interesting thread I got from Reddit, someone made a game for 
 PC and mobiles fully in Rust.

 https://michaelfairley.com/blog/i-made-a-game-in-rust/

 "Last week, I released A Snake’s Tale on iOS, Android, Windows, 
 Mac, and Linux.".

 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
7700 lines of Rust. We need a language called Nine Inch Nails or something :D
May 10 2017
prev sibling next sibling parent Atila Neves <atila.neves gmail.com> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 Interesting thread I got from Reddit, someone made a game for 
 PC and mobiles fully in Rust.

 https://michaelfairley.com/blog/i-made-a-game-in-rust/

 "Last week, I released A Snake’s Tale on iOS, Android, Windows, 
 Mac, and Linux.".

 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
I'd like to know how it was packaged to run Rust on both iOS and Android. Atila
May 10 2017
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
Probably about the same, the author mostly complains about immature libraries for mobile and D is really in the same boat... BTW: "Add an icon to my .exe” don’t have ready-made solutions." I'd be surprised if that is any different in Rust than it is in D... which is no different than it is in C. And this is what jumps out at me: "Holy cow are the compiler error messages generally fantastic." Those of you on IRC know that I've been pushing hard for better error messages. I think that is *the* killer feature clang offered and I see it brought up again and again. D used to do well. Now we're lagging behind. No language change needed to vastly improve error messages.
May 10 2017
parent reply Ethan Watson <gooberman gmail.com> writes:
On Wednesday, 10 May 2017 at 13:22:22 UTC, Adam D. Ruppe wrote:
 Those of you on IRC know that I've been pushing hard for better 
 error messages. I think that is *the* killer feature clang 
 offered and I see it brought up again and again.

 D used to do well. Now we're lagging behind. No language change 
 needed to vastly improve error messages.
I find it a very curious state of affairs myself that Microsoft's C++ compiler has significantly better error messages than DMD.
May 10 2017
parent reply Adrian Matoga <dlang.spam matoga.info> writes:
On Wednesday, 10 May 2017 at 14:00:08 UTC, Ethan Watson wrote:
 On Wednesday, 10 May 2017 at 13:22:22 UTC, Adam D. Ruppe wrote:
 Those of you on IRC know that I've been pushing hard for 
 better error messages. I think that is *the* killer feature 
 clang offered and I see it brought up again and again.

 D used to do well. Now we're lagging behind. No language 
 change needed to vastly improve error messages.
I find it a very curious state of affairs myself that Microsoft's C++ compiler has significantly better error messages than DMD.
Would you mind giving some examples?
May 10 2017
next sibling parent reply Ethan Watson <gooberman gmail.com> writes:
On Wednesday, 10 May 2017 at 14:02:38 UTC, Adrian Matoga wrote:
 Would you mind giving some examples?
My biggest bugbear with DMD is internal compiler errors giving me no meaningful information. Excepting one or two edge cases with SSE types and the .NET compiler, I can get a meaningful error message and an error code from MSVC. And you can search them all through the MSDN documentation. https://msdn.microsoft.com/en-us/library/8x5x43k7.aspx If I find the message isn't that helpful, googling for the error code usually brings up discussions on stackoverflow about it. Even user-inserted #errors have an error code. https://msdn.microsoft.com/en-us/library/y0tzt8e0.aspx
May 10 2017
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Wednesday, 10 May 2017 at 14:13:37 UTC, Ethan Watson wrote:
 On Wednesday, 10 May 2017 at 14:02:38 UTC, Adrian Matoga wrote:
 Would you mind giving some examples?
My biggest bugbear with DMD is internal compiler errors giving me no meaningful information.
Internal compiler errors (ICEs) are bugs which are generally treated as high priority. Please report them.
May 10 2017
parent reply Ethan Watson <gooberman gmail.com> writes:
On Wednesday, 10 May 2017 at 14:31:28 UTC, Vladimir Panteleev 
wrote:
 Internal compiler errors (ICEs) are bugs which are generally 
 treated as high priority. Please report them.
See my previous rant on this subject. http://forum.dlang.org/post/qkxyfiwjwqklftcwtcik forum.dlang.org tl;dr - Sure, we'll submit bugs, but if someone literally has to stop work for a day because they can't tell at a glance what's gone wrong when compiling code then that's a massive failure of the compiler.
May 10 2017
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/10/17 10:37 AM, Ethan Watson wrote:
 On Wednesday, 10 May 2017 at 14:31:28 UTC, Vladimir Panteleev wrote:
 Internal compiler errors (ICEs) are bugs which are generally treated
 as high priority. Please report them.
See my previous rant on this subject. http://forum.dlang.org/post/qkxyfiwjwqklftcwtcik forum.dlang.org
And my previous answer: http://forum.dlang.org/post/nqc4tg$12im$1 digitalmars.com I'll reiterate here: if the compiler's sanity is suspect, there's nothing much for it to do except crash. hard. And tell you where to look. Fortunately for the current state of affairs, if the error is in the front-end, it's D. And it should give you a stack trace. Your previous example seems to be in C++ part of it, so no stack trace. -Steve
May 10 2017
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, May 10, 2017 at 07:52:53PM -0400, Steven Schveighoffer via
Digitalmars-d wrote:
[...]
 I'll reiterate here: if the compiler's sanity is suspect, there's nothing
 much for it to do except crash. hard. And tell you where to look.
[...] OTOH, it's not very nice from a user's POV. It would be nice(r) if this PR could be looked at and brought to a mergeable state: https://github.com/dlang/dmd/pull/6103 T -- Programming is not just an act of telling a computer what to do: it is also an act of telling other programmers what you wished the computer to do. Both are important, and the latter deserves care. -- Andrew Morton
May 10 2017
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/10/17 7:54 PM, H. S. Teoh via Digitalmars-d wrote:
 On Wed, May 10, 2017 at 07:52:53PM -0400, Steven Schveighoffer via
Digitalmars-d wrote:
 [...]
 I'll reiterate here: if the compiler's sanity is suspect, there's nothing
 much for it to do except crash. hard. And tell you where to look.
[...] OTOH, it's not very nice from a user's POV. It would be nice(r) if this PR could be looked at and brought to a mergeable state: https://github.com/dlang/dmd/pull/6103
Yes, totally agree. Proper reporting of errors is a very important thing. Here's another one: https://issues.dlang.org/show_bug.cgi?id=13810 -Steve
May 11 2017
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 10 May 2017 at 14:02:38 UTC, Adrian Matoga wrote:
 Would you mind giving some examples?
What bothers me on a regular basis is overloading. Basic case: $ dmd lll lll.d(6): Error: none of the overloads of 'foo' are callable using argument types (int, double), candidates are: lll.d(1): lll.foo(int a, int a) lll.d(2): lll.foo(int a, string s) Contrast that to g++: $ g++ lll.cpp lll.cpp: In function ‘int main()’: lll.cpp:7:14: error: no matching function for call to ‘foo(int, Foo)’ foo(0, Foo()); ^ lll.cpp:7:14: note: candidates are: lll.cpp:1:6: note: void foo(int, char*) void foo(int a, char* b); ^ lll.cpp:1:6: note: no known conversion for argument 2 from ‘Foo’ to ‘char*’ lll.cpp:2:6: note: void foo(int, float) void foo(int a, float b); ^ lll.cpp:2:6: note: no known conversion for argument 2 from ‘Foo’ to ‘float’ The g++ example isn't great either... but is better because of this: "no known conversion for argument 2 from ‘Foo’ to ‘float’" It actually told me which argument didn't match! clang is similar: $ clang lll.cpp lll.cpp:7:2: error: no matching function for call to 'foo' foo(0, Foo()); ^~~ lll.cpp:1:6: note: candidate function not viable: no known conversion from 'Foo' to 'char *' for 2nd argument void foo(int a, char* b); ^ lll.cpp:2:6: note: candidate function not viable: no known conversion from 'Foo' to 'float' for 2nd argument void foo(int a, float b); With the dmd one, especially on a long function, it is hard to tell just which argument is giving trouble. The C++ errors just flat out tell me which argument didn't match for each candidate. Templates with constraints are even worse. lll.d(3): Error: template std.algorithm.sorting.sort cannot deduce function from argument types !()(int), candidates are: /home/me/d/dmd2/linux/bin32/../../src/phobos/std/algorithm/sorting.d(1830): std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range) What a mess! Just formatting that output might help, but I'd especially love it if it told me which individual boolean elements failed, passed, and were short-circuited. The compiler knows this, it had to evaluate that to figure out it didn't match, but it doesn't tell me. At a glance, can you even tell what I passed to the function? Bonus points would be it telling me why, for example, `isInputRange` failed, but I understand that is an even bigger problem to solve. Of course, C++ doesn't have constraints so there's no comparison there. Lastly, check this out: lll.d(5): Error: function lll.foo (Color c) is not callable using argument types (Color) WTF, right? Well, I have a locally defined `struct Color` and an imported one. Same name, but different type. The error message doesn't tell me which one is which. These are the top 3 dmd error messages that bother me regularly. At runtime, little drives me more nuts than RangeError not telling me the index and the length. Again, it knows, the code checked it, but it didn't report it.
May 10 2017
parent reply Adrian Matoga <dlang.spam matoga.info> writes:
On Wednesday, 10 May 2017 at 15:03:19 UTC, Adam D. Ruppe wrote:
 On Wednesday, 10 May 2017 at 14:02:38 UTC, Adrian Matoga wrote:
 Would you mind giving some examples?
What bothers me on a regular basis is overloading. Basic case: $ dmd lll lll.d(6): Error: none of the overloads of 'foo' are callable using argument types (int, double), candidates are: lll.d(1): lll.foo(int a, int a) lll.d(2): lll.foo(int a, string s) Contrast that to g++: $ g++ lll.cpp lll.cpp: In function ‘int main()’: lll.cpp:7:14: error: no matching function for call to ‘foo(int, Foo)’ foo(0, Foo()); ^ lll.cpp:7:14: note: candidates are: lll.cpp:1:6: note: void foo(int, char*) void foo(int a, char* b); ^ lll.cpp:1:6: note: no known conversion for argument 2 from ‘Foo’ to ‘char*’ lll.cpp:2:6: note: void foo(int, float) void foo(int a, float b); ^ lll.cpp:2:6: note: no known conversion for argument 2 from ‘Foo’ to ‘float’ The g++ example isn't great either... but is better because of this: "no known conversion for argument 2 from ‘Foo’ to ‘float’" It actually told me which argument didn't match! clang is similar: $ clang lll.cpp lll.cpp:7:2: error: no matching function for call to 'foo' foo(0, Foo()); ^~~ lll.cpp:1:6: note: candidate function not viable: no known conversion from 'Foo' to 'char *' for 2nd argument void foo(int a, char* b); ^ lll.cpp:2:6: note: candidate function not viable: no known conversion from 'Foo' to 'float' for 2nd argument void foo(int a, float b); With the dmd one, especially on a long function, it is hard to tell just which argument is giving trouble. The C++ errors just flat out tell me which argument didn't match for each candidate.
In this simple case above, I actually prefer DMD's messages, as there's simply less text for my eyes to read and brain to parse, so I can quickly spot where the problem is. I agree, though, that with longer argument lists, especially with const vs. non-const or template constraints, trying to figure out what's wrong could be at least frustrating.
 Templates with constraints are even worse.

 lll.d(3): Error: template std.algorithm.sorting.sort cannot 
 deduce function from argument types !()(int), candidates are:
 /home/me/d/dmd2/linux/bin32/../../src/phobos/std/algorithm/sorting.d(1830):   
    std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss =
SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable &&
(hasSwappableElements!Range || hasAssignableElements!Range) || ss !=
SwapStrategy.unstable && hasAssignableElements!Range) &&
isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range)


 What a mess! Just formatting that output might help, but I'd 
 especially love it if it told me which individual boolean 
 elements failed, passed, and were short-circuited. The compiler 
 knows this, it had to evaluate that to figure out it didn't 
 match, but it doesn't tell me.

 At a glance, can you even tell what I passed to the function?

 Bonus points would be it telling me why, for example, 
 `isInputRange` failed, but I understand that is an even bigger 
 problem to solve.
It's indeed painful, but I found UDAs to be useful in dealing with it. First, I'm sure you know Atila's concepts [1]. I also use UDAs in flod [2], so instead of checking whether the implementation satisfies a constraint, I only check if it's explicitly tagged with a specific UDA. Now, I immediately see whether it's a method that I forgot to implement or just a typo, instead of being forced to guess by a "missing overload" message.
 Of course, C++ doesn't have constraints so there's no 
 comparison there.


 Lastly, check this out:

 lll.d(5): Error: function lll.foo (Color c) is not callable 
 using argument types (Color)

 WTF, right? Well, I have a locally defined `struct Color` and 
 an imported one. Same name, but different type. The error 
 message doesn't tell me which one is which.
Yeah, that one was funny. :)
 These are the top 3 dmd error messages that bother me 
 regularly. At runtime, little drives me more nuts than 
 RangeError not telling me the index and the length. Again, it 
 knows, the code checked it, but it didn't report it.
Same with assertions. I usually end up adding wrappers like assertEqual, and the more I use them, the more I feel like switching to something like [3] or [4], as much as I normally prefer to keep the number of dependencies low. I think RangeError could be solved without much effort by changing the compiler/runtime interface at _d_arraybounds*. Assertions are probably harder. [1] http://forum.dlang.org/post/eoxerbkaowxpgjubhdqq forum.dlang.org [2] https://github.com/epi/flod/blob/develop/source/flod/package.d [3] https://code.dlang.org/packages/fluent-asserts [4] http://code.dlang.org/packages/unit-threaded
May 10 2017
next sibling parent "Nick Sabalausky (Abscissa)" <SeeWebsiteToContactMe semitwist.com> writes:
On 05/10/2017 11:50 AM, Adrian Matoga wrote:
 On Wednesday, 10 May 2017 at 15:03:19 UTC, Adam D. Ruppe wrote:
 lll.d(5): Error: function lll.foo (Color c) is not callable using
 argument types (Color)

 WTF, right? Well, I have a locally defined `struct Color` and an
 imported one. Same name, but different type. The error message doesn't
 tell me which one is which.
Yeah, that one was funny. :)
It's not so funny when you're new to that error and don't already know to look for two types from different modules with the same name. :(
 Same with assertions. I usually end up adding wrappers like assertEqual,
 and the more I use them, the more I feel like switching to something
 like [3] or [4], as much as I normally prefer to keep the number of
 dependencies low.

 [3] https://code.dlang.org/packages/fluent-asserts
 [4] http://code.dlang.org/packages/unit-threaded
Unit-threaded rocks my world. First I've heard of fluent-asserts but it looks interesting.
May 10 2017
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 10 May 2017 at 15:50:06 UTC, Adrian Matoga wrote:
 In this simple case above, I actually prefer DMD's messages, as 
 there's simply less text for my eyes to read and brain to 
 parse, so I can quickly spot where the problem is.
Well, even here, I'd prefer a small tweak: lll.d(6): Error: none of the overloads of 'foo' match given: foo(int , double) lll.d(1): lll.foo(int a, int a) lll.d(2): lll.foo(int a, string s) The alignment would make it easier to eyeball the matches and options... though that fails on longer lines too. Another option is using colors (or something) to highlight which ones in the candidates matched and which didn't. The difference is small in a short case like this... but even here, I'd call it slightly better, and in a big case, it is much better.
 It's indeed painful, but I found UDAs to be useful in dealing 
 with it.
Oh, that's on the declaration side, but this error message is on the call side. Suppose I pass an input range to sort(). I prove it is an input range with UDAs or static asserts or whatever, yet the call to sort fails. Why? It is because sort requires more than just an input range, but just whate is difficult to determine from the error message. So a legible error message tells you WHAT you need to test on the declaration ("must be random access"), then the udas can handle those error messages (so like "it is not a random access range because opIndex is not implemented") Of course, the sort() function could check `isSortable` instead of everything it lists in its constraint... and I think I'd like that, but still, a more readable error message would be a big win. The llvm people are just annihilating us in the error messages and that's a bigger day-to-day boost than it seems. So yeah, we should do both: make the decls nicer with UDAs, but also make the error messages nicer for all cases. oh another class of error messages that suck: " nogc function cannot call non- nogc function map". but map is inferred so why did it fail? wrote this up in bugzilla: https://issues.dlang.org/show_bug.cgi?id=17374
 I think RangeError could be solved without much effort by 
 changing the compiler/runtime interface at _d_arraybounds*. 
 Assertions are probably harder.
yeah, I actually tried to implement it one time and failed though - the compiler code is a bit more fragile than I thought. Still shouldn't be too hard, if I had a few hours to spend on it I could prolly do it.
May 10 2017
prev sibling next sibling parent reply zetashift <rskaraya gmail.com> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
Reading this thread while going through the online D book I wonder; Would one recommend D for gamedev? I was thinking of writing small games with the help of SFML to learn D better and try to get better at programming game logic(DLang is my second programming language).
May 10 2017
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 10/05/2017 7:20 PM, zetashift wrote:
 On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 I wonder, would it be possible for D in the current state to achieve
 the same? I imagine iOS isn't possible yet and Android is just getting
 there?
Reading this thread while going through the online D book I wonder; Would one recommend D for gamedev? I was thinking of writing small games with the help of SFML to learn D better and try to get better at programming game logic(DLang is my second programming language).
Well, I wouldn't be working on[0] and [1] if I didn't think D could be used for game dev. Yes it has some work to do to make it nice, but over all its workable. [0] http://spew.cf [1] https://github.com/rikkimax/ogl_gen
May 10 2017
prev sibling parent JN <666total wp.pl> writes:
On Wednesday, 10 May 2017 at 18:20:01 UTC, zetashift wrote:
 On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
Reading this thread while going through the online D book I wonder; Would one recommend D for gamedev? I was thinking of writing small games with the help of SFML to learn D better and try to get better at programming game logic(DLang is my second programming language).
I've been using D for little 2D games for Windows and it's an excellent choice. I never bothered to set up debugging properly, I mostly rely on printf debugging and stacktrace after crashes though. But you have access to libraries like SDL/SFML, Box2D/Chipmunk, for 2D game you don't really need much more. And it's definitely more fun than C/C++.
May 10 2017
prev sibling next sibling parent Joakim <dlang joakim.fea.st> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 Interesting thread I got from Reddit, someone made a game for 
 PC and mobiles fully in Rust.

 https://michaelfairley.com/blog/i-made-a-game-in-rust/

 "Last week, I released A Snake’s Tale on iOS, Android, Windows, 
 Mac, and Linux.".

 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
iOS is possible, though that cross-compiler hasn't been updated in a year: https://github.com/smolt/ldc-iphone-dev/releases Cross-compiling for Android has been available for awhile, and I got JNI working late last year: https://github.com/joakim-noah/android/releases That game programmer mentions wanting more control over optimizing methods in Rust. Funnily enough, I've been messing with pragma(inline, true) just today to track down a bug related to inlining, and Johan added an attribute called optStrategy to ldc last summer, which lets you selectively turn on or off optimizations for a method: https://github.com/ldc-developers/ldc/pull/1637 Radu used it when debugging ldc on an ARMv5 microcontroller recently. Not available standardized across D compilers obviously, but could be some day.
May 10 2017
prev sibling next sibling parent reply Lewis <musicaljelly gmail.com> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
I've been developing a small 2D PC-only game in my free time over the last year or so (10 kLOC so far). It's very much still in the early stages, but I'll add some of my experiences here in case it's useful. For context, I'm a developer of 2.5 years at a medium-sized studio that ships full-price games. At work we use C++ (msvc) for TLDR: You can totally make a game in D right now. However, it's definitely not ideal. Be ready to deal with untested tools/libraries, wrangling with how you call out to C libraries, and a couple hacks to the D source to make things work the way you want. PROS I'll skim this section, because you all know the pros of D at this point :) No header files, sane templates, way better introspection, the list goes on. D is one of the nicest programming languages I've had the pleasure of working in. It's not without its faults, but my experience so far is that it's the language I most want to be developing a game in right now. We'll see if Jai might take that throne some day, but I reserve judgement until I can actually get my hands on it, and even that might still be years out. The Rust article mentions build times as a downside. In contrast, that has been one of the upsides of D for me. My build time is ~1.75s for a usual-case rebuild (all the game files), and ~4.5s for a full rebuild (the game, plus all heavy templates (like regexes), and all library glue code (like derelict)). Rapid build times are one of the killer features of DMD, and it makes me happy to know it will continue to be a focus as development continues. CONS The debugger. Rainers is doing great work with Mago, I suspect it simply needs more developers giving it some love. It's currently a far cry from the MSVC debugger. Mago crashes/hangs regularly for me, doesn't step in and out of functions consistently (and you can't reposition the instruction pointer by dragging if you miss a function call you want to re-run), is inconsistant about which variables I can see and which I can't, and lacks features I miss greatly (like data breakpoints). This is *by far* my biggest pain point. I'd like to look at it at some point and try to improve some of the low-hanging fruit, but debugging a debugger is a daunting proposition. DLL support. I've made a handful of hacks to druntime to allow me to implement hot-reloading via a DLL (a la Handmade Hero). My problems all stem from the fact that a D DLL has its own copy of the runtime and GC. I use the GC proxy to redirect calls from the DLL's GC to the EXE's GC, and have hacked together a similar solution for redirecting the spawning of threads. On top of that I had to completely disable finalizers, and pretty much avoid using classes altogether (at least any that might need to outlive a frame or survive a hot reload). I'll bet it's no easy task to implement, but if D supported "light" DLLs (ie DLLs that just work out of the executable's druntime), probably 2/3 my hacks to D would evaporate. This all being said, the hot reloading works marvellously with these changes, and it combined with a <2s build time makes day-to-day development far more of a joy than at work. The GC. This is an issue in games for reasons already tread many times over. It's lower on my list because it's relatively straightforward for me to intercept GC calls and do my own memory management instead. I've hacked in a setup that lets me swap allocators at runtime. For example, I can add a line at the top of a scope that says "for the duration of this scope, allocate into the scrapheap" (a bump-the-pointer stack that gets wiped at the end of each frame). I currently use the GC by default, and manually specify an allocator to use anywhere I'm generating excessive garbage, but this strategy will likely change as development continues and performance constraints start becoming more strict. Library support. Basically the same as mentioned in the Rust article. I regularly try out libraries where I find a critical bug within an hour of using the library. I've used libraries (plural) that interface to C but use the wrong calling convention, so before I discovered the problem, every function I called was a crapshoot as to whether or not some subtle misbehaviour or outright crash would occur. For reference, the libraries I'm using are: - SFML (graphics/windowing, misc utilities) - FMOD (audio) - dear imgui (debug UI) - msgpack-d (save game/state serialization) - OpenGL (just tiny bits here and there for stuff SFML and imgui don't handle out of the box) - speech4d (TTS for placeholder dialogue, I heavily modified this library to fix some critical bugs and make it work better for my purposes) Any questions, ask away!
May 10 2017
parent reply evilrat <evilrat666 gmail.com> writes:
On Wednesday, 10 May 2017 at 22:13:29 UTC, Lewis wrote:
 On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:

 PROS


 The Rust article mentions build times as a downside. In 
 contrast, that has been one of the upsides of D for me. My 
 build time is ~1.75s for a usual-case rebuild (all the game 
 files), and ~4.5s for a full rebuild (the game, plus all heavy 
 templates (like regexes), and all library glue code (like 
 derelict)). Rapid build times are one of the killer features of 
 DMD, and it makes me happy to know it will continue to be a 
 focus as development continues.
I have played recently with one D game engine and result was frustrating. My compile time was about 45 sec! Engine split in core and actual game module, every time i build game module it recompiles the engine. Great compile times, yay! The engine itself is just ~12k LOC, "game" roughly 200 lines. For example UE4 project with same line count compiles within 50 secs! Of cource whole D engine takes just 20 secs on single core, while C++ project takes all my 8 cores. (and for example building whole UE4 takes almost hour on SSD) Every changed line of code triggers full rebuild in D (remember, it does this twice, one for engine, second for game). As C++ user I find it unacceptable, simply because with PCH such changes is usually takes 2-3 secs if one don't touch the headers (well okay, more like 10 secs, still twice faster than D on edit-build-debug runs).
 CONS

 The debugger. Rainers is doing great work with Mago, I suspect 
 it simply needs more developers giving it some love. It's 
 currently a far cry from the MSVC debugger.
There is no sane x64 debugging on Windows. structs doesn't shows at all, that just top of the list... But I remember what's was back in 2011, now we at least can do full debug for x86! And last time I used OS X(in 2013) that was... well I prefer not to comment, there was simply no debugging at all.
 DLL support. I've made a handful of hacks to druntime to allow 
 me to implement hot-reloading via a DLL (a la Handmade Hero). 
 My problems all stem from the fact that a D DLL has its own 
 copy of the runtime and GC. I use the GC proxy to redirect 
 calls from the DLL's GC to the EXE's GC, and have hacked 
 together a similar solution for redirecting the spawning of 
 threads. On top of that I had to completely disable finalizers, 
 and pretty much avoid using classes altogether (at least any 
 that might need to outlive a frame or survive a hot reload). 
 I'll bet it's no easy task to implement, but if D supported 
 "light" DLLs (ie DLLs that just work out of the executable's 
 druntime), probably 2/3 my hacks to
 D would evaporate. This all being said, the hot reloading works 
 marvellously with these changes, and it combined with a <2s 
 build time makes day-to-day development far more of a joy than 
 at work.
How did you managed using classes from DLL? I mean in its current state D unable to cast anything that comes through process/shared lib boundaries(except on Linux) due to missing type info, right? And this is serious issue, this is really blocks D from commercial usage, simply because there is no way to add plugin support (from user's point of view). And realistically this is also not so trivial, this requires making special 'core' library with common classes and interfaces to include in every DLL and app itself, because one would need to use both .d and compiled module .obj (for type info, that annoying unresolved _ClassZ and others) and current build systems doesn't helps with that all, so all by hand it seems... Overall, I really like D, but its like feeding on cactus...
May 10 2017
parent reply Lewis <musicaljelly gmail.com> writes:
On Thursday, 11 May 2017 at 03:17:13 UTC, evilrat wrote:
 I have played recently with one D game engine and result was 
 frustrating. My compile time was about 45 sec!
Interesting. What game engine were you using? To me this sounds like a problem in the build process. DMD isn't a build system and doesn't handle build management, incremental builds, or anything else like that. You'll need an external tool (or roll a python script like I did). At the end of the day, you hand a bunch of files to DMD to build, and it spits out one or more exe/dll/lib/obj. This process for me has been quite fast, even considering that I'm pretty much rebuilding the entire game (minus libs and heavy templates) every time. My python script basically separates the build into four parts, and does a sort of poor man's coarse incremental build with them. The four parts are: - D libs - Heavy templates - Game DLL - Game EXE (which is pretty much just one file that loads the DLL then calls into it) For example, if a lib changes, I rebuild everything. But if a file in the Game DLL changes, I only rebuild the game DLL.
 There is no sane x64 debugging on Windows. structs doesn't 
 shows at all, that just top of the list...
In C++, I've generally had a very good experience with the visual studio debugger, both with x86 and x64. When I program C++ at home, literally the only thing I use visual studio for is the debugger (the rest of the program is pretty bloated and I use almost none of the other features). When you debugged on x64 in windows, what debugger were you using? Even back in 2011 things were good enough that I could see into structs :)
 How did you managed using classes from DLL?
I pretty much don't. If a class is created in the DLL from a class defined in the DLL and is never touched by the EXE, things seem fine. But I don't let classes cross the EXE/DLL boundary, and even then I keep my usage of classes to a bare minimum. Thankfully though my programming style is fairly procedural anyway, so it's not a huge loss for me personally.
May 11 2017
parent reply evilrat <evilrat666 gmail.com> writes:
On Thursday, 11 May 2017 at 17:38:26 UTC, Lewis wrote:
 On Thursday, 11 May 2017 at 03:17:13 UTC, evilrat wrote:
 I have played recently with one D game engine and result was 
 frustrating. My compile time was about 45 sec!
Interesting. What game engine were you using? To me this sounds like a problem in the build process. DMD isn't a build system and doesn't handle build management, incremental builds, or anything else like that. You'll need an external tool (or roll a python script like I did). At the end of the day, you hand a bunch of files to DMD to build, and it spits out one or more exe/dll/lib/obj. This process for me has been quite fast, even considering that I'm pretty much rebuilding the entire game (minus libs and heavy templates) every time. My python script basically separates the build into four parts, and does a sort of poor man's coarse incremental build with them. The four parts are: - D libs - Heavy templates - Game DLL - Game EXE (which is pretty much just one file that loads the DLL then calls into it) For example, if a lib changes, I rebuild everything. But if a file in the Game DLL changes, I only rebuild the game DLL.
I use just dub and generated Visual D project. Well in my case the problem is that engine is built as static lib, and there is not much i can do with this. I've started moving things around and turn lib to executable, at least now build time cut in half, down to 20-22 sec. And speaking about build time i mean exactly it, compile+link. Compiling without linking is just 10-12 sec. That's really good for single-threaded build! As for the engine... Here, take a look. https://github.com/Superbelko/Dash And you also need the "game" itself, add it to the engine as submodule. https://github.com/Circular-Studios/Sample-Dash-Game
 There is no sane x64 debugging on Windows. structs doesn't 
 shows at all, that just top of the list...
In C++, I've generally had a very good experience with the visual studio debugger, both with x86 and x64. When I program C++ at home, literally the only thing I use visual studio for is the debugger (the rest of the program is pretty bloated and I use almost none of the other features). When you debugged on x64 in windows, what debugger were you using? Even back in 2011 things were good enough that I could see into structs :)
Everything I said about debugging was related to D, and on Windows Visual D specifically. C++ had it for ages.
 How did you managed using classes from DLL?
I pretty much don't. If a class is created in the DLL from a class defined in the DLL and is never touched by the EXE, things seem fine. But I don't let classes cross the EXE/DLL boundary, and even then I keep my usage of classes to a bare minimum. Thankfully though my programming style is fairly procedural anyway, so it's not a huge loss for me personally.
I see. This could even be benefit for low-level stuff like renderer or physics system, especially when keeping required data in large single array. But for the game part itself this is no go, not for business at least. The real issue is that you can pass classes both ways, but any casts will fail due to no type info, I have not tested it myself but they said on Linux(only) it works as it should. So this problem had to be resolved as soon as possible, for the sake of D future.
May 11 2017
parent reply Lewis <musicaljelly gmail.com> writes:
On Friday, 12 May 2017 at 02:43:17 UTC, evilrat wrote:
 I use just dub and generated Visual D project.

 Well in my case the problem is that engine is built as static 
 lib, and there is not much i can do with this. I've started 
 moving things around and turn lib to executable, at least now 
 build time cut in half, down to 20-22 sec.

 And speaking about build time i mean exactly it, compile+link. 
 Compiling without linking is just 10-12 sec. That's really good 
 for single-threaded build!
Ah okay. If I understand correctly, the "game" itself is just the two .d files in the Scripts folder, which get compiled then linked with the prebuilt .lib for the engine. If so, a 10-12s compile just for those two files still sounds really long to me. Either I'm misunderstanding, or there's something bizarre going on that's causing those build times. I'm using derelict heavily in my project, and therefore most of my libraries live in DLLs. I've run into some annoyances with this, for example, bugs in the derelict interface to the DLL, either existing ones or ones I introduce myself, can be very difficult to detect and debug, since there's no type checking across the DLL boundary. But one huge advantage is that the build time overhead for these libraries is almost zero.
 Everything I said about debugging was related to D, and on 
 Windows Visual D specifically.
 C++ had it for ages.
Ah, my apologies I misunderstood. Agreed, the current debugging experience for D leaves much to be desired unfortunately.
 I see. This could even be benefit for low-level stuff like 
 renderer or physics system, especially when keeping required 
 data in large single array. But for the game part itself this 
 is no go, not for business at least.
Yeah I agree that this limitation sucks. Even if I try to avoid using classes, there are still times where I'm forced into it. For example, Thread is a class. I have to be very cautious when working with an instance of Thread, or I risk bizarre crashes due to mismatched typeinfo.
May 11 2017
parent Marco Leise <Marco.Leise gmx.de> writes:
Am Fri, 12 May 2017 05:42:58 +0000
schrieb Lewis <musicaljelly gmail.com>:

 Ah okay. If I understand correctly, the "game" itself is just the 
 two .d files in the Scripts folder, which get compiled then 
 linked with the prebuilt .lib for the engine. If so, a 10-12s 
 compile just for those two files still sounds really long to me. 
 Either I'm misunderstanding, or there's something bizarre going 
 on that's causing those build times.
You can't tell how long a compile takes from looking at the size of the modules you pass to the linker. Unlike C++, Dlang lacks header files that could short-circuit import chains. What this means is that all the imports in a module (except inside templates) are analyzed recursively. In the game at hand this only means parsing the entire engine code base in addition to the two modules, but projected onto LibreOffice or other big projects it would parse the code of so many libraries that compilation times would sky-rocket. (I told this story here once or twice before, but haven't actively done anything to improve the situation.) Things you can do today: - If an import is only used in templates, copy it inside of them. This works today and stops the import from being analyzed unless the template is instantiated during the compilation. Multiple instances wont pessimize compile times. - Move imports from top-level into the functions that use them. There is no other way to say "This import not needed by our public interface". - Don't turn everything and the dog into a template. Nested templates stretching over several modules require analysis of all those modules along the way, while a regular function may stop right there. - Following all the above, generate .di files for your library's exported modules. All the imports inside non-template functions will be removed and only what's needed by the public interface (i.e. argument types and return types) is kept. Several ideas spread in the past. From the top of my head: - Walter had the idea to make imports evaluate lazily, and improve the situation without resorting to .di files. - Some issued with the .di file generation stop it from being widely used for example by dub when installing libraries. - The "export" keyword could be narrowed down to be the only visibility level that goes into the .di files created for a library. (Removing public and package visibility symbols and imports pulled in by them in turn.) Last not least, with single-file-compilation like in C++ you may still shoot yourself in the foot in Dlang, because when you update a template and forget to recompile all modules that instantiate it, it is left in the old state there and cause conflicts at link time or runtime errors. Disclaimer: If you find mistakes in the above or something simply isn't true any more please give an update on the current situation. -- Marco
May 14 2017
prev sibling parent reply Vadim Lopatin <coolreader.org gmail.com> writes:
On Wednesday, 10 May 2017 at 12:52:34 UTC, JN wrote:
 Interesting thread I got from Reddit, someone made a game for 
 PC and mobiles fully in Rust.

 https://michaelfairley.com/blog/i-made-a-game-in-rust/

 "Last week, I released A Snake’s Tale on iOS, Android, Windows, 
 Mac, and Linux.".

 I wonder, would it be possible for D in the current state to 
 achieve the same? I imagine iOS isn't possible yet and Android 
 is just getting there?
DlangUI has Android support. You can develop and debug game on desktop, then build for Android.
May 11 2017
parent evilrat <evilrat666 gmail.com> writes:
On Thursday, 11 May 2017 at 08:27:16 UTC, Vadim Lopatin wrote:
 DlangUI has Android support.
 You can develop and debug game on desktop, then build for 
 Android.
Can we have an option to create OpenGL forward compatible context, please? This would really help with debugging graphics issues because not all tools (renderdoc for example) support multi-threaded rendering and/or multi-context programs. And running DlangUI with CodeXL shows it doesn't use deprecated functions, I assume it is, maybe except that old "gears" sample.
May 11 2017