22 ms·
Show HN: Crown – A flexible game engine written from scratch in C++
- comstock 9y agoInteresting! I'd be interested in better understanding the motivation behind Orthodox C++. In particular, you seem to dump most of the C++ standard library: "Don't use anything from STL that allocates memory, unless you don't care about memory management." I now mostly avoid templatization in my own code unless there's a really good reason. But the standard library often lets me avoid explicit memory allocation. Would love to hear more about the motivation for this (and other aspects of your C++ usage). Also, if you have a demo of the engine in use that would be fun to see!
- thehardsphere 9y agoYeah, I'd like to know why you'd still use C++ at all if you find Orthodox C++ appealing. It would seem easier to just write C. Unless I'm missing something (I probably am; don't write enough of either one to have an informed opinion, which is why I'd love to hear more about this).
- badsectoracula 9y agoWell, you still get classes and templates.
- dgfgfdagasdfgfa 9y agoRAII is incredibly attractive, especially if you disable exceptions.
- maccard 9y agoIf you disable exceptions hoe do you handle failures in constructors?
- dgfgfdagasdfgfa 9y agoI mean it's kind of a smartass answer, but—don't fail during constructors. Move all possible code that can fail into an initialize method; check explicitly for allocation failure and/or put things on the stack instead of heap when possible; consider failing hard with a stack trace or core dump over catching and processing exceptions before (likely) failing anyway.
- dan00 9y agoInstead of using a constructor you can use a constructor method e.g.: class Foo { public: static std::optional<Foo> create(); private: Foo(); };
- maccard 9y agoIn general if you're not using exceptions, you're not going to be using features that haven't actually been published in a formal standard (optional). This now means that you can't use any constructors, so how do you have Containers of foo?
- imron 9y ago> you're not going to be using features that haven't actually been published in a formal standard (optional). So you then have things like: class Foo { public: static Foo* create(); ... }; ... Foo* foo = Foo::create() if ( foo != nullptr ) ... > so how do you have Containers of foo? std::vector<Foo*> Not saying either of those are better than the alternative (I prefer using exceptions and RAII), just pointing out what I've seen in real world projects.
- mikepurvis 9y agoI don't think this is the proposal. The proposal is that the object contains a genuine constructor that only does the bare-bones "safe" stuff, and then it has a separate non-static method that does the might-fail initialization. So: class Foo { public: Foo(); bool initialize(); // returns success ... }; ... Foo foo; if ( !foo->initialize() ) { // handle error } This also means you can break up your initialization so that you drive the risky pieces from outside the object, rather than monolithically from within. This has a further benefit for testing, since you can use your major objects without fully initializing the entire world that they depend on.
- tjoff 9y agoWhy would RAII be especially attractive if disabling exceptions?
- deleted 9y ago[deleted]
- mbel 9y agoProbably because exceptions are the biggest source of pain with RAII.
- tjoff 9y agoI'd say that exceptions are the biggest source of pain if you don't have RAII. Or, rephrased: RAII is incredibly attractive, especially when exceptions are being used.
- dgfgfdagasdfgfa 9y agoRAII is necessary for exceptions. Why the hell would you do that to yourself?
- leni536 9y agoHow do you deal with constructors that might fail?
- dbartolini 9y agoSensible usage of templates, operator overloading and namespaces is ok.
- dbartolini 9y agoI do not use STL because I want consistent implementation across all supported platforms. Also, you have to care about memory management when you need performance or when working with memory constrained devices. The way STL deals with custom allocators makes no sense to me, hence my own implementation. You can find demos in the `samples` folder. :)
- moomin 9y agoShow me a man who thinks STL allocators make complete sense, and I'll show you a man with some serious cognitive issues.
- badsectoracula 9y agoGenerally speaking many C++ game engines avoid the STL stuff and reimplement their own more predictable containers, often with custom allocation schemes. The engine at the last game company i worked at, for example, had its own containers and memory allocator and allowed you to define the allocation category and pool per allocator and per object class (so, e.g., dynamic strings would be isolated to their own pool to avoid fragmenting the heap). Related, Andrei Alexandrescu had a great talk about allocators in C++ a couple of years ago: https://www.youtube.com/watch?v=LIb3L4vKZ7U https://www.youtube.com/watch?v=LIb3L4vKZ7U Also related to the Orthodox C++, the same engine also ousted exceptions and RTTI. I'm not sure about the reason for exceptions, but C++'s RTTI was simply inadequate and instead it was replaced with a custom one made using macros (similarly to wxWidgets and MFC) that allowed automatic object serialization and reflection which was used for all saving and loading, exposing objects to the editor automatically with a common UI and exposing classes and objects to the (custom) scripting language with very little setup. Interestingly most of the stuff the engine had to reinvent seem to be first class citizens in the D language. Also Andrei's allocators also seem to be available (experimentally) there too. Personally i prefer plain old C (C89 even, although with a few commonly available or easily reproducible extras like stdint) because i see C++ as too complex for what it is worth. However D seems to provide more power with less complexity and more and more makes me want to try it, especially the new "better C" mode that DMD has got (which i think is somewhat the D equivalent to Orthodox C++ that is linked from the page).
- netheril96 9y ago> dynamic strings would be isolated to their own pool to avoid fragmenting the heap Strings have arbitrary sizes. How does pooling them together reduce fragmentation? Do they always come and go in groups?
- moomin 9y agoI think it reduces fragmentation in the other pools, not the string pool.
- 9y ago
- dagw 9y agoWould love to hear more about the motivation for this (and other aspects of your C++ usage). I know EA wrote their own implementation of STL[1] to get around the problems that the standard implementation was causing in their game engines. Doing a 'diff' between that and a standard implementation should highlight some of the potential problems they found. [1] https://github.com/electronicarts/EASTL https://github.com/electronicarts/EASTL
- torrent-of-ions 9y agoWhat is "a standard implementation"?
- Jumziey 9y agoReally cool work! I would love to have some time over to try it out.
- dbartolini 9y agoHey, thanks. :)
- aaron-lebo 9y agoNew hobbyist engines pop up from time to time and then they fade into memory. Why is this going to be different? Not to be too grumpy but game engines are a weird thing cause they are such complex beasts and usually the people using them have invested a lot of time in learning them. It's fun to make a new engine, but it probably doesn't have the community nor interest to cover the hard 10 to 20% that inevitably come up. Seems like the time is better invested in one of the super big AAA engines or in writing your own. What's the plan for 2 to 3 years from now? https://news.ycombinator.com/item?id=5442366 https://news.ycombinator.com/item?id=5442366 Polycode had some interest around here 4 years ago, with lots of the same goals, but haven't really heard from it since. Similarly, how does this compare to Godot or even something like Torque?
- grive 9y agoThe use of Orthodox C++ is more interesting than yet another game engine I think. This speaks about language design and communities, approach to development practices.
- numbsafari 9y agoDo features or concepts kicked around in the "hobbyist" engines ever influence or inform the mainstream engines?
- dbartolini 9y agoThese are features and concepts kicked around by mainstream engines. In fact, this work is inspired by Bitsquid/Stingray.
- AHTERIX5000 9y agoYeah, writing game engines can be a great framework for learning all kinds of useful and interesting concepts (and trying out experimental things!) but an actual, usable engine needs a ton of "boring" stuff regarding tooling and asset pipeline that hobby engines usually miss. When artist creates shiny visuals in <some editor> it is expected to look somewhat like that in engine and then you find yourself deep in some FBX/whatever SDK/your own loader + shaders wondering how the pipeline is supposed to work and how all the usual formats seem to suck in some way. Add animations, IK etc. and suddenly there is a lot of work to do that production quality engines solve. That is not to say it is always needed though if the game is really simplistic. But there are a lot of engines capable of rendering instanced bouncing OBJs out there.
- OssetianOdin 9y agoI partially agree with "Orthodox C++". Templates should be used only when needed and for turn the code simpler(not like the abomination used in most of Boost libraries). But also, i don,t see any sane reason to reinvent the wheel and reimplement basic stuff like thread/mutex classes when the C++ version works well. Or using "NULL" instead "nullptr", or using that pre-processor macro garbage instead templates/constexpr, etc I think some modern C++ features, that if well used, turn the code much clear and expressive.
- dbartolini 9y agoWhen I started the project C++11 was not supported well on most compilers. I'm fine with new features when they don't limit my freedom. I'm fine with nullptr, it is going to replace NULL very soon.
- sqeaky 9y agoYou should just replace it and define a nullptr macro for older compiles.
- teknico 9y agoIt's a lost cause: there's no such thing as "sane" or "orthodox" C++. Instead, use something actually sane like Go. Or Rust, if you really must (first bad pun is free, then it's 50 cents each).
- aaron-lebo 9y agoIf you're gonna bother with orthodox C++, or Go (suited to 3d games? nobody seems to have tried or lived to tell the tale), or Rust (no libraries anyway, so you may as well use something which wraps C easily and is higher level), why not try Nim?
- gmfawcett 9y agoI think if you were writing C, then Nim might be a good alternative. If you're writing C++, then Nim offers a lot of similar metaprogramming features; but it lacks RAII, which IMO is a monumental drawback. People may dislike C++ for many reasons, but RAII is a killer feature -- there's no question why languages like D and Rust adopted it.
- Araq 9y agoWe're slowly getting there though. I hope to release a blog post soon about how it might look like in Nim.
- zielmicha 9y agoGo is a bad choice for game with its unavoidable GC. And Rust is simply too complicated for a person wanting sane C++. D or Nim (or even C!) would make more sense.
- dmit 9y agoIs there not a point where GC overhead becomes negligible? There have been production examples of Go maintaining sub-millisecond GC pauses with a multi-GB heap under a server workload. https://twitter.com/brianhatfield/status/804355831080751104 https://twitter.com/brianhatfield/status/804355831080751104 Surely there are better reasons to disregard Go for gamedev by now.
- JabavuAdams 9y agoGreat learning project, but for production just use Unity unless you absolutely, positively (triple-check) cannot. You will be massively more productive.
- thehardsphere 9y agoUmm, no. Unity has lots of problems that make it not ideal for games that have fast action or are developed by a larger team. Like, the fact that it uses an old version of Mono on not-Windows, which uses a mark and sweep garbage collector. You end up with frequent stop-the-world garbage collection pauses that freeze the screen for seconds at a time. Play any Unity game on the PS4 and you'll see it frequently. I've also heard that Unity's project asset management doesn't really work for teams that have more than 10 people working together, but that's something I don't have direct knowledge of.
- JabavuAdams 9y agoThere's a lot of FUD surrounding Unity, although I cannot comment on PS4, specifically, as I have not shipped for that platform. On mobile, and/or desktop there are very few empirical reasons not to use Unity. If you have the skills to develop your own engine and tools, then you certainly have the skills to work around Unity or garbage-collection issues. When I'm hiring a game developer and they'd rather work on engine or tools than making games, this is a red flag. I've seen projects waste person-decades of development effort all because one or two senior devs wanted to do roll their own thing instead of using Unity. The engine and toolchain that is always has flaws that the utopian engine and toolchain that could be don't have (yet).
- thehardsphere 9y ago>On mobile, and/or desktop there are very few empirical reasons not to use Unity. If you have the skills to develop your own engine and tools, then you certainly have the skills to work around Unity or garbage-collection issues. I guess. The question is why should I have to work around Unity? I mean, everything is a trade-off. I understand that for many teams and games, the hassles of Unity are worth the benefits. But that is not every game and every team. >The engine and toolchain that is always has flaws that the utopian engine and toolchain that could be don't have (yet). We don't have to compare Unity to utopian engines and tool chains when we can compare it to its competitors like Unreal.
- alkonaut 9y agoWow it seems to contain a full level editor written in vala, a language I hadn't heard of. It seems to be a high level language similar to C# but with a native compiler and some different semantics (RC instead of a tracing GC for example). Is vala widely used?
- rhodysurf 9y agoIts really only used for gtk3 apps. I think it was created with that in mind by the gnome team
- dbartolini 9y agoToolchain was initially written in C#. Vala simplified a lot the switch to GTK+3. Today I think an IMGUI-like approach is the way to go for game tools. Rewriting the editors should be rather painless due to their engine-decoupled TCP/IP architecture.
- pjmlp 9y ago> RC instead of GC RC is a GC algorithm
- alkonaut 9y agoI just had to change my comment now, thanks.
- pja 9y agoVala came out of Gnome/Gtk app development on Linux IIRC. It takes the GObject object layer from Gtk/Glib and promotes it to a first class part of the language: There’s a fairly direct translation from the various parts of the Vala language to C + GObject / Glib / Gtk+. I don’t think it’s widely used outside of the Gnome desktop world, but there’s quite a few apps written in it out there.
- escapetech 9y agoVala has been out for some time. I haven't used it since 2007 though. Vala would always come up in discussions about C# on GNU/Linux and Stallman in particular wanted no parts of C# or Mono in the operating system.
- lazyjones 9y agoWhile I find the "sane C++" approach pragmatic and practical all things considered, I'm firmly in the "time to use a better language if possible" camp. The problem with approaches requiring extra discipline is: it's an extra mental burden to bear while programming. Also, you'll always be limited by the fact that you're working in a less pure ecosystem and will likely end up using libraries written in "not very sane C++" anyway. We seem to have flexible compiler SDKs these days (LLVM etc.), why isn't there a strict "sane C++" or "orthodox C++" subset available as a custom language or compiler option yet?
- jahnu 9y agoI guess the reason is that a combination of static analysis and code formatting does most of the same job. But I would also love to have it as a compiler switch.
- dbartolini 9y agoPeople are working towards that objective, see for example Jonathan Blow's Jai.
- jcalabro 9y agoI'm really excited about this language. Here is a link where Blow live codes and explains features: https://www.youtube.com/playlist?list=PLmV5I2fxaiCKfxMBrNsU1kgKJXD3PkyxO&app=desktop https://www.youtube.com/playlist?list=PLmV5I2fxaiCKfxMBrNsU1...
- mbel 9y ago> why isn't there a strict "sane C++" or "orthodox C++" subset available as a custom language or compiler option yet? Probably because sanity is (1) subjective, (2) in this case doesn't really come from disabling features (restricting language). He is still using most of the C++ features (overloads, operator overloading, templates) but only in semantic context that is obvious for them (i.e. templates for collections, overloaded operators for vectors and matrices). Therefore it might be a little bit hard to create a compiler front end that would understand which class acts as a collection or whether given structure is implementation of well known mathematical concept.
- zakirenish 9y agoIf you come to finance, most of the developers love premature templatization, it makes them feel like they know something. Not sure it that can be attributed to their insecurity about C++ coding skills, but it gets really ridiculous at times.
- dbartolini 9y agoI guess they start over each time the requirements change? :)
- jcranberry 9y agoI have a friend who runs a hedge fund, not really insecure at all but uses templates vigorously. More stuff in compile time rather than runtime. In critical sections inheritance can be prohibitively expensive because of the use of lookup tables.
- monocasa 9y agoThrashing your I$ because you have too many template instantiations can be prohibitively expensive too, it's just harder to metric.
- mhh__ 9y agoJust how many nested templates are we talking about here? You can have that problem (obviously) with or without templates. Most sane template designs don't exist when the program is actually run (Debugging them when they don't work is another matter)
- makapuf 9y agoif you're using templates for compile time computations it's maybe time for c++14 or even c++17 simpler constexpr functions (if possible and available, and if allowed to, ofc.)
- typon 9y agoWhat's wrong with using templates vigorously?
- tempodox 9y agoProps for the coding discipline. I couldn't even tell how long it has been since I saw C++ as readable as this.
- dbartolini 9y agoThanks, I'm glad you like it. :)
- ericfrederich 9y agoGreat title. C++ is so terrible you have to prefix it with "modern" or "sane" to get people excited about it.
- mikepurvis 9y agoA cross platform project in modern C++ that doesn't use CMake? Unsure if want.
- dbartolini 9y agoIt is not "modern" C++. It uses GENie, a fork of premake.
- mikepurvis 9y agoHuh. Okay, that was not immediately apparent from viewing the project— it looked like a hand-written Makefile. Link for the curious: https://github.com/bkaradzic/GENie https://github.com/bkaradzic/GENie Appreciating that CMake has its warts, it also has a ton of mindshare and has lots of convenient modules for handling common dependencies. What are the motivations to use a Lua-based scheme instead?
- dbartolini 9y agoI find GENie/premake way simpler to read and write. Also, you have more flexibility since your build scripts have full-fledged Lua capabilities.
- mikepurvis 9y agoYeah, similar sentiments in the PPT presentation here: https://onedrive.live.com/view.aspx?cid=171ee76e679935c8&page=view&resid=171EE76E679935C8!139573&parId=171EE76E679935C8!18835&authkey=!AKv_SGrgJwxDGDg&app=PowerPoint https://onedrive.live.com/view.aspx?cid=171ee76e679935c8&pag... CMake is "too complicated" and "you need to be an expert". Understandable, I suppose. There are certainly specific things in CMake which are pretty terrible, like the add_custom_command/add_custom_target dance, but from the perspective of someone who has had to become an expert in it (via ROS/catkin), I would be unlikely to give it up. There's just way too much stuff it gives you for free, especially when it comes to things like packaging, testing, etc.
- mikepurvis 9y ago
- krapp 9y agoI'm not trying to be too critical, but the first thing I look for whenever I come across a new game engine is an actual game implemented in it. Unfortunately, almost none of these engines ever seem to get around to providing a MVP.
- andrewmcwatters 9y agoBingo. Designing a game engine that has no dogfood project(s) just portrays it has no applied use, and hasn't ran into issues with its own design before.
- B1narySunset 9y agoHow long have you been working on this engine for?
- dbartolini 9y agoI started with game engines well before I put this project on github in 2012.
- mendeza 9y agoCan you recommend any resources/books to learn game engine development? I would love to implement a mini one where I can rapidly prototype AR applications :).
- dbartolini 9y agoGame Engine Architecture by Jason Gregory is a nice one. Search for "Bitsquid" and "Our Machinery": pure gold IMHO.
- slavik81 9y agoYou may just want to start by building your AR applications first. After a few of them, you'll have a better understanding of what common functionality is needed. See also: https://geometrian.com/programming/tutorials/write-games-not-engines/ https://geometrian.com/programming/tutorials/write-games-not...
- mendeza 9y agoI love the article! It makes sense that after developing AR application on a game engine, I will identify the common functionality that would fit better for an "engine" that would fit the ideas I want to develop. I am interested in developing AR applications that are not as much of a game, so I was worried that a game engine would not fit. With both learning more about graphics and making my own games, it would make future engine development more clear.
- partycoder 9y agoThe code seems clear enough, though I think the preprocessor macros for wrapping OS specific logic could be at the function level or class level rather than at the statement level.
- dbartolini 9y agoWhy when code amount is small enough?
- andrewmcwatters 9y agoYour use of `require` is incorrect.
- dbartolini 9y agoCan you elaborate on this?
- andrewmcwatters 9y agohttp://lua-users.org/lists/lua-l/2012-08/msg00302.html http://lua-users.org/lists/lua-l/2012-08/msg00302.html
- dbartolini 9y agoAll resource paths (.lua files are resources like any other) in Crown are unix-style and do not include the extension. I have a custom loader that deals with it: https://github.com/dbartolini/crown/blob/master/src/lua/lua_environment.cpp#L52 https://github.com/dbartolini/crown/blob/master/src/lua/lua_...
- andrewmcwatters 9y agoI would recommend that you extend `package.loaders` instead. You risk breaking expected `require` functionality. Then you get the benefits of both!! https://www.lua.org/manual/5.1/manual.html#pdf-package.loaders https://www.lua.org/manual/5.1/manual.html#pdf-package.loade...
- dbartolini 9y agoI already do so: https://github.com/dbartolini/crown/blob/master/src/lua/lua_environment.cpp#L85 https://github.com/dbartolini/crown/blob/master/src/lua/lua_...
- andrewmcwatters 9y agoExample: https://github.com/Planimeter/grid-sdk/blob/master/engine/init.lua#L7 https://github.com/Planimeter/grid-sdk/blob/master/engine/in...
- Jeaye 9y agoYet another game engine written in an imperative language, seemingly with the focus on writing something in Orthodox C++ and not necessarily writing something to solve a problem. Just as the discussion on this post shows, the more interesting thing here is Orthodox C++, not yet another game engine which doesn't offer any featues that modern game engines offer. If you're expecting people to see this as a useful product, please explain why it should be used instead of the existing game engines. Consider listing its features and comparing them, maybe in a table, to popular game engines. Deferred rendering? Multi-threaded rendering? Entity-component system? etc. Right now, I can see it has a (nice looking) editor, "physics" (nothing's moving, so it's hard to tell), and "animation" (again, nothing's animating in the image). Alas, one needs to learn to use its entirely fresh standard library reimplementation, and likely its strict C++ subset, if one actually wants to be productive with it. Given apparently no active community, no sample (or actual) games written in it, and no paid support, I don't see how that would be feasible. If you have no interest in actually making a competitive, novel, or useful (to others, compared to existing solutions) game engine, please just say that. In that case, I'd just say this is a neat side project: well done, but try to focus on building something with it to help sell/prove its features.
- dbartolini 9y agoIt is just a simple general-purpose, data-oriented, data-driven, entity-component based, lua scripted game engine written in sane C++ for my own game development needs. Nobody's trying to sell anything here.