Help finding system for grid based building system capable of free rotation

Darcanlos

Member
Hi all,

I need help on finding the best system for a grid based building system for a ship that later needs to move and rotate as a single entity. I'm trying to find out what would be the ideal system before starting with it so I don't lose too much time programming stuff that I might have to redo later on from scratch because I chose the wrong approach.

I'm right now just doing an editor for building a ship piece by piece through a grid system. This ship and all it's components later need to move together as one single object, capable of rotating in any direction. I'm trying to figure out what's the best way to approach this. I've been looking into different options, but can't really conclude what would work best at the end. My guess is ds_grid, but I'm not sure how easy is it going to rotate everything later on.

During runtime I would still need to access each part of the ship individually if needed to apply damage to parts or make modifications to that part, but the basic structure of the ship would remain the same once out of the editor.

Any ideas greatly appreciated and thanks in advance!
 

NightFrost

Member
Yes you could use a grid, though that leaves empty cells. Another approach would be an array or a struct, storing the pieces in linear fashion; in this case each piece would contain data which other pieces it connects to. For example examining the contents of fifth ship piece would reveal it connects to ninth piece in north direction and thirteenth piece in west direction. The most important part is to construct a standard format to store data for ship pieces. This lets you loop through them and easily discover relevant data from each stored piece, whatever it might be you need at the time (like its appearance).

Rotating the ship on screen is a visual thing and storage method has no real relevance to it. When you have a ship design, you can draw it unrotated to surface, then rotate it by appropriate amount as you draw to screen. Also, redrawing the ship every step would be an inefficiency; you'd redraw the surface only when ship's visual appearance needs updating (ie you'd set some flag variable when damage gets done, then later check that flag and redraw if necessary).
 

TheouAegis

Member
Don't be afraid to try thinking outside the box (although it's likely by now the box is larger than you realize after other people have expanded it).

A ds_grid with all its empty spaces would be fine if the ship will have a size limit. Is it optimal? Not when the ship is small, but once the ship is built to max size, the amount of memory required and time to read the grid will be the same as any other data structure. All you would be doing is preallocating memory and forcing GM to look over all that memory. The gain from this is the column and row of a cell will directly correlate to the x and y of a ship part. This is probably the most beginner-friendly, I would think. The caveat is if a part of the ship occupies multiple cells, you would need to to devise a system to keep track of which cells have which fragments of which parts. That ain't complicated, but ramps things up to novice level.

You could use an unsized array of arrays. The primary index (the number immediately after the name of the variable) is inconsequential. You just need a simple incrementing variable to keep track of which index to write to, and a simple FOR loop to read it. Since you would not have a 1:1 coordinate correlation anymore, you would need to store the x and y coordinates of each part in one or more subindexes. If memory management is a concern for you you could reduce x and y to x' and y', where x' is defined by x divided by the cell width and y' is y divided by the cell height, then concatenate the bits (e.g., yprime*1024+xprime, where xprime can only be less than 1024). Parts of the ship with varied sizes would be somewhat trivial. If the part has one size, you don't even need to define it, as the part's ID itself should dictate the size. If the size is user-defined, you could store the size in another subindex.

YOu could even keep it all in a simple 1D array (at the cost of processing speed) using some bitmasking. For example, if x' is less than 1024 and y' is less than 512, and a part could have up to 4 different sizes (defined by the range {0,3}), your data blob per index could be ((PartID*4+size)*512+yprime)*1024+xprime. But now we're just getting into fluff. (BTW 1024x512 would be a very big ship).

You could draw every part individually rotated and positioned using trig functions, but since the parts themselves wouldn't be changing every step, just their angle and position relative to the rest of the game world, rendering them to a surface as they are added or changed would boost the efficiency of the Draw event hundredfold. If you are going to have little people visibly running around on your rotated spaceship, you may want to consider rendering them to a separate surface which you do update every step so rotating everything together would be easier for you. However, some video cards don't like too much surface data for some reason, but that might be a rarity these days. When using surfaces, you could also consider using a surface buffer for the ship parts surfaces (not the tiny people surfaces) in tandem so if the surface is ever lost, you can just copy the buffer back into it.
 
Top