mjaun / android-anuto

Another ugly tower defense for Android
GNU General Public License v2.0
212 stars 68 forks source link

Ideas for battery life / performance improvements #141

Open mjaun opened 5 years ago

mjaun commented 5 years ago

Main issue for ideas to optimize the game performance.

Mannshoch commented 5 years ago

I do not know how to develop an app. But how do you handle the audio for a shoot? it sounds nice the first time but after a while i deactivate it. But does the sound also is not anymore calculated? because I do not see any difference if sound is active or not. On a huge amount of attackers the audio overhead may plays his part here.

zz-ha-dum commented 5 years ago

Disable UI after setting up level. Simply have lives totaled. Ui resumes for additional configuration

now the "game" is as much "fun" as a baseball game summary matrix in a newspaper.

blackboxlogic commented 5 years ago

Don't play audio if the device is muted (or volume is at 0).

rigao1981 commented 5 years ago

I would also propose not to display every little bullet once the game is accelerated.

easyaspi314 commented 2 years ago

In addition to my fixes in #200, here is an idea to improve the collision detection algorithm, which is the majority of the runtime on the logic thread.

The current approach to collision checking is pretty inefficient. The functional filter iterators are quite clever, but they still have to iterate through each element.

Healing, aiming, and glue are the largest bottlenecks in typical play. These check every entity every time they are applied, and that adds up quickly once you get to the hundreds of thousands of enemies.

image

Note that this is with #200 applied and measuring thread time. If you include sleeping, it is active 36% of the time.

One way of improving this would be to sort the entity map up by region to avoid even thinking about entities that are clearly not applicable. This could easily be done by splitting it via the visual grid.

Moving an entity would be slightly more complex as a case for moving between cells would need to be made.

image

Glue towers should be a special case. They are everywhere in current meta, and basically affect the floor only. Therefore, the map could theoretically be divided up into a (more fine than the rough hitbox) grid with each cell having a speed modifier.

easyaspi314 commented 2 years ago

To expand on the previous, I believe a decent data structure would be ArrayList<HashSet<Entity>>.

An iterator could use a set of cells to filter, and box an iterator for each HashSet, jumping to the next one if that is empty. Then, some function in this entity list class can use some math to find the possible cells for either a radius (e.g. aiming) or a vector (e.g. big laser).

private ArrayList... mEntities;
class FilteredEntityIterator ... {
    private ArrayList<Integer> mIndices;
    private int mIndicesPos;
    private Iterator<Entity> mCurrentSubIterator;
    public boolean hasNext() {
        if (mCurrentSubIterator.hasNext()) {
            return true;
        } else {
            // Set mCurrentSubIterator to the first mEntities[mIndices[mIndicesPos]]
            // that isn't empty, or return false
        }
    }
}

Something like this (only iterating the first few because I don't want to animate all those squares 😛) The yellow is mIndices, red is mIndicesPos, and green is mCurrentSubIterator.

Only 22% of the cells are checked, instead of all of them. 20220317_195734 (1).gif

The yellow box could probably be calculated using the Midpoint Formula and cached for towers.

This would improve performance even more than the tweaks I made in #200, as this would reduce the constant factor of collision checking greatly.

easyaspi314 commented 2 years ago

While collision detection is the biggest issue, here are some other performance issues I noticed.

Flame chart for resetting a large game: image image

mjaun commented 2 years ago

Thank you very much for your thorough investigations! Unfortunately I currently don't find time to do such refactorings on this project. But maybe somebody else will. I think the points you made do all make sense, especially since it is backed by your measurements.