how best to structure/manage hundreds of 'in-game' characters?
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I've been making a simple RTS game, which contains hundreds of characters like Crusader Kings 2 in a Unity. For storing them the easiest option would be to use scriptable objects, but that isn't a good solution as you cannot create new ones at runtime.
So I created a C# class called "Character" which contains all data. Everything is working fine but As game simulates it constantly creates new characters and kill some characters(As in-game events happen). As game continuously simulates it creates 1000s of character. I added a simple check to make sure character is "Alive" while processing its function So it helps performance but I can't remove "Character" if he is dead because I need his info while creating the family tree.
Is list is the best way to save data for my game? Or it will give problem once there are 10000s of a character created. One possible solution is to make another list once list reaches a certain amount and move all dead characters in them
unity c#
add a comment |Â
up vote
1
down vote
favorite
I've been making a simple RTS game, which contains hundreds of characters like Crusader Kings 2 in a Unity. For storing them the easiest option would be to use scriptable objects, but that isn't a good solution as you cannot create new ones at runtime.
So I created a C# class called "Character" which contains all data. Everything is working fine but As game simulates it constantly creates new characters and kill some characters(As in-game events happen). As game continuously simulates it creates 1000s of character. I added a simple check to make sure character is "Alive" while processing its function So it helps performance but I can't remove "Character" if he is dead because I need his info while creating the family tree.
Is list is the best way to save data for my game? Or it will give problem once there are 10000s of a character created. One possible solution is to make another list once list reaches a certain amount and move all dead characters in them
unity c#
One thing I've done in the past when I need a subset of a character's data after its demise is to create a "tombstone" object for that character. The tombstone can carry the information I need to look up later, but it can be smaller and iterated less often because it doesn't need constant simulation like a living character.
– DMGregory♦
1 hour ago
en.wikipedia.org/wiki/Object_pool_pattern
– Evorlor
2 mins ago
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I've been making a simple RTS game, which contains hundreds of characters like Crusader Kings 2 in a Unity. For storing them the easiest option would be to use scriptable objects, but that isn't a good solution as you cannot create new ones at runtime.
So I created a C# class called "Character" which contains all data. Everything is working fine but As game simulates it constantly creates new characters and kill some characters(As in-game events happen). As game continuously simulates it creates 1000s of character. I added a simple check to make sure character is "Alive" while processing its function So it helps performance but I can't remove "Character" if he is dead because I need his info while creating the family tree.
Is list is the best way to save data for my game? Or it will give problem once there are 10000s of a character created. One possible solution is to make another list once list reaches a certain amount and move all dead characters in them
unity c#
I've been making a simple RTS game, which contains hundreds of characters like Crusader Kings 2 in a Unity. For storing them the easiest option would be to use scriptable objects, but that isn't a good solution as you cannot create new ones at runtime.
So I created a C# class called "Character" which contains all data. Everything is working fine but As game simulates it constantly creates new characters and kill some characters(As in-game events happen). As game continuously simulates it creates 1000s of character. I added a simple check to make sure character is "Alive" while processing its function So it helps performance but I can't remove "Character" if he is dead because I need his info while creating the family tree.
Is list is the best way to save data for my game? Or it will give problem once there are 10000s of a character created. One possible solution is to make another list once list reaches a certain amount and move all dead characters in them
unity c#
unity c#
asked 3 hours ago
paul p
1975
1975
One thing I've done in the past when I need a subset of a character's data after its demise is to create a "tombstone" object for that character. The tombstone can carry the information I need to look up later, but it can be smaller and iterated less often because it doesn't need constant simulation like a living character.
– DMGregory♦
1 hour ago
en.wikipedia.org/wiki/Object_pool_pattern
– Evorlor
2 mins ago
add a comment |Â
One thing I've done in the past when I need a subset of a character's data after its demise is to create a "tombstone" object for that character. The tombstone can carry the information I need to look up later, but it can be smaller and iterated less often because it doesn't need constant simulation like a living character.
– DMGregory♦
1 hour ago
en.wikipedia.org/wiki/Object_pool_pattern
– Evorlor
2 mins ago
One thing I've done in the past when I need a subset of a character's data after its demise is to create a "tombstone" object for that character. The tombstone can carry the information I need to look up later, but it can be smaller and iterated less often because it doesn't need constant simulation like a living character.
– DMGregory♦
1 hour ago
One thing I've done in the past when I need a subset of a character's data after its demise is to create a "tombstone" object for that character. The tombstone can carry the information I need to look up later, but it can be smaller and iterated less often because it doesn't need constant simulation like a living character.
– DMGregory♦
1 hour ago
en.wikipedia.org/wiki/Object_pool_pattern
– Evorlor
2 mins ago
en.wikipedia.org/wiki/Object_pool_pattern
– Evorlor
2 mins ago
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
2
down vote
There are three things you should consider:
Does it actually cause a performance problem? 1000s is, well, not many actually. Modern computers are awfully fast and can handle a lot of stuff. Monitor how much time character processing is taking and see whether it's actually going to cause a problem before worrying too much about it.
Fidelity of currently minimally active characters. A frequent mistake of beginner Game Programmers is to obsess over precisely updating off-screen characters in the same way as on-screen ones. This is a mistake, no-one cares. Instead you need to seek to create the impression that off-screen characters are still acting. By reducing the amount of update characters that are off-screen receive you can dramatically increase processing times.
Consider Data-Oriented-Design. Instead of having 1000 character objects and calling the same function for each, have an array of the data for the 1000 characters and have one function loop over the 1000 characters updating each in turn. This kind of optimisation can dramatically improve performance.
add a comment |Â
up vote
1
down vote
When you have a large amount of data to handle and not every data-point is represented by an actual game object, then it is usually not a bad idea to forego Unity-specific classes and just go with plain old C# objects. That way you minimize overhead. So you seem to be on the right track here.
Storing all characters, living or dead, in one List (or array) can be useful because the index in that list can serve as a canonical character ID. Accessing a list position by index is a very fast operation. But it might be useful to keep a separate list of the IDs of all living characters, because you will likely need to iterate those far more often than you will need the dead characters.
As your implementation of your game mechanics makes progress, you might also want to look at what other kind of searches you perform the most. Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries. Just remember that each of them must be kept up-to-date. This requires additional programming and will be a source of additional bugs. So only do it if you expect a notable performance increase.
CKII "prunes" characters from its database when it deems them as unimportant to save resources. If your pile of dead characters consumes too many resources in a long-running game, then you might want to do something similar (I don't want to call this "garbage collection". Maybe "respectful incremator"?).
If you actually have a game object for every character in the game, then the new Unity ECS and Jobs system might be useful to you. It is optimized for handling a large number of very similar game objects in a performant way. But it forces your software architecture into some very rigid patterns.
By the way, I really like CKII and the way it simulates a world with thousands of unique AI-controlled characters, so I am looking forward to playing your take on the genre.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
There are three things you should consider:
Does it actually cause a performance problem? 1000s is, well, not many actually. Modern computers are awfully fast and can handle a lot of stuff. Monitor how much time character processing is taking and see whether it's actually going to cause a problem before worrying too much about it.
Fidelity of currently minimally active characters. A frequent mistake of beginner Game Programmers is to obsess over precisely updating off-screen characters in the same way as on-screen ones. This is a mistake, no-one cares. Instead you need to seek to create the impression that off-screen characters are still acting. By reducing the amount of update characters that are off-screen receive you can dramatically increase processing times.
Consider Data-Oriented-Design. Instead of having 1000 character objects and calling the same function for each, have an array of the data for the 1000 characters and have one function loop over the 1000 characters updating each in turn. This kind of optimisation can dramatically improve performance.
add a comment |Â
up vote
2
down vote
There are three things you should consider:
Does it actually cause a performance problem? 1000s is, well, not many actually. Modern computers are awfully fast and can handle a lot of stuff. Monitor how much time character processing is taking and see whether it's actually going to cause a problem before worrying too much about it.
Fidelity of currently minimally active characters. A frequent mistake of beginner Game Programmers is to obsess over precisely updating off-screen characters in the same way as on-screen ones. This is a mistake, no-one cares. Instead you need to seek to create the impression that off-screen characters are still acting. By reducing the amount of update characters that are off-screen receive you can dramatically increase processing times.
Consider Data-Oriented-Design. Instead of having 1000 character objects and calling the same function for each, have an array of the data for the 1000 characters and have one function loop over the 1000 characters updating each in turn. This kind of optimisation can dramatically improve performance.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
There are three things you should consider:
Does it actually cause a performance problem? 1000s is, well, not many actually. Modern computers are awfully fast and can handle a lot of stuff. Monitor how much time character processing is taking and see whether it's actually going to cause a problem before worrying too much about it.
Fidelity of currently minimally active characters. A frequent mistake of beginner Game Programmers is to obsess over precisely updating off-screen characters in the same way as on-screen ones. This is a mistake, no-one cares. Instead you need to seek to create the impression that off-screen characters are still acting. By reducing the amount of update characters that are off-screen receive you can dramatically increase processing times.
Consider Data-Oriented-Design. Instead of having 1000 character objects and calling the same function for each, have an array of the data for the 1000 characters and have one function loop over the 1000 characters updating each in turn. This kind of optimisation can dramatically improve performance.
There are three things you should consider:
Does it actually cause a performance problem? 1000s is, well, not many actually. Modern computers are awfully fast and can handle a lot of stuff. Monitor how much time character processing is taking and see whether it's actually going to cause a problem before worrying too much about it.
Fidelity of currently minimally active characters. A frequent mistake of beginner Game Programmers is to obsess over precisely updating off-screen characters in the same way as on-screen ones. This is a mistake, no-one cares. Instead you need to seek to create the impression that off-screen characters are still acting. By reducing the amount of update characters that are off-screen receive you can dramatically increase processing times.
Consider Data-Oriented-Design. Instead of having 1000 character objects and calling the same function for each, have an array of the data for the 1000 characters and have one function loop over the 1000 characters updating each in turn. This kind of optimisation can dramatically improve performance.
edited 22 mins ago
Philipp
74.1k19171223
74.1k19171223
answered 25 mins ago
Jack Aidley
648311
648311
add a comment |Â
add a comment |Â
up vote
1
down vote
When you have a large amount of data to handle and not every data-point is represented by an actual game object, then it is usually not a bad idea to forego Unity-specific classes and just go with plain old C# objects. That way you minimize overhead. So you seem to be on the right track here.
Storing all characters, living or dead, in one List (or array) can be useful because the index in that list can serve as a canonical character ID. Accessing a list position by index is a very fast operation. But it might be useful to keep a separate list of the IDs of all living characters, because you will likely need to iterate those far more often than you will need the dead characters.
As your implementation of your game mechanics makes progress, you might also want to look at what other kind of searches you perform the most. Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries. Just remember that each of them must be kept up-to-date. This requires additional programming and will be a source of additional bugs. So only do it if you expect a notable performance increase.
CKII "prunes" characters from its database when it deems them as unimportant to save resources. If your pile of dead characters consumes too many resources in a long-running game, then you might want to do something similar (I don't want to call this "garbage collection". Maybe "respectful incremator"?).
If you actually have a game object for every character in the game, then the new Unity ECS and Jobs system might be useful to you. It is optimized for handling a large number of very similar game objects in a performant way. But it forces your software architecture into some very rigid patterns.
By the way, I really like CKII and the way it simulates a world with thousands of unique AI-controlled characters, so I am looking forward to playing your take on the genre.
add a comment |Â
up vote
1
down vote
When you have a large amount of data to handle and not every data-point is represented by an actual game object, then it is usually not a bad idea to forego Unity-specific classes and just go with plain old C# objects. That way you minimize overhead. So you seem to be on the right track here.
Storing all characters, living or dead, in one List (or array) can be useful because the index in that list can serve as a canonical character ID. Accessing a list position by index is a very fast operation. But it might be useful to keep a separate list of the IDs of all living characters, because you will likely need to iterate those far more often than you will need the dead characters.
As your implementation of your game mechanics makes progress, you might also want to look at what other kind of searches you perform the most. Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries. Just remember that each of them must be kept up-to-date. This requires additional programming and will be a source of additional bugs. So only do it if you expect a notable performance increase.
CKII "prunes" characters from its database when it deems them as unimportant to save resources. If your pile of dead characters consumes too many resources in a long-running game, then you might want to do something similar (I don't want to call this "garbage collection". Maybe "respectful incremator"?).
If you actually have a game object for every character in the game, then the new Unity ECS and Jobs system might be useful to you. It is optimized for handling a large number of very similar game objects in a performant way. But it forces your software architecture into some very rigid patterns.
By the way, I really like CKII and the way it simulates a world with thousands of unique AI-controlled characters, so I am looking forward to playing your take on the genre.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
When you have a large amount of data to handle and not every data-point is represented by an actual game object, then it is usually not a bad idea to forego Unity-specific classes and just go with plain old C# objects. That way you minimize overhead. So you seem to be on the right track here.
Storing all characters, living or dead, in one List (or array) can be useful because the index in that list can serve as a canonical character ID. Accessing a list position by index is a very fast operation. But it might be useful to keep a separate list of the IDs of all living characters, because you will likely need to iterate those far more often than you will need the dead characters.
As your implementation of your game mechanics makes progress, you might also want to look at what other kind of searches you perform the most. Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries. Just remember that each of them must be kept up-to-date. This requires additional programming and will be a source of additional bugs. So only do it if you expect a notable performance increase.
CKII "prunes" characters from its database when it deems them as unimportant to save resources. If your pile of dead characters consumes too many resources in a long-running game, then you might want to do something similar (I don't want to call this "garbage collection". Maybe "respectful incremator"?).
If you actually have a game object for every character in the game, then the new Unity ECS and Jobs system might be useful to you. It is optimized for handling a large number of very similar game objects in a performant way. But it forces your software architecture into some very rigid patterns.
By the way, I really like CKII and the way it simulates a world with thousands of unique AI-controlled characters, so I am looking forward to playing your take on the genre.
When you have a large amount of data to handle and not every data-point is represented by an actual game object, then it is usually not a bad idea to forego Unity-specific classes and just go with plain old C# objects. That way you minimize overhead. So you seem to be on the right track here.
Storing all characters, living or dead, in one List (or array) can be useful because the index in that list can serve as a canonical character ID. Accessing a list position by index is a very fast operation. But it might be useful to keep a separate list of the IDs of all living characters, because you will likely need to iterate those far more often than you will need the dead characters.
As your implementation of your game mechanics makes progress, you might also want to look at what other kind of searches you perform the most. Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries. Just remember that each of them must be kept up-to-date. This requires additional programming and will be a source of additional bugs. So only do it if you expect a notable performance increase.
CKII "prunes" characters from its database when it deems them as unimportant to save resources. If your pile of dead characters consumes too many resources in a long-running game, then you might want to do something similar (I don't want to call this "garbage collection". Maybe "respectful incremator"?).
If you actually have a game object for every character in the game, then the new Unity ECS and Jobs system might be useful to you. It is optimized for handling a large number of very similar game objects in a performant way. But it forces your software architecture into some very rigid patterns.
By the way, I really like CKII and the way it simulates a world with thousands of unique AI-controlled characters, so I am looking forward to playing your take on the genre.
edited 1 hour ago
answered 3 hours ago
Philipp
74.1k19171223
74.1k19171223
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgamedev.stackexchange.com%2fquestions%2f164417%2fhow-best-to-structure-manage-hundreds-of-in-game-characters%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
One thing I've done in the past when I need a subset of a character's data after its demise is to create a "tombstone" object for that character. The tombstone can carry the information I need to look up later, but it can be smaller and iterated less often because it doesn't need constant simulation like a living character.
– DMGregory♦
1 hour ago
en.wikipedia.org/wiki/Object_pool_pattern
– Evorlor
2 mins ago