Game questions

I'm making a game engine with SFML and I had a few questions before I start writing my game.

My first question is when I'm loading sound and or music, is it better to load them when they are needed or do something else? My current system is that I have 1 file that has the name of the map, the tile sheet to load and the sounds and characters to load as well, so it looks like this:

Overworld.txt:OutsideTiles.png:AmbientMusic.ogg:SoundEffect1.wav:SoundEffect2.wav;

It separates the names then loads the files necessary, that way the game doesn't have to load everything at once, although i'm not sure if loading everything once would be better, it sound like it would be less stress on the game and computer but I dont know. I plan on playing the sounds and music and animations on separate threads. But I don't know how many threads you can safely run at once. Lastly as for the map, I plan on making a top down adventure game, and thus there will be no screen loading unless the player goes into a building, so do I draw the entire huge map in one text file? That would seem kind of difficult but i dont know, can someone please clear these points up for me. Also for collision I am going to make a function that assigns collision to every object that is specified. I have a lot of things done. The map generator is done, and loading the player and player movement and animation is done but a bit buggy.
My first question is when I'm loading sound and or music, is it better to load them when they are needed or do something else?


Music can (and typically should) be streamed -- that is, loaded and decompressed as it's being played back.

You could also stream one-time use or excessively-long sound effects.

For sound effects that are going to be played frequently throughout the game, it's better to preload them and just keep them ready.


Now you probably shouldn't preload ALL your sound effects since that'd be a huge waste of memory. Instead, when the player gets within a certain range of an enemy or something, you can load all the sound effects that enemy would use. There are ways to cleverly unload sound effects that are no longer needed.


The easiest way to do this is with a "level" system. If you have clear cut levels, and are okay with having maybe a short loading screen between them... then you can preload everything the level is going to use (except BGM -- stream that) and not have to worry about it.

I plan on playing the sounds and music and animations on separate threads


Don't put things in separate threads unless you have a very good reason to. It severely complicates everything and you have to be vigilant of race conditions.

Playing sound effects and animation doesn't even particularly take a long time (playing a preloaded sound is practically instantaneous)... so you wouldn't even get a speed boost by doing this. In fact, with the necessary synchronization, this is more likely to slow the game down. Unless you are really, really clever about it.


Loading, on the other hand, is a candidate for running in a separate thread. Especially if you want on-the-fly loading without loading screens. Just be careful about race conditions and make sure SFML allows loading SFX in another thread.

But I don't know how many threads you can safely run at once


The limit is absurdly high. You are unlikely to reach it.

Though any more threads than the number of cores on the machine is kind of a waste, and again, is more likely to harm performance than help it.

Lastly as for the map, I plan on making a top down adventure game, and thus there will be no screen loading unless the player goes into a building, so do I draw the entire huge map in one text file?


That's one way. Depending on the size, you might want to split the map into "segments"... of say.... 1000x1000 pixel areas (for example). Then only keep segments that the player is in or near loaded (ie: load new segments on the fly).

Though you'd only need to do that if the map is so big that it becomes a memory drain having the entire thing loaded at once.



EDIT:

Most of this comes down to preload vs. on-the-fly load. That's really the crux of it.

Preload: Typically faster and easier, but uses more memory.
On-the-fly: Typically requires more computation power, more complex, but uses less memory.


If you want to get an idea.... try preloading everything first. Then if you find you are using way too much memory, then try being more creative about it. But if you have the memory available -- you might as well use it.
Last edited on
Ok, I see, now I plan on having a pretty huge map, but I don't want loading screens and I don't want to write it all in one text document, I can load the other map with no problem, but how will I be able to make it seamless? I want it to be like Pokemon where you can keep walking with no teleporting(unless you go into a building) but I dont want something like Zelda for the NES where when you get to the edge of one screen you stop and the camera scrolls to the next screen.
Do the segment thing. Split your big map into smaller segments. And have ~4 segments loaded at a time. As the player moves around the map, swap out which segments are loaded. You can get away with on-the-fly loading if the loading is quick or if you put it in a separate thread.
So I would get the width and length of my current map and load the other one next to it? then I can unload the other ones that are off screen, and I'll just load the next map before the player sees it, so ok I can see how that will work. Im trying to figure out how to do it though lol, I'm new to SFML but I'm getting the hang of it really quickly, it's not hard at all. I'm having a little trouble understanding the map generator though, I understad it much better now but could you help me explain some of the code?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
while(getline(stream, value, ' ')) //Putting the contents of value in stream, what is the  ' ' for? what is that doing?
            {
                if(value.length() > 0)// if the file has anything in it
                {
                    string xx = value.substr(0, value.find(',')); //Starting a the beginning of the file, finding all ',' and storing them in xx
                    string yy = value.substr(value.find(',') + 1); //Finding ',' and storing them in yy

                    int x, y, i, j;
                    for(i = 0; i < xx.length(); i++)
                    {
                        if(!isdigit(xx[i])){break;} //Checking to see if any of the contents of xx were not digits
                    }
                    for(j = 0; j < yy.length(); j++)
                    {
                        if(!isdigit(yy[j])){break;}  //Checking to see if any of the contents of yy were not digits
                    }

                    x = (i == xx.length() ? atoi(xx.c_str()) : -1); // What are these two statements doing?
                    y = (j == yy.length() ? atoi(yy.c_str()) : -1);

                    gameVars.tempMap.push_back(sf::Vector2i(x, y)); // Push back the contents of x and y into vector to output later.
                }
            }



also this, I know it outputs the map to the screen, and I know mostly whats going on but what is:

1
2
3
4
5
6
7
8
9
10
11
12
for(int i = 0; i < gameVars.map.size(); i++)
    {
        for(int j = 0; j < gameVars.map[i].size(); j++)
        {
            if(gameVars.map[i][j].x != -1 && gameVars.map[i][j].y != -1) // -1? is that from the generator,  y = (j == yy.length() ? atoi(yy.c_str()) : -1); so if that equals -1 it wont draw anything?
            {
                gameVars.tiles.setPosition(j * 32, i * 32); // Set tiles 32 X 32 spaces apart each time.
                gameVars.tiles.setTextureRect(sf::IntRect(gameVars.map[i][j].x * 32, gameVars.map[i][j].y * 32, 32, 32));
                winVars.window.draw(gameVars.tiles);
            }
        }
    }

Last edited on
while(getline(stream, value, ' ')) //Putting the contents of value in stream, what is the ' ' for? what is that doing? The space is the delimiter for the std::getline function (by default it is a newline '\n' in this case it is a space. http://www.cplusplus.com/reference/string/string/getline/?kw=getline

Also your reading in of a tilemap looks a bit odd imo.

You could simply do something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::ifstream in("map.txt");

//rows and columns of map (number of tiles)
std::size_t rows = 0u;
std::size_t columns= 0u;

in >> rows >> columns;

std::size_t tile = 0u;
for(std::size_t row = 0; row < rows; ++row)
{
    for(std::size_t column = 0; column < columns; ++column)
    {
        in >> tile;
        //do what ever with the tile
    }
}



I think on SFML they actually have a tilemap tutorial.
http://sfml-dev.org/tutorials/2.1/graphics-vertex-array.php
I understad it much better now but could you help me explain some of the code?


?? You don't understand the code you wrote? Or are you using someone else's code?

Anyway, I'll do my best:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// getline will normally take one "line" from 'stream' and put it in 'value'.
// However, here we are giving it a space (' ') as a delimiter, so it will stop
//   at a newline or at a space.  IE:  if you have this in the file:
//
//   123,456 78,90
//
//  getline will take "123,456" from the file and then stop
/
// This while loop will repeat until EOF or until some other error happens
while(getline(stream, value, ' '))
{
    if(value.length() > 0)  // makes sure the line isn't empty
    {
        // 'find' gives the position of the first comma.
        //   substr breaks the string up based on the given position
        string xx = value.substr(0, value.find(','));  // everything left of the comma goes in xx
        string yy = value.substr(value.find(',') + 1); // everything right of the comma goes in yy

        int x, y, i, j;
        // This loop scans xx to make sure every character in it is a numerical digit.
        // If any character is not a digit, the loop will exit (via break).
        // Ultimately this means that i==xx.length() if and only if all characters are digits
        for(i = 0; i < xx.length(); i++)
        {
            if(!isdigit(xx[i])){break;}
        }
        // Ditto, but uses 'j' and yy.
        for(j = 0; j < yy.length(); j++)
        {
            if(!isdigit(yy[j])){break;}
        }

        // remember that i==xx.length if all characters are digits.
        //   So here... if all characters are digits, we convert them to an int.
        //   Otherwise (if any non-digits), we just use -1.
        //   -1 looks to be a special marker not to draw this tile.
        x = (i == xx.length() ? atoi(xx.c_str()) : -1);
        
        // ditto for y
        y = (j == yy.length() ? atoi(yy.c_str()) : -1);

        gameVars.tempMap.push_back(sf::Vector2i(x, y));
    }

@Giblet "The space is the delimiter for the std::getline function (by default it is a newline '\n' in this case it is a space."

So it just adds the whiteline to the stream?

As for reading the tilemap, I followed a tutorial on how to make it, I understand it now, pretty simple actually, I don't really think it's all that strange myself. I dont want to hard code any maps in the game. Right now im actually building the Engine that I will use for all my games. I got tiles working, basic movement, loading and displaying a cropped character with animation and made a clock to make it so he doesnt run so fast, and a few other small things. Collision will be hard, so i'm going to work on that right now.

But what about the rest of the stuff in my post?

@Disch, yes I followed a tutorial, I understand it the more I read it and I have an idea what all of it means but I want to be crystal clear on it so I dont make any future mistakes. Also thank you vbery much for explaining the code I understand it 100% now :D
Last edited on
I have another question that I wanted to ask before but I forgot, now I plan on having a function that loads sprites, so if I have 12 enemies on one map, in SFML you load the texture then set it to a sprite, so this is for the player character,

1
2
3
4
5
6
7
8
9
10
void LoadCharacter(WinVars &winVars, GameVariables &gameVars)
{
    if(!gameVars.playerTexture.loadFromFile("Resources/Characters/$Player.png"))
    {
        std::cout << "Error loading Player Character" << std::endl;
    }
    gameVars.playerSprite.setTexture(gameVars.playerTexture);
}

Can I just have 1 instance of sprite and texture for all 12 enemies? basically what i'm asking is how do I load the sprites for all characters without programming 12 different functions like this. Do I need to use a class? Right now everything is in structs because classes give me a headache, but when my engine is where it needs to be to be able to develope a game then everything that needs to be in a class will be, but most things are just variables, and so using a class would be a waste if i'm not doing anything other than getting a variable.
Can I just have 1 instance of sprite and texture for all 12 enemies?


Yes.

And in fact... you should have only 1 texture for all your enemies. You should never have the same texture loaded multiple times.

Sprites, on the other hand, are cheap and there's nothing wrong with having a bunch of them. One for each enemy is typical.

basically what i'm asking is how do I load the sprites for all characters without programming 12 different functions like this. Do I need to use a class?


You never NEED a class, but they can certainly make things easier.

What you want is a resource manager -- it could be a simple function (though you'd need a global map or unordered_map). The idea is you give the function an ID (like a filename) and it gives you back a reference to a loaded texture.

The thing is you will want EVERYTHING to use it. That way... since everything is going through the same function to load their textures, the function can check to see if the texture is already loaded... and if it is, it doesn't have to load it again... it can just give a reference to the existing texture.
So it just adds the whiteline to the stream?
nope, it is a delimiter. In other words it reads up into the character and discards that particular character. Guess you didn't read the reference link I linked you :(
Get line from stream into string
Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)).

The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.

If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it.

Each extracted character is appended to the string as if its member push_back was called.


Right now everything is in structs because classes give me a headache
ugh.. What you can do in a class you can do in a struct and vice versa. I could be wrong but AFAIK the only difference is the default access (class = private, struct = public).
"Guess you didn't read the reference link I linked you :(" Oh crap i'm sorry man I didnt even see it :( I will read through it though.

"ugh.. What you can do in a class you can do in a struct and vice versa."

I know, but I think of using classes more for stuff like polymorphism and advanced stuff and structs for just variables. I know I can do the exact same stuff with a struct, but eh.

"You should never have the same texture loaded multiple times."

What i'm talking about though is different textures and sprites, what if I have 12 different sprites and textures? can I still use the one function?
Last edited on
Also I was thinking instead of loading all the sounds at once, I can load all the file names and locations into vectors and call them when they are needed, will that work ok? My original plan was to load them from functions, but if Im concerned that when I use the one variable to get a character it will overwrite the other, I think a vector will solve this but idk. I've literally been up for 22 hours straight programming.
Last edited on
giblit wrote:
ugh.. What you can do in a class you can do in a struct and vice versa. I could be wrong but AFAIK the only difference is the default access (class = private, struct = public).


While this is technically true, on a conceptual level structs and classes are quite different. A struct is a collection of several small pieces, whereas a class is a singular thing that has complex parts.

std::string is a class because you treat them like they're strings... like they're a singular thing. You don't treat them as a collection of parts.

std::pair is a struct because it's nothing more than a grouping of 2 variables.

It's a stylistic difference, yes. And yes, you don't have to do things that way. But that's typically how they're perceived. At least in my experience.

Ch1156 wrote:
What i'm talking about though is different textures and sprites, what if I have 12 different sprites and textures? can I still use the one function?


Yes. The idea is the manager keeps track of things that are already loaded. If it's already loaded, it returns the object it already has. Otherwise, it loads it, then returns it.

Also I was thinking instead of loading all the sounds at once, I can load all the file names and locations into vectors and call them when they are needed, will that work ok?


Err... load the file names? File names are like 20 characters.... so they'll 'load' pretty much instantly. Yeah you could do that. But I might be misunderstanding you.

My original plan was to load them from functions, but if Im concerned that when I use the one variable to get a character it will overwrite the other


Every kind of big resource (textures, sound effects, etc) that you will need to load should be accessed through a resource manager as I previously described. It makes it easy and prevents you from loading the same resource multiple times unnecessarily.
"Err... load the file names? File names are like 20 characters.... so they'll 'load' pretty much instantly. Yeah you could do that. But I might be misunderstanding you."

Well what I was thinking is that by doing this I don't have to hard code it into the engine, I want to be able to basically almost be able to make maps, load characters and sound etc by just typing it into a text document, and so far its going very well.


"Every kind of big resource (textures, sound effects, etc) that you will need to load should be accessed through a resource manager as I previously described. It makes it easy and prevents you from loading the same resource multiple times unnecessarily."


I decided to use a function and a vector for loading characters, it works really well. I'll probably hard code the player stuff as that will never really chnage from game to game but I can use the vector to load charactersd and spawn them. I'm just trying to make the engine as re usable as possible and not trying to customize it to one game.
Last edited on
Well what I was thinking is that by doing this I don't have to hard code it into the engine, I want to be able to basically almost be able to make maps, load characters and sound etc by just typing it into a text document, and so far its going very well.
Doesn't mean you need to store all the filenames :P You could simply store what the texture is and the texture.

I'm just trying to make the engine as re usable as possible and not trying to customize it to one game.
I'd honestly suggest you make games not engines :P

If you really are making an "engine" I would suggest you do component based entity system like unity does and many other engines. It's very simple to use and to create entities.
"Doesn't mean you need to store all the filenames :P You could simply store what the texture is and the texture."

Oh wait haha I didnt mean the file names sorry, I mean the actual files themselves, for now I decided to separate the character sprite names, sound names, tile names etc into separate files until I come up with a better system. Right now im just focused on getting everything at least semi working. I have a vector that loads the characters, it gets the names from the file and then i append the name to a hard coded file directory that the assets are in. Maybe thats overly complicated idk, I've not had any sleep in 26 hours. As for the maps, I was thinking I could just load 2 maps in, 1 of them being on screen and the other being in memory and not assigned any textures yet, and then doing that . I have no idea how i'll place them i still need to figure that out.



As for the component based system, do you mean like for my engine making a tile editor where i can place tiles with the mouse and do other things without coding? cause if thats what you mean then yes i definetly am planning on doing that.
As for the component based system, do you mean like for my engine making a tile editor where i can place tiles with the mouse and do other things without coding? cause if thats what you mean then yes i definetly am planning on doing that.
That's not what I meant by a component based entity system. That is more of a grid system. A component would be say we have a character. He is made up of health (can take damage, can die), and a weapon (can deal damage), and some sort of movement (can walk). Basically each component will have core functions such as Update and Start there are possibly others like onMouseUp, onMouseEnter,onMouseExit, onCollisionEnter, onCollisionExit, and onCollisionStay then you would make them do nothing by default and make it a virtual function.
Topic archived. No new replies allowed.