English Direct Manipulation of Object Spawning via Script

5 replies
Goto Page
To the start Previous 1 Next To the start
Up
Cren
User
Offline Off
Okay, so using some of my own variations of software, I rigged up a height map, (shown in contour form here).
IMG:http://i.imgur.com/Bkf60cf.png


And then I rigged up a poorly made mechanism to (mostly manually) distribute various trees in a manner to my liking.
IMG:http://i.imgur.com/rygU6V2.png


I have a list of some 2500 trees that have precise locations (I'll put a randomizer in later and run neighbor checks to make certain I don't overlap), but the only way to import these it would seem is to use

Code:
1
create("object",8,-64,-6080,1);


So far, I cannot find a way to execute these lines without creating a new game (at which I then lose ability to manipulate the map).

I don't actually know how far I care to go with this, but right now I'm thinking the only real way to do this would be to directly inject the data into the save file, wouldn't it?

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
;Object
     c=0
     For Tobject.Tobject=Each Tobject:c=c+1:Next
     WriteInt(stream,c)                                                                 ;Count
     For Tobject.Tobject=Each Tobject
          WriteInt(stream,Tobject\id)                                                  ;ID
          If tfobject Then                                                            ;Typ
               WriteShort(stream,Tobject\typ)
          Else
               WriteByte(stream,Tobject\typ)
          EndIf
          WriteFloat(stream,EntityX(Tobject\h))                                   ;X
          WriteFloat(stream,EntityZ(Tobject\h))                                   ;Z
          WriteFloat(stream,EntityYaw(Tobject\h))                                   ;Yaw
          WriteFloat(stream,Tobject\health#)                                        ;Health
          WriteFloat(stream,Tobject\health_max#)                                   ;Health Max
          WriteInt(stream,Tobject\daytimer)                                        ;Daytimer
     Next


In that case, what is Tobject\typ and Daytimer.
12.02.15 01:45:49 am
Up
Hurri04
Super User
Offline Off
in the team-project game I'm creating together with a fellow student as a project for university (using Unity3D) we use a self-written perlin-noise algorithm to create a semi-random but reproduceable height-map.

for the step of tree-creation we then use a combination of a seed-variable and another variable that counts the iterations to create a pair of numbers which are entered into the perlin-noise function that's already in Unity (it's easier to use this than to change our own function which is better suited for the terrain-creation, lol :P). doing this 2 times yields an x- and y-position which can be used to get the terrain-height there as the z-position and then all 3 can be used to do the neighbour-check. if that returns okay a tree will be spawned. the iteration-variable will be increased and the whole thing repeats, resulting in different x- and y-positions because of this. if the z-check returns false (if there is water at that position) or if the neighbour-check returns false (because there is another tree in range) no tree will be spawned and the loop steos to the next position. this is done until either enough trees have been spawned or there have been to many failures trying to fit a tree inbetween the ones that already exist.

I think it should be possible to create something much like this using scripts in S2 in order to achieve a similar effect without having to mess with map safe-files (which I never even tried).
unless I understand something wrong and it absolutely has to be the exact same positions?

Edit: or is this for a story-map (since you mentioned still wanting to be able to manipulate the map)? in that case, there's the possibility of using s2 cmd create to spawn the trees at the s2 cmd on:start event of the map (if that is what already works for you), then saving it and renaming the safe-file extension so that it can be loaded into the editor as a map-file.
/Edit end

edited 2×, last 12.02.15 02:15:39 am
12.02.15 02:50:49 am
Up
Cren
User
Offline Off
Well, it was less about wanting the EXACT positions as much as wanting the general positions; I might (or might not) want to toy with going into a stronger procedural generation [as it is, I currently only separated various trees by the initial height map, and then used a "by the eye" tinkering looking around ranges with a new perlin noise map for various formations and densities that I liked].

I think this is more just boredom and tinkering to keep my mind active.

I'm strongly considering just editing the map file directly; but this is of interest:

Quote:
in that case, there's the possibility of using create to spawn the trees at the on:start event of the map (if that is what already works for you), then saving it and renaming the safe-file extension so that it can be loaded into the editor as a map-file.


You're saying I can rename the save files and they'll act exactly like a map?
12.02.15 04:51:55 am
Up
Hurri04
Super User
Offline Off
yep, sure can do. just rename the extension of the save-file from ".sav" to ".s2" and you can open it in the editor. edit all you like and afterwards you can even name it back. although normaly as a player you'd just start the map from the map-file at this point.

usually this is something people only use when they
• cheat (it would have to be a pretty complex cheat though in order to justify the amount of work needed),
• want to try and fix something, like e.g. colour problems on the map after alt-tabbing out when in fullscreen mode (here's the image user DC likes to post) or
• try to debug something in a save-file.



but if your main focus is only on certain height zones then a much easier way would be to simply use s2 cmd randomcreate
(use google translate on that site if you need to, it should give you the gist of it.)

the only thing is that you wont be able to see in the editor where exactly the trees will be placed when you use s2 cmd loop to create them s2 cmd on:start but you can still use s2 cmd count_inrange to see if there is more than 1 tree (namely the newly created tree that needs neighbour checking) within a certain radius and then use s2 cmd free to get rid of it again if there are other trees too close by.

though a smaller issue with randomcreate is that the results of where the trees are placed are actually random in the sense that they can not be replicated exactly the same, an idea to get slightly more comparable results would be to manually place e.g. flags from the "info" category on the map and check after a tree has been created whether such a flag is in range. delete the tree if that's not the case, otherwise leave it. the result would be small round-ish (depending on the radius you check) patches of forests. you could even give the flags local variables each and check for the values of those in order to create e.g. patches of different tree-types!

although Stranded2Script ("s2s") does have its limitations at some points it's still a pretty powerful language. if you need help getting into it I'd suggest to read the tutorial and maybe try to get a general overview of the command list
13.02.15 06:41:50 pm
Up
Cren
User
Offline Off
Honestly, you probably are right that I'm taking a long cut here; but on the other hand I like having 100% control and know exactly what is going on. The images I posted were generated with Octave (MATLAB Clone) and it gives me quite a bit of power without digging into the a new language. To be honest, I'm not really certain I would want to learn it, given I would have to be working with the limitations of the engine rather than the limitations of my (admittedly limited) mathematical knowledge.


As it stands though, I rigged up a parser to get to the object code (it isn't too deeply buried), and now can very easily directly modify the map :D.


As it stands, my islands are rather small with fairly dense forests all around which I can modify manually still; but I was thinking about modeling forest growth a little more.



First, I would generate a few "curved" shapes that would then randomly populate the area; (using some kind of system of weighting so that a large island isn't populated by many small "shapes" and a small island isn't populated by many large shapes). I think bezier curves might work here, do some extinction process to remove overlaying shapes and keep the area within threshold percentages, etc.

From here, I can determine the centroid of my new shape and create a density contour map, focusing on the center and propagating outwards. Use perlin noise to add some slight variations to the resultant contour map; and use white gaussian to populate the area based on chance.


The islands I'm currently playing with are far too small to really make the most of this (at best, there'd be one density contour) and I'm pretty happy with how they've been populated, but implementing that in Octave vs implementing in a new language isn't really favourable.
13.02.15 09:32:53 pm
Up
Hurri04
Super User
Offline Off
okay, I can understand if you want to have reproduceable positions for the trees. if the parser works then it will probably be indeed the fastest way to import these positions into a map, other than writing the coordinates into a file and interpreting it in S2 or rebuilding the algorithm that produces the positions in S2.


my approach for "organic" forest growth would be to have some "seeds" (the flags I mentioned earlier) and let trees stay if they are within a certain radius of those or within a certain smaller radius to another already existing tree (but not too close). that way the forest will grow within the starting area, reach its borders and then develop by creating paths that stretch out like fingers. or something like that.


I quickly threw this script together:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
on:start {
  $numberOfTreesToSpawn = 1000;
  event "spawnTree", "info", currentid();
  jumptime 15000;
  jumpfactor 5;
}

on:spawnTree {
  $treeType = random(1, 9);
  $tree = randomcreate("object", $treeType, 20, 160);
  if($tree != 0) {
    $inrange_MaxDistance = 0;
    $inrange_TooClose = 0;
    
    $inrange_MaxDistance += count_inrange("info", 32, 300, "object", $tree);
    loop("count", 9) {
      $type = loop_id();
      $inrange_MaxDistance += count_inrange("object", $type, 100, "object", $tree);
    }
    
    loop("count", 9) {
      $type = loop_id();
      $inrange_TooClose += count_inrange("object", $type, 60, "object", $tree);
    }
    
    if(($inrange_MaxDistance > 1) && ($inrange_TooClose == 1)) {
      $numberOfTreesToSpawn--;
    }else{
      $failures++;
      free "object", $tree;
    }
    
    if(($numberOfTreesToSpawn > 0) && ($failures < 1000)) {
      event "spawnTree", "info", currentid();
    }
  }
}

the start event calls the event I created below it which then creates a tree. note that s2 cmd randomcreate could be replaced by the normal s2 cmd create command if e.g. perlin noise was used to determine the positions, like I suggested before. also I put in a s2 cmd random factor to spawn different kinds of trees. nothing big really.

the tree then checks whether there is a red flag info within a radius of 300 units or if there is another tree within a radius of 100 units. next up is the neighbour check to make sure there is no other tree within a radius of 60 units.

if the right conditions are met the tree can stay, otherwise it gets deleted and a counter is increased to make sure that the script can end after a certain amount of tries (e.g. if there is no more free space on the island).

if everything works out fine this should create about 1000 trees. it's possible to change this number and the number of allowed failures a bit but I would advise against setting them too high or else the game might crash.


the script has to be placed in the script box of one red flag info of which multiple can be placed to create multiple small forests.
(pro-tip: F12 starts the current map in the editor as a game in debug mode and also brings you back to the editor afterwards )

here's a screen of how it would look, the colums mark positions of the flags which are invisible in game mode. although this is already the maximum view distance you can only see 2 of the 4 I placed but you can see the tree groups surrounding them top left and right.
(also here is the reason for the s2 cmd jumptime and s2 cmd jumpfactor commands I used, so that I could get the picture from high up ):
IMG:http://fs1.directupload.net/images/150213/a3acwgaj.jpg
To the start Previous 1 Next To the start