More bug squashing! This included three entirely distinct lake-related bugs that all coincided in a single regional map. I really hate lakes. I've also made a few more refinements along the way that are too minor to detail.
A couple of recent screenshots:
Anyway, what this means is that I've pretty much finished this stage of Undiscovered Worlds. As I said a million years ago, I envisaged a long-term project in three stages:
- terrain generation
- flora and fauna generation
- civilisation generation
I don't know whether I'll ever get to (3) - and really it's the one that interests me the least right now, especially as so many other people have done it so well - but I do think that (1) is pretty much done now. It's certainly not perfect but it's as good as I can plausibly get it, at least in the foreseeable future.
So I'd like to release this now. I'm planning on putting the source code up on GitHub so that anyone can tinker with it and make it better. I'd also like to make executable versions available so that less technically minded people can use it too. However, there are a couple of problems with this:
- The project uses several external libraries: NanoGUI, SFML, and stb_image. Somehow I've installed these in some eccentric way that allows my code to work fine on my computer, but I can't build an executable that will run anywhere else, because it won't incorporate at least some of these libraries. The fact that I can't manage what ought to be a fairly elementary part of development should indicate my skill level at this sort of thing.
- This project is written in C++ using Xcode on a Mac. Even if I manage to solve problem 1, I'll only be able to create an app that runs on Mac. It would be nice to be able to make it for Windows and Linux too, but I don't know how to do that.
SFML can be installed on the system or included as a git submodule. stb_image is header only and shouldn't have any other dependencies. I have no idea about NanoGUI. They all should be cross platform. I don't know anything about developing on a Mac, but it would probably build and run on Windows as long as you have the correct .lib and .dll files.
ReplyDeleteCreate a GitHub project and I'll take a look. I can create a Windows project file + build with MSVS 2022 if it's not too difficult. I can even create a linux build if you feel the need. As long as it doesn't take too much time or use anything MacOS specific. We'll see.
Thank you! Yes, it seems to be NanoGUI that's causing the problems (or more accurately, my ham-fisted installation of it).
DeleteAnyway, the code is now all on GitHub. Have a look here: https://github.com/JonathanCRH/Undiscovered_Worlds
I'd be very grateful for any help!
Code but no project files or anything? That could take some effort to set up. But if you say you made this in Xcode on a Mac, that won't help me build on Windows anyway. Let me see if I can create a Visual Studio project for this. At least it's a flat directory structure with only a few (very large!) source files.
DeleteYes, I think I set up my project wrongly, hence my difficulties. I thought it'd be easier simply to post the code so more knowledgeable people could set up a project correctly and copy them over!
DeleteOkay, first off, what do you need from the include of unistd.h? This is a POSIX header file and I don't know of a Windows equivalent. If you want the build to work on Windows, you probably can't use anything from here. I'm sure there's some way to wrap this and make it work, but it's probably outside the scope of what I'm willing to do right now.
DeleteIt looks like GLFW is also a dependency.
And nanogui is used all over the place across multiple files. The combination of 13K/21K line files with all the nanogui errors are giving MSVS trouble even parsing the file and getting correct syntax highlighting.
I appreciate you trying at least, so thank you, no worries if it looks too much of a headache!
DeleteI think Xcode includes unistd.h automatically - at any rate I removed it from the #include lists and it all still works fine, so it's not needed for this, thankfully.
I forgot about GLFW - yes, NanoGUI uses it, hence that dependency too.
Okay, I downloaded all four dependencies and I can attempt to compile. There are 112 compile errors and 1836 warnings. Some of the errors are:
Delete* Dozens of functions such as createislandtemplates() are declared as returning an int but have no return statement.
* This is not legal because you can't have a static array with a variable size: int windlines[12][n+1]; I see you have commented out uses of vector<> above some of these, why is that?
* Two errors related to sf::Vec2 that I don't understand and don't know how to fix, possibly incorrect usages of them
* There is an error that a static array is too large in size
* uint is undefined. Is that uint32_t?
What C++ standard are you using? I tried C++14, C++17, and C++20 and get somewhat different errors. Anyway, that's as far as I've gotten. I can attempt to fix some/all of these errors, but I'm not very confident I can fix it correctly. Do you have anything other than a Mac to compile on?
Also nanogui seems to depend on GLAD and NanoVG as well, so there are actually 6 dependencies.
DeleteAnd python as well? nanogui needs python, seriously? I'm not sure I really want to continue here, as I feel this will take tens of hours to get setup. I might be better off trying to do this in linux because I already have some of those dependencies installed on my dev machine. But I feel that most users here would be on Windows.
DeleteI installed python and can run it from a command prompt. But cmake in nanogui still claims it can't find python and exits with an error. You don't use python, do you? Maybe I can edit the cmake files to disable it.
DeleteFinally got it working! At least the GUI comes up. When I try to generate terrain it crashes with a stack overflow in createmountainrangetemplate(). I think the problem is that you have too many large static arrays of data in your various functions, and these are using too much stack space. I'm talking about the variables such as windlines[12][n+1] that are scattered around the code. This is bad practice. If you can change all of this style of code to allocate on the heap that would probably fix the stack overflow. It's too much work for me to fix.
DeleteI've made many code edits at this point. I have no idea what I've broken. How exactly do you want me to share what I've done? Create some new Git repo? Put a gzip file on Google Drive? Add some git pull request with a ton of changes?
Wow, thank you so much for persevering! I'm sorry to have given you such a morass to work through. You can see I need help!
DeleteMaybe it would be easiest to create a new Git repo, then I can basically clone that and make the needed further changes?
I wasn't as busy yesterday, but I'm busy with other things today. I'll get back to this when I have a chance.
DeleteQuestion: When you have lines like this, what are you intending to do?
Deletevector> fractal(ARRAYWIDTH,vector(ARRAYWIDTH,ARRAYHEIGHT));
Are you expecting this to create a 2D nested vector of size ARRAYWIDTH by ARRAYHEIGHT? That's not what this does. It creates a 2D vector of size ARRAYWIDTH by ARRAYWIDTH with the initial values of ARRAYHEIGHT. The two-parameter vector constructor takes (size, init_value). I see this in various places in the code and it looks wrong. I suspect the stack overflow is actually a memory write error.
I forked your repo and have it here:
Deletehttps://github.com/fegennari/Undiscovered_Worlds
I fixed some include problems, defined "uint", added missing return values, and replaced some stack arrays with std::vectors. I added a MSVS2022 subdirectory with project files and a .gitignore file.
It's still failing with a stack overflow in createmountainrangetemplate(). It looks like that function is some 4400 lines of nested case splits, so maybe Visual Studio can't compile it properly. I think you have to split that up into smaller functions before we can work past this failure on Windows.
Yes, it is meant to be ARRAYWIDTH*ARRAYHEIGHT - thank you for catching this!
DeleteAnd thank you for all your help with this. I really appreciate it. Now I can hopefully clean it up further.
Please start from my source files when you clean up the code so that I don't have to do a merge or re-apply my changes. Since your ARRAYWIDTH is larger than ARRAYHEIGHT, those errors are allocating extra data rather than accessing out of bounds data. However, there may be other cases that do access out of bounds in the many places where you create nested vectors. I'm not sure if the incorrect vector constructors are causing the stack overflow, or if the problem is due to the length of that one function. I might try to increase the stack size tonight if I can figure out how.
DeleteI was able to increase the stack size to 8MB in the linker settings and get past the stack overflow. There are two more exceptions thrown somewhere in string processing that are likely some sort of code bugs. If I run through the debugger and continue (ignore the exceptions) then I can get it to run and show me a map. What's interesting is that I don't see these two exceptions in the debug build, but it takes forever to generate the map.
DeleteI went through and fixed most of the Visual Studio warnings, and committed the changes to my repo. Feel free to review these to see if they look correct. There were an awful lot of "&" that should have been "&&", incorrectly placed parentheses, uninitialized variables, questionable mixing of int/float/bool in math and comparisons, statements with no effect, incorrect uses of 2D nested std::vectors, etc. This is the benefit of using a second compiler that will print a different set of warnings. I would guess there were at least 30 real bug fixes in there.
DeleteSadly, none of that fixes those two errors I'm getting in the debugger. They appear to be memory corruption where something is writing off the end of an array, or something like that. I have no idea how to fix them. I can't create a Windows build because there's no way to get past those errors without stepping over that code in the debugger.
Please let me know if you would like to move this discussion somewhere else. Email? GitHub issues?
DeleteI still haven't gotten the Windows release build to run without randomly crashing most of the time. It seems to be a nanogui problem, or at least it's related to the UI startup.
DeleteI did get the linux build to work with only about an hour of effort and it doesn't seem to crash.
Oh, oh, I had no idea of your plans for this - I assumed it was maps and maps only. Do you mean to say you're about to figure out how to step into these maps and explore them? That got me so excited. If so, I'm curious about a couple of things - how long does it take to create a new map at this stage? And what kind of data are you storing, which can be utilized to build the explorable world? Bonus points if answer is 'nothing', with only some seed values to look up data as needed. :) As much as I'd like to help you, with your current issues, I have no experience (compilers and libraries), sorry. Congratulations on acing the first step, can't wait to see what you come up with for ecosystems!
ReplyDeleteThank you for such a nice comment! The creation time varies, but I find that it takes about four minutes to make an entire world, and about twenty seconds to make a regional map like the first two in this post. Larger maps at the regional scale take longer, of course.
DeleteThe program stores a lot of data about the world: terrain elevation, wind direction, rainfall (summer and winter), temperature (summer and winter), river flow direction and size (also summer and winter), climate type, etc. This is all for the global map, which is low on detail - 1 pixel is approximately 16km.
When you zoom in to view a regional map, where 1 pixel is approximately 1km, it creates all that data for the region you're looking at, too - based on the broader-brush data it pulls from the relevant part of the global map. But this regional data isn't stored permanently. If you move to a different part of the world to view a different region, it will delete the previous region and create the new one from scratch. Since it's all procedural, you can go back to an earlier one and it will recreate it exactly the same, so it maintains the illusion of an enormous and detailed world that you can move around.
Don't get too excited about the prospect of stepping into the maps - anything like a 3D or first-person perspective is well beyond me, at least for now. But what I do want to do is focus on teaching the program to create new animal and plant species to populate the world with, so that the information about any point on the map will also include information about the ecosystems found there.