Breaking your engine/game...

Published December 03, 2014
Advertisement
It is a very long time since I last posted about gnoblins (almost 2 years). After a major shift in the game design and some major refactoring actions, I'm stablilzing the gameplay at the moment. I will present the result of all this refactoring/redesign in the future, for now I will write about my experience with the attempt to crash my own game engine...

From time to time I want to break my engine/game, pushing it to its boundary until it crashes or collaps. I think everyone should do it to learn more about its weaknesses. This shouldn't be too hard considering that my engine is a homebrew, hobby product. smile.png

Testcase:
My testcase is spawning lot of entities, all having their individual AI, movement, sensory scanning, pathfinding, animation etc. active. I want to spawn them in a single spot. This is important, because many systems, including mine, scale better with entities distributed evenly in the world. But if you pack them all in a single spot, you suddenly have very high context density, you need to render them all, you need to simulate them all etc.

Okay... Let's go smile.png

Level 1:
Task: Spawn 200 entities in a single spot.
Assumption: Crash !

Hey, it crashed, my assumption was right biggrin.png Better said, some asserts kicked in. I use almost no dynamic allocation once the game is running.
My engine design idea was: I will have enough memory, concentrate on performance first (and I dislike dynamic memory allocation and garbage collection). So, I needed to increase some constants.

Level 2:
Task: Yet, again spawn 200 entities in a single spot.
Assumption: Massive slow down..

It didn't slow down.. not a lot... well, partylaugh.png ... next step

Level 3:
Task: Spawn 1000 entities in a single spot.
Assumption: Massive slow down..

It didn't slow down...yeahhlaugh.pnglaugh.png ... WAIT...blink.png
Something is wrong huh.png . After watching the scene it didn't look like 1000 entities. *Facepalm* rolleyes.gif .. The entity pool is kicking in, reusing entities.
Taking a look at the pool size, only 70... atleast the system handles massives entities spawn in a robust way.happy.png

I increase the pool size to 1000.

Level 4:
Task: Spawn 1000 entities in a single spot.
Assumption: Massive slow down.. finally ?

Crashed again (asserts). The problem is, that I spawn 1000 entities in a single frame. Fixing some parameters and finally not crashing..

Level 5:
Task: Smaller steps, lets start with 250 entities
Assumption: Massive slow down.. finally version 2.0 ?

Yep, its slows down finally. Entities spawn and start moving... well atleast partly. It seems that only groups of entities start moving, group after group start to move. A second effect is, that almost all ignore an enemy entity standing next to them.huh.png

Well, every entity is able to start multiple (4 at the moment) scanning/pathfinding requests which are processed concurrently. If the entities does not receive the answer in ~1-2 seconds, it will timeout and restart the request. The issue seems to be, that some entities will timeout at first, starting a new request. Starting a new request removes the old one from the processing queue and adding the new one at the end. This seesm to result in starvation. Once the requests of the first X entities are through, the workload on the multithreaded pathfinder/scanner is reduced and the next group of entities will receive their response in time. I could make it more robust (instead of enqueue at the end, exchange the old request with the new one). but this isn't my requirement yet, so I leave it for now.ph34r.png

Level 6:
Task: Go for 400 entities
Assumption: Massive slow down..

Yep, it goes down. From 90-110 fps to 6-8 fps at first. Later it crawls to 0.6 fps at times. The problem is a spin down (longer frametimes => more processing per frame). This was expected. Every single entity scan its environment for other entities to do steering, it scans for threats, it scan for tasks to do, it tries to find a path to its goal, collision detection with the world (not with other entities), AI update method and behavior trees.

Woah... what happens... suddenly I got 50 fps ?blink.png Hmm...ahhh... all entities are dead now. The game tracks invading entity raids and cut them off after a few minutes to prevent a system collaps during long game sessions. At least it works and the rendering system seesm not to be the bottleneck.

Level 7:
Task: Final test with 100 entities only, which is more than the expected maximum number of active entities in a game session.
Hope: Acceptable slow down...hopefully

Yep, it works finally like a charm. All entities start to react immediatly, hacking down two minions and a bed. The game is stable at ~330 MB, ~80 fps, 30-50% CPU (quad core) with almost equal distribution on all 4 cores ( no core reaches its limits).

Conclusion:
I know, that a AAA engine is by far more powerful, but on the other hand it is really satisfying to see of what your own engine is capable of. There's enough potential for optimization left over, but eventually I'm really proud of result. biggrin.png
6 likes 1 comments

Comments

riuthamus

Glad to hear you posting again. It has been some time since we seen a blog from you! <3 I was watching your development for a bit and was excited to see you branch into greenlight and other areas.

I know the feeling of testing the engine. The other day we spawned 40+ mobs without any optimization and saw them all working without flaws. This was a rewarding experience and while others might have been bored I was very entertained. Good luck and keep posting status/changes.

December 03, 2014 02:48 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement