Getting dependencies set up in C++ is pretty much always an onerous process, so don't worry if you find it difficult; just stick through it.
Thank god, it really felt like I was doing something wrong. Thanks for the advice, I'll work on PDCurses then. When I was futzing with Python ages ago, I used ncurses, which seems similar in its abilities.
-snip-
There's a lot here, and I don't understand all of it, but I appreciate the wealth of knowledge here and the advice.
Well boiling that down into some practical advice -
in C++ you have two main types of files, ,cpp files and .h files. Each cpp file is a separate compilable entity. The .h files are shared stuff.
You "include" the .h file in one or more cpp files so that both files have those definitions. But the downside is that if the .h file needs to change, then all .cpp files that include that .h file also need to change.
So if you have a class defined inside the .h file used by several .cpp modules, then any change at all to that class means all the modules need to be rebuilt, because they all include that code. The solution is to push as much of the internal details into one .cpp or another, then strip down the class in the .h file to the bare-bones "need to know" stuff.
For example, you might have a Terrain class for storing a terrain height map, and this also has information about rendering the terrain in it. You then put that in a .h file and #include it for every cpp file that needs to do anything with terrain. The problem is that any change to the class definition for Terrain now requires all dependent code to be recompiled. Which gets quite slow as the project grows.
So, you can now ask,
why does each module need to know about the "Terrain Object" at all? That TerrainObject might have a "GetHeight(x,y)" method, and one cpp file calls it thus: "TerrainObject->GetHeight(PlayerX, PlayerY)". So, what you can do instead is just make a different .h file and put a function header in there "float TerrainGetHeight(float X, float Y)", which is then properly defined in another .cpp file. Then, that cpp file that
used to have access to the entire TerrainObject, and thus was compile-dependent on it, now only knows about that one single function it needs. it no longer needs to know that there is such a thing as "TerrainObject", thus the dependency has been removed, and you can now have the Terrain module define the TerrainGetHeight function whichever way you like. The details are now hidden from the other cpp files.
This also helps with self-documentation and making the program simpler to understand. For each .cpp file, you make a matching .h file, and you can put at the start of it "extern" links for all functions it needs to be able to access from different modules. Then you could just look at the .h file for that module and know which specific bits from other modules it uses, rather than #including the
entire other module and only guessing as to which features this module is using.