oakes / play-clj

A Clojure game library
The Unlicense
939 stars 73 forks source link

What if I have my custom built entity system? #39

Closed ysmolski closed 10 years ago

ysmolski commented 10 years ago

Hello! Thanks for the work on this awesome lib. I did small toy project on it and it was nice and clean.

But then I have decided to do my custom object for managing Entity-components system, maps, etc. Everything is stored in big hash-map. My whole game logic does work fine, but it's completely not fitting concept of play-clj entities which are placed in the vector.

Is there a clean way to ignore vector based entities concept of play-clj and fit the other parts easily? E.g rendering part troubling me.

It would be awesome to have this kind of functionality in play-clj as optional since vector based entities system imposing some limitation on performance when I have about thousands of entities in the system...

Thanks again!

oakes commented 10 years ago

Someone asked me a similar question and I posted some code showing how you can store entities in a map. Let me know if that works well for you.

oakes commented 10 years ago

I will close this for now but let me know if the solution I linked to doesn't work for you.

ysmolski commented 10 years ago

Thank you very much! That gave me idea to implement my own renderer function quite easily using libgdx objects directly. Also I like how you wrapped some of object like BitmapFont or TextureAlias into handy wrappers (though for Texture class I would have to use (import) it directly b/c play-clj "texture" wrapper is for TextureRegion. Correct me if I am wrong.

oakes commented 10 years ago

Yes, texture wraps TextureRegion because that is it must be in order to be drawn. However, you can get the underlying Texture object like this: (texture! (texture "player.png") :get-texture)

ysmolski commented 10 years ago

Ah... Seems I understood TextureRegion incorrectly. It's used for speeding up rendering because only one image is used instead of many and small regions are selected out from it.

Another question: is it okay to use draw-entity! from my own rendering function or it should be avoided as some internal function which might change in future?

oakes commented 10 years ago

Technically it's an internal function but you can use it if you need to. Why do you need to make a custom rendering function?

ysmolski commented 10 years ago

Okay, here is the situation.

Think of Dwarf Fortress. I have a tiled map which is dynamic and can be changed during the game. Cells are stored in the vector of vector and each cell has some "content". Also I have many entities representing "dwarves". "dwarves" are stored in EntityComponentSystem as hashes in some other hashes with some components. My plan is to make rendering function which:

Ordering of drawing is determined by game's logic and I might have up to 150 dwarves :)

All images will be placed on one big image and draw smaller regions of it. The most troubling part is that I have small cells (16x16 px) and thus many cells should be displayed on the screen. I do it via SpriteBatch as LibGDX manual recommends and I display two kinds of textures and layer with text on top of it for 1920x1080px screen. But FPS is about 45 on modern hardware.

I was thinking about storing all my state in my ECS structure, while rendering function will be reading it and iterating over specific sets of data, making calls to SpriteBatch, rendering stuff on the screen.

So the most expensive operation is to draw all those 5000k cells each frame. And I am not sure where is the bottleneck.

Sorry for so many words :)

oakes commented 10 years ago

Is there a reason you don't just use the built-in tiled map functionality? It allows you to change cells at runtime.

ysmolski commented 10 years ago

Haven't considered it yet. :smile:

One cons against it that my world logic is fully functional and all data is in the persistent structures. Tiled maps might require me to rethink my world or make mechanism to sync tiled maps with the world.

Do you think performance of tiled maps would be much better that just rendering tiles one by one? If so I might give it a try.

oakes commented 10 years ago

I think it would be faster, but I don't know by how much. I don't know where the performance issue is with your current code. You should definitely make sure you have your sprites in a single sprite sheet, if you aren't doing that already.