ID:1999512
 
(See the best response by Ter13.)
I have a turf (32x32 pixels) that shows, let's say, grass. Then, I have an image 8x8 pixels that shows a rock. I use that specific rock picture only once in the whole map. Do I make the rock image an object and place it above the grass turf or make the whole rock+grass a turf and place it on map? If I'd use that rock several times and above different kind of turfs then I'd define it as obj, but now? Is there any real difference between them two?

And also, if I have a box that is 32x32 pixels, do I define it as a turf or an object? Because if it is to be placed above a turf floor for example, that turf won't be shown.

Ty
Copy/Paste the rock into a .dmi file then overlay the rock over grass turfs.
It's best to make anything that doesn't cover a whole tile into an object to avoid weird overlay issues, and especially in this case, you'd definitely want an object.

Not only will it save you a ton of headache in the future, if you do decide you want to use that rock elsewhere, it'd be trivial to do so.

As for the box, boxes are interacted with, things that are interacted with on that level are usually best left as objects too.

The only things you should really be making into turfs are, well, turfs, dirt, grass, water.
What if the box isn't interacted with? Just part of the furniture. Do I make it an object or a turf?
Object
Best response
...Everything in this thread so far is wrong, BTW.

Alright, so the ol' turf/obj debate.

Yut Put lost this debate by making everything in Epic: Legend into an object so that he could do all kinds of crazy layering crap. It ground his project to a halt and murdered it. The more objects you have in the world at any given time, the worse your game is going to perform.

Not only that, but the more objects you have in the general view of the player, the more players you have, the worse performance is going to be.

I hate flow charts. Flow charts are hard. But here's a flow chart:

In response to Ter13
This is fantastic, saved!

I've long told people to not over-use objs, and nobody has ever taken me seriously, I'm so glad I can now KAPOW this in their face.
Here's a perspective from the guts of BYOND:

The turf map is very heavily optimized, built on the assumption that it's basically just scenery. The server gives clients a partial version of the turf map, with a lot of overflow, and only sends them new turfs after they stray close to the edge of the turfs they have. The check for this is done on each map tick. In old BYOND versions, any change to a turf's appearance caused their whole turf map to be resent, and since 505 it's only the turfs that changed. Turfs are extremely memory-efficient, extremely network-efficient (especially since 505), and extremely server-friendly.

Objs and mobs are handled in two separate routines, for Dream Seeker (the webclient optimizes a little). For every turf in actual view of the client plus a little overflow--but not as much overflow as the partial turf map--the server checks the contents of the turfs and tries to figure out if any of the objects there have changed, are new, or have been removed. Then it tells the client about those changes. Movables use more memory than turfs, and those in view have to be looped through on every map tick; therefore overuse of them can hurt performance.

Regarding the OP's question, if this rock is somehow significant to anything then I suspect it'd make a good obj. If it's just decoration, it should be a turf, with the turf "beneath" it as an underlay. Obviously the flowchart is the ultimate arbiter, as it takes things like pixel movement into consideration. General rule of thumb, though: Turfs are best for things that are pretty darn static.
General rule of thumb, though: Turfs are best for things that are pretty darn static.

Here's a little bit of code that can give you more milage:

area
Enter(atom/movable/o)
return o.density&&!density
static_area
density = 1

obj
static_obj
New()
if(loc)
if(density)
if(!((step_x+bound_x)%TILE_WIDTH||(step_y+bound_y)%TILE_WIDTH||bound_width%TILE_WIDTH||bound_height%TILE_HEIGHT))
var/area/a = locate(/area/static_area)||new/area/static_area()
for(var/turf/t in locs)
t.loc = a
/*t.verbs += verbs //if you need verb behavior to transfer from the static object to the turf*/
loc:overlays += src
loc = null
else
pixel_x += step_x+bound_x
pixel_y += step_y+bound_y
loc:overlays += src
/*loc:verbs += verbs //if you need verb behavior to transfer from the static object to the turf*/
loc = null


This snippet provides a useful subtype of obj for mapping. Statics will boil down to turf overlays using the obj/static's post-initialization layer provided it is dense and they have a bounding area that perfectly maps to tile boundaries, or it is not dense.

The object will then remove itself to a null location, removing the /obj from rendering and improving performance slightly.

I also modified areas to disallow entry provided the area is dense. If you are using area-based behavior for some other purpose, I'd highly recommend not using this script without looking into adapting it to your current system.

This is what I was referring to on the flow chart when I wrote "turf and dense area", or "turf overlay or turf", etc.