Anyway I am the developer of rbSFML and while creating this I have a game as a side project for fun that I also use to verify that the binding is working as intended. Anyway I've reached a problem I would need an outside look on as my thought process has become stuck.
As I normally work with 3D and so on I thought it would be fun to see if I could make a game with fake 3D and build a game from that. That has already been solved and works just fine and efficiently. Problem I have to solve is that when the camera moves the order of the walls have to be rearranged so they draw over each other correctly(SFML doesn't allow the use of depth buffer). Since this is being done in Ruby it's pretty slow. As soon as the rebuild runs the update time spikes and this builds linearly with the amount of walls I have. Currently the spike isn't that big, just takes Ruby around 1000 microseconds to build the walls you see on the image.

But that's only 28 walls. The plan is to have a big and vivid world filled with this. So let's say worst-case scenario is a big city with large buildings so at any given time we might have around 500 walls showing on the screen. That would result in around 17.8 milliseconds of thinking time and resulting on less than 60 FPS on my hardware which is all of the latest. Of course that's not acceptable as it won't work as the development progresses. What I want is solutions in how to make this work better, I am out of ideas.
class TileArea def rebuild_wall_vertexes(camera_position) for layer in @wall_vertex_arrays layer.clear end for wall in @walls rect = wall.display_rect min_tex = wall.type.texture_offset max_tex = SFML::Vector2.new(min_tex.x + WallType::Size.x, min_tex.y + WallType::Size.y) layer = @wall_vertex_arrays[wall.position.z] wall.sort_directions(camera_position) for direction in wall.directions case direction when :south then layer.append(SFML::Vertex.new([rect.left, rect.top + rect.height], [min_tex.x, min_tex.y])) layer.append(SFML::Vertex.new([rect.left, rect.top + rect.height], [min_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top + rect.height], [max_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top + rect.height], [max_tex.x, min_tex.y])) when :north then layer.append(SFML::Vertex.new([rect.left, rect.top], [min_tex.x, min_tex.y])) layer.append(SFML::Vertex.new([rect.left, rect.top], [min_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top], [max_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top], [max_tex.x, min_tex.y])) when :west then layer.append(SFML::Vertex.new([rect.left, rect.top + rect.height], [min_tex.x, min_tex.y])) layer.append(SFML::Vertex.new([rect.left, rect.top + rect.height], [min_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left, rect.top], [max_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left, rect.top], [max_tex.x, min_tex.y])) when :east then layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top], [min_tex.x, min_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top], [min_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top + rect.height], [max_tex.x, max_tex.y])) layer.append(SFML::Vertex.new([rect.left + rect.width, rect.top + rect.height], [max_tex.x, min_tex.y])) end end end end end class Wall def sort_directions(camera_position) position_x = @position.x * WallType::Size.x + WallType::Size.x / 2 position_y = @position.y * WallType::Size.y + WallType::Size.y / 2 if(camera_position.y > position_y && (@directions.first == :south || @directions.last == :north)) @directions.reverse! elsif(camera_position.y < position_y && (@directions.last == :south || @directions.first == :north)) @directions.reverse! end end end
The rebuild method is only called when needed and even only on specific intervals. The vertex code can be optimized with not clearing and reusing the already in place vertexes but it doesn't give much(I tried but there is a visual bug in rbSFML that will be fixed soon and then I'll apply it). As far as I can see I need an architectural change in order to make the better of this. Any crazy idea is accepted. Keep in mind I am only interested in a solution for the walls visible on screen.
I have backup solutions but I would like to try and not do them as they are more or less just brute-forcing by providing more power instead of actually solving the problem.






