ID:2231860
 
Hello in my game, because I do not want to decorate my maps manually, I made some code that will automatically apply cliffs and edges and such automatically on startup.

So I call this proc on EVERY turf on startup.

var/image/edge_image = image(icon = 'Edges6.dmi')

//check if a turf needs an "edge" and apply it as appropriate
GenerateEdges()
set waitfor=0
if(Water || density || !auto_edge || !edge_icon) return

var/list/ts = list(get_step(src,NORTH), get_step(src,EAST), get_step(src,WEST))
if(do_south_edge) ts += get_step(src,SOUTH)

for(var/turf/t in ts)
var/d = get_dir(src,t)
if(t.Water || (t.type == cliff_type && (d == EAST || d == WEST)))
switch(d)
if(NORTH)
edge_image.icon = edge_icon
edge_image.icon_state = "N"
overlays += edge_image
if(EAST)
edge_image.icon = edge_icon
edge_image.icon_state = "E"
overlays += edge_image
if(WEST)
edge_image.icon = edge_icon
edge_image.icon_state = "W"
overlays += edge_image
if(SOUTH)
if(do_south_edge && t.type != type)
edge_image.icon = edge_icon
edge_image.icon_state = "S"
overlays += edge_image


My question is how do I make it faster? It makes startup time ridiculously long. Thanks.
What are the slowest sections of this proc? I don't have much perspective on precisely where the slowdown primarily resides.
Ideally, you'd only call it for things that need it which you seem to have setup with the variable checks at the top.

The proc itself could be caching the changes to edge_image, so further usage of that exact change to it wouldn't result in further appearance churn. So instead of changing edge_image.icon and edge_image.icon_state every time (which generates overhead), you'd store the first result of that in a list and reuse that in places where appropriate.
The slowest part of this proc is that it's called for every turf at startup.
I probably should have asked if he had it being called for /turf or some child of it. If it's under /turf, then yeah, that's definitely the biggest issue. Doing anything under /turf is generally going to bite you in the ass as your game grows.
In response to Kaiochao
Kaiochao wrote:
The slowest part of this proc is that it's called for every turf at startup.

Any way around that? Any turf that fits these requirements (Water || density || !auto_edge || !edge_icon) could potentially need an "edge" depending on the turfs that border it
You'd want to put them in a child type specific for those conditions, so that things that will never need edges never have the proc called at all.
In response to Tens of DU
Is there a reason it must happen for all turfs at startup? Would it be safe to delay most if not all of the edge generation until it's actually necessary (i.e. when players are near for the first time)? I understand that all of the turfs may need this to happen at some point, but if you want to avoid ridiculously long startup times, then the best thing to do would be to not try to do it all at startup if you can.
Aside from Kaio's recommendation to delay/stagger this (which is wise), you could also setup the proc so it can loop through a list instead. If the proc isn't called once per turf, handling many more turfs per call, you drop a lot of proc call overhead.

Also it would be wrong of me not to point out that this method of handling edges via mulptiple overlays is not great. Better to have the appropriate multi-state icons.
Wow both good and easily doable ideas thanks.
I now generate the map by individual zones when that zone is occupied by a player and it works great. Thanks.
In response to Tens of DU
Awesome. If you haven't yet, I still suggest converting that proc to a loop so it isn't called once per turf. That way you get to do the calculation without all the proc call overhead, and the impact on the server when a player enters a new zone is even lower.