Design Ambitious Strategy Game

D

Drazex

Guest
Hi,
I'm a fairly new programming hobbyist. I've already designed one simple game with GameMaker, and now am aiming for something more ambitious. My goal is to create a strategy game framework that I can build on and make more complex over time, for something that basically bridges the gap between Civilization and Stellaris, allowing for interaction with a living galaxy on multiple levels.

Right now I have the concept of what I want to do, but I'm having trouble figuring out what the best way to mechanically implement it would be, and also how to start. I'd love any and all advice on what would work best for the sake of end-user processing, keeping the potentially very complicated game elegant, etc.

So my opening questions:
(1) What would be the easiest/most elegant way to handle multiple map views? To reduce processing requirements, I was thinking it would make the most sense to have different "levels of resolution", with higher levels giving more summarized information (total production, etc.), and smaller levels having more detailed information (possibly to the point of regions of a few hundred square miles).

To handle this, I was considering using a section of the main room that would change based on the section selected, and have either a persistent "detail" view section in the UI, or create an object to display it. I'm considering that having object pop-up windows is probably better, especially so that multiple levels can be opened from each other, though I'm open to suggestions on the best way to handle this. Further, I would love any pointers (either directly, or pointers towards good tutorials) on creating an interactive view inside an object.

(2) What would be the most elegant way to store world variables? I'm planning to use very simple graphics to reduce the load on the computer, so I don't need to store any kind of meshes or textures to the save file. I was thinking of using nested arrays to store this information. Things like "sector[0,0]=world1, sector[1,0]=world2" where "world1[0,0]=province1, world1[1,0]=province2", etc. With 2D arrays, I could then store variables like terrain, production, etc.

Is this a good idea, or will this result in something unwieldy/unstable? Especially because I plan to procedurally generate the areas of each province, the provinces of each world, the worlds of each sector, and possibly go up to a larger level above that (eg, sectors in a galaxy); I'm not sure the best way to distinguish "province1 of world1" from "province1 of world2", for example.

Thanks for any and all help! Any advice in general is greatly appreciated!
 

andev

Member
If this is of high importance to you:
. I'd love any and all advice on what would work best for the sake of end-user processing, keeping the potentially very complicated game elegant, etc.
Then this is not a good place to start your decisions from:
To reduce processing requirements, I was thinking it would make the most sense to have different "levels of resolution"
(1) What would be the easiest/most elegant way to handle multiple map views?
In my opinion, hide the fact there are multiple views and make a single, dynamic camera that can seamlessly zoom in and out at any resolution.

(2) What would be the most elegant way to store world variables? I was thinking of using nested arrays to store this information.
This is what I do, but I'm not sure if its the most elegant! If you use macros, you can name each position for tidiness.

WorldSize = WorldArray[WA_WorldData,W_1];
WorldW = WorldData[WD_Width];
WorldH = WorldData[WD_Height]

And you'd have the following macros:
WA_WorldData = 0
WA_WorldEntities = 1
etc

WD_Width = 0
WD_Height = 1
WD_Trees = 2
WD_* etc

W_1 = 0
W_2 = 1
W_3 = 2
etc
 
D

Drazex

Guest
Thanks for your reply!

If this is of high importance to you ... Then this is not a good place to start your decisions from
I should clarify, when I say "reduce processing", I don't mean I want it to run on a potato. What I mean is just that I don't want to give a supercomputer problems. I plan on having a lot of variables as it increases in complexity over time, and I don't want the game to crash or become unplayable due to CPU burden.

As I said, I'm pretty new to game design, so I'm not sure how much most PC's can take. My line of thought before was that trying to calculate and display thousands of elements on a world map would be prohibitive, so it would make sense to only render one section at a time, such as only province info on a world, instead of the details that make up those provinces.

In my opinion, hide the fact there are multiple views and make a single, dynamic camera that can seamlessly zoom in and out at any resolution.
I really like that idea, though I'm not sure where to start with that. Are there any tutorials you would recommend on the subject? Most of the ones I've found so far are related to camera following rather than zooming in.

As for the basic logic of it, would that keep the entire main game in a single room? Would you just choose a given zoom level to despawn all the objects in the higher level, and spawn new objects for the lower level?

This is what I do, but I'm not sure if its the most elegant! If you use macros, you can name each position for tidiness.
Even if it's not the most elegant, it's good to know that my first thought wasn't completely off the mark! Also, thanks for the tip about the macros. That'll be really helpful for indexing the arrays.
 

andev

Member
I'm not sure how much most PC's can take.
Benchmark and test! Upload a demo project on the forums here, and ask people to share their rough specs and fps.

My line of thought before was that trying to calculate and display thousands of elements on a world map would be prohibitive, so it would make sense to only render one section at a time
Use tiles to render things that don't move for very little performance cost. Remember to spawn them in advance though!

Most of the ones I've found so far are related to camera following rather than zooming in.
Zooming in is as simple as changing the width/height of the camera/view. But this will appear to zoom in to the top corner.
upload_2018-2-16_16-30-50.png
So to make it move to the middle, you just have to take the amount you subtracted from the width, halve it, and add it to the x of the camera. Then do the same for the height and y.
 

Yal

🐧 *penguin noises*
GMC Elder
Andev gave some sound advice, I'll try to add some additional stuff:
  • You can compactify data using binary operations, if you need to store a bunch of true/false values you could store all of them in a single variable using |, ^ and & operations. But generally, your graphics and music will use a lot more RAM than your variables (you need several hundred thousand numeric variables to reach a megabyte memory footprint, OGGs easily reach a handful of megs each)
  • Data doesn't really waste any processing unless you operate on it, so try to do two things: don't operate on data more than you need, and spread out processing so you don't get spikes of a lot of stuff happening at once (alarms is a good way to do that in GM).
  • Spawning and destroying objects is pretty expensive in GM, it might be more efficient to have a single controller object that just draws the relevant stuff (it's pretty simple to loop over only the stuff that should be visible on screen in a grid, if you just can compute the top/left grid cell that's gonna be visible in the view)
  • I'd say having "area simplifications" is gonna be just as useful to make it easier mentally for the player to manage stuff as it is at saving CPU use, and it might result in a better game design if you consider the summarize-things-for-the-player / make-it-easier-to-make-broad-strokes-plans aspect first and the CPU aspect second (e.g. maybe add commands so the player can order all soldiers to train at once instead of having to go through 300 bastions and manually select it). Micromanagement is nice, but unnecessary busywork isn't; try to draw the line somewhere reasonable (and make sure to get people to test play, etc etc).
 

NightFrost

Member
And not to sound overly negative, but you need to undersand how complicated it can be to create a competent AI. Look at how braindead sector governance (same thing that runs AI empires) in Stellaris can be at developing planets, making super-baffling building choices (or building nothing at all), or how Federations pretty much just don't work. Or how in EU4 you can bait Ottoman's doomstack onto an island and trap them there with your fleet, the AI being unable to figure what just happened and what to do about it. I think Paradox has several people in house whose sole task is game AI.
 
D

Drazex

Guest
Thanks for all the replies!

As one note, I plan to make this game turn-based, for a number of reasons, not the least of which being personal preference. I think it'll also make it easier for the player to micromanage (as much as they want to), and also to reduce having to render too much change.

Use tiles to render things that don't move for very little performance cost. Remember to spawn them in advance though!
Oh, definitely! I was planning to use tile objects to represent each section, and try to use some simple, self-choosing sprites for each based on terrain/development/etc.

Zooming in is as simple as changing the width/height of the camera/view. But this will appear to zoom in to the top corner.
That makes a lot of sense. I was thinking in much more complicated ways.

But generally, your graphics and music will use a lot more RAM than your variables (you need several hundred thousand numeric variables to reach a megabyte memory footprint, OGGs easily reach a handful of megs each)
Thanks, this is a really useful benchmark! I was worried before after managing to lag my game with excessive objects in my previous project (due to a bug), but it sounds like that was probably because of the rendering of all those objects, rather than the existence of the objects themselves, right? (Though when I get back to gamemaker, this should be easy to check by generating a few hundred thousand instances of a spriteless object to check lag.)

Data doesn't really waste any processing unless you operate on it, so try to do two things: don't operate on data more than you need, and spread out processing so you don't get spikes of a lot of stuff happening at once (alarms is a good way to do that in GM).
With a turn-based system, ending a turn will probably cause a spike of lots of stuff happening at once, I'm afraid. In my personal experience, though, as a fond player of Space Empires, having a loading screen at the end of the turn while other actors moved never bothered me, so depending on what kind of benchmarks I get, I think this will probably be OK.

Spawning and destroying objects is pretty expensive in GM, it might be more efficient to have a single controller object that just draws the relevant stuff
I see, thanks for the tip! I was thinking about having objects in order to make it more interactive, but I could probably get the same effect by having the controller object itself compare the location of a mouse click to what it's rendering, right?

I'd say having "area simplifications" is gonna be just as useful to make it easier mentally for the player to manage stuff as it is at saving CPU use, and it might result in a better game design if you consider the summarize-things-for-the-player / make-it-easier-to-make-broad-strokes-plans aspect first and the CPU aspect second (e.g. maybe add commands so the player can order all soldiers to train at once instead of having to go through 300 bastions and manually select it). Micromanagement is nice, but unnecessary busywork isn't; try to draw the line somewhere reasonable (and make sure to get people to test play, etc etc).
Oh, definitely. Because I still don't have a lot of benchmark experience, my first concerns were toward having a framework that wouldn't break halfway through building it. From the advice I'm getting so far, that's probably not something I have to worry about too much, so I'll definitely be focusing my questions more on the user end than the computation end in the future.

One of my goals with this, which I understand is ambitious, is to create a bit of a living world. Assuming I can get that to work, my aim is that the player can then micromanage as much or as little as they want to, being able to take control of individual battles for territory, or just pointing their army at a country/planet and saying "conquer this".

And not to sound overly negative, but you need to undersand how complicated it can be to create a competent AI.
Good point, thanks! One advantage of being a hobbyist, is that I can shoot for the moon here, and nothing's really lost if it goes down in flames, lol. I realize that AI programming is hard, though. One of my goals is to try to create living worlds that operate a bit more on automatic interactions between resources and populations, so I'm hoping this focus on low-level decisions will help simplify the higher-level AI. I'm under no illusion that this will be quick or easy, though ^_^''
 

Morendral

Member
Very interesting! I myself am working on something a bit more in between civ and eu4, though it is a bit closer to civ and this sounds closer to the paradox type games. I'm glad I'm not the only one thinking along those lines!
 

Yal

🐧 *penguin noises*
GMC Elder
but it sounds like that was probably because of the rendering of all those objects, rather than the existence of the objects themselves, right? (Though when I get back to gamemaker, this should be easy to check by generating a few hundred thousand instances of a spriteless object to check lag.)
Existence probably slows down stuff too, but events you don't have code in don't get hooked up in the final executable, so it shouldn't be too much (it's probably more side-effects, like collision checks having to loop through more objects). Basically, your own code in step events and stuff like that is likely the biggest contributing factor to object overload slowdowns... but even small simple code's gonna easily add up if you have tons of objects. Everything has a draw event, though, so that can tend to add up processing costs - stuff like texture page swaps and having to clear the display buffer because you change blend modes gets a lot more common if you have tons of objects with different graphics.

I see, thanks for the tip! I was thinking about having objects in order to make it more interactive, but I could probably get the same effect by having the controller object itself compare the location of a mouse click to what it's rendering, right?
Yeah, and it's likely faster as well - just do a single math operation on the current mouse_x/mouse_y and you have the currently clicked grid cell, for instance. It could also be easier to handle priority this way, normally if you have your mouse over both a menu button and an object on the map screen both of them get mouse click events, and you need to figure out which object should actually do something. If you handle it via code, you'd check in descending priority order until you find the object you clicked on, or realize nothing was clicked, and then you can just abort the loop once you handle a click event.
 
Top