Others have beaten me to it but I'll post anyway.
It's this line:
tree(i) = Load object "good tree.dbo"
If you want the tree(i) to hold the object numbers you need to do something like:
Dim tree(100)
object_number = 0
For i=1 To 100
inc object_number
tree(i) = object_number
load object "good tree.dbo", tree(i)
Position object tree(i),Rand(-1000,1000),55,Rand(-1000,1000)
Next
In this example object_number = 0 at the start because no other objects have been loaded prior to loading the trees.
If you are using this method then you would have to use increment the variable object_number, assign this to another variable (so if you had rocks and mushrooms then you might have variable for holding the rock and mushroom object numbers), and then load the object using a similler FOR...TO...NEXT loop. You will also have to do this for any objects that are loaded individually.
The other way to do this is to have a function that simply finds an unused object number. I believe that there is such a function in Iam M's matrix utility plugin but it's easy enough to do your own.
Whether you do this or what has been posted above will depend if you need to keep track of the object numbers. I find it easier to write object number to variables as it makes things easier to deal with, especially if you are loading lots of different object that might have different properties / influences in the game. I.e. to differentiate between destructible, non-destructible scenery and exploding scenery for example.