If I just have C++ and say SDL or Raylib, how do I structure game code to keep it scalable (ie not a huge mess when I add more levels, items, mechanics, etc)? I have been able to make very simple stuff but the moment I try to add to it, it always gets out of hand and I can’t really refactor it without starting fresh.
The game engine is the integration point for your content. If you’re running into architectural issues that require you to start afresh, it’s probably because you haven’t figured out the requirements for your game and the type of content it requires. For example, if you’re making a Super Mario clone, then it’s pretty easy to design an engine for it since you know exactly what the game will look like at the end. Like @boaratio suggested, don’t try making a generic off the shelf engine, which is something you’ll inadvertently do if you don’t know what game you’re making.
Then spend some time learning about game engine design. The book “Game Engine Architecture” by Json Gregory is a good introduction, and probably all you’ll need. It’s kind of short and doesn’t go super deep on anything, but it does give you good perspective on everything, and is a good jumping off point for everything else. This ebook also has good content: https://gameprogrammingpatterns.com/ (in particular, read the chapter on state machines)