DEVLOG 2023-04-01


Since the beginning of the project I have been posting regular updates on the development side of this project on redddit.com/r/roguelikedev but some people asked for these to be more public so I will be posting them here under under the title prefix DEVLOG. This can get highly technical so feel free to skip these if you are not interested into how the thing is done haha I will continue posting on reddit and here both each week.

This week I resumed the livestreams and development of the prototypes of MEGASTRUCTURES as the other game I’m working on got it’s first alpha publicly released.

In the stream we continued work I’ve been doing through the previous weeks but not publicly. The first issue was to note some things I learned (sorry if it’s quite advanced programming below haha it’s ok if you skip the details of these points, it doesn’t change the game itself):

  • Most ECS libraries (in C++ at least) are not allowing value-semantics, or more specifically they don’t allow copying the whole sets of components. This means either it’s not the right tool for my need OR I will need to write my own (maybe based on plf-colony/hive). This will have to be decided for the real game, for now I’ll continue with the “world” object not being value-semantic as it’s not a pre-requirement for the first prototype, but it is for the game’s logic. The main thing I want from an ECS is extensibility without much performance loss. These ECS libraries are providing that but push the performance to the point that copying the state of the components become complicated. One other possibility would be to still use an ECS library but to implement manual copy for it in the “world state” type, although I suspect it would not be efficient as the ECS library will not be designed around that. Anyway this is good that I realized that early.

  • Most type-erasing type libraries are either broken or super ugly: in this project I want to use type-erasing types to allow value semantics but also extensibility for action types and event types and various other things. This means that I have like a type Action which is actually a wrapper to hold any kind of action type which are implemented separately. That way I can add actions without having to register them everywhere, without a need for explicit inheritance (but it have to match a C++ concept) and in a way that let the code using actions just know it’s a value, they can be stored and manipulated in the same way as any value. Unfortunately in C++ there is nothing that helps building this kind of type-erasing types automatically (like in Rust). There are some techniques to do that easily but that require inheritance (I might end up doing this but I dont like it) and there are libraries using either heavy macros or metaprog magic to do the code generation for you - but the one that I like doesn’t work with msvc (microsof’ts compiler) and the alternatives are kind of problematic for understanding what’s going on. So last stream we just implemented the thing manually because I did that a tons of time in the past. I also improved that implementation after the stream. Anyway, the point is either I’ll write these manually or have to find a library that work and well that’s another thing to decide for the real game.

  • Godot’s GDExtension system got a bit more documentation so I browsed the docs and some code in the last few weeks. I can see how to set it up with my build system + package manager (build2 and I see how it works and the limitations etc. To me it looks good, the only thing I’m wondering is if there is any way to automate the build of the non-godot code from Godot, like having an extension that will execute some command line for you before each time you build your Godot project? That would be super neat! And if it doesn’t exist, would it be hard to make an extension for Godot like that? Recently in the other project that I’m finishing which is using Godot so that I learn about it, I had to write a script to automate a development thing, it was neat to be able to “just run the script” inside the engine! Tooling seems very easy in Godot. But this is about invoking something from outside so I have no idea if it’s doable. I will have to explore that more soon.

  • std::generator - based coroutine to handle turn solving works apparently perfectly and is very very pleasant (as soon as you have a nice implementation of it available, which most compiler dont have yet as it have been standardized only recently - I’m using tl::generator for now and will use the standard one as soon as it’s available in my compilers). So this validates my experience of writing action-turn logic as coroutine in other languages, it’s basically the same with C++ (except more complicated if you try to look into the details, as usual haha).

At the end of the stream we finally had the “Move” action implemented in a very basic way that doesn’t check if it’s valid to move where you want to move. Then I wired the view’s update logic to the update of the turns which happens when the player take a decision so I had to do some logic for capturing input. I ended up using some code from another project (teaching gamedev to a friend) to facilitate keyboard input capture. So right now we have a “working” game as in the player can move from square to square using they keyboard arrow, and wait using the space key.

That’s not much gameplay-wise but that’s almost all that was necessary for the prototype 1 because the goal was about the tech stack, not the gameplay, in this prototype. However this doesn’t mean that prototype is finished, there is still some work to do, mostly making sure a non-player can also act, try to have different actions (maybe attacking or pushing or something like that) and also try to update the view using events instead of re-reading the whole state of the game.

That’s all for this week!

Klaim

Leave a comment

Log in with itch.io to leave a comment.