Jump to content

animats

Resident
  • Content Count

    2,342
  • Joined

  • Last visited

Posts posted by animats


  1. 4 hours ago, ArgontheDevil Ormega said:

    A little small for an oil refinery.  Some sort of waste disposal facility would be in period but definitely industrial.

    pumpingstationnumberone.thumb.jpg.8be4d787f6bc5fb28a0a6b6c10aea155.jpg

    Like this?

    This is a well done piece of mole work. The pumping station has pumps and an engine, a control room with a map of the sewer system, and a pipeline out into the bay out back.

    • Like 2

  2. After much struggling, I have things working, but memory is still extremely tight in one script. Notes:

    • There's no memory leak. These busy scripts can run for days. The way llGetFreeMemory reports free memory creates the illusion of a memory leak, but if you force a garbage collection, llGetFreeMemory then returns a realistic number.
    • Passing link messages around creates some problems. Link messages are broadcasts to every script in the prim. Scripts can ignore messages, but a big incoming message can cause a stack/heap collision in a script that's going to discard the message. So every script has to have enough free memory for the longest message sent by any script. Putting scripts in different prims is a possible workaround; you can address messages by prim, but not by script.
    • The 64 event queue limit is real, and it's exactly 64, as documented. Two scripts exchanging messages rapidly while another script in the same prim is doing a long task can overflow the queue for the script with the long task. Then  events are lost. I hit that.
    • A stack/heap overflow produces a message on DEBUG_CHANNEL, but only within normal 20m "talk" range. For a while, I was running around after my NPCs to be in range when they crashed. I finally wrote a little script that repeats DEBUG_CHANNEL error messages to  llOwnerSay, so I can see the crash info anywhere in the same sim. Since you can't listen to yourself, that has to go in a different prim than the ones that might crash.
    • A script can't reset itself after a stack/heap overflow, but another script can reset it with llResetOtherScript. So I now have a stall timer. If all progress stops, the script with the stall timer resets all the other scripts and recovers.
    • This was a huge pain to write, but it's working reasonably well.
    • Like 1

  3. On 9/5/2019 at 1:41 PM, Nova Convair said:

    You can use an autoincrement field in the database. The numbers are unique. If you need it in a variable while performing an insert you can get it with lastInsertId()

    Only the database can guarantee you unique numbers, everything else is clumsy.

    Yes. The problem is at "Pet ID is "number of rows" +1." It's quite possible for two PHP scripts running at the same time to get the same value for that. This is a database update race condition.

    lastInsertID, though, is unique across multiple simultaneous requests. See the MySQL manual here. Also the PHP manual here.

    If you use SQL, you may need to understand how transactions work. If you do several SQL operations in a row, expecting the database to be in the same state it was after the previous operation, you may find that some other event got in there and changed it between your operations. Either write your code to not depend on that, or learn how to use transactions in SQL to lock things.

    SL can do many things simultaneously, PHP can do many things simultaneously, and MySQL can do many things simultaneously. Fortunately, how to deal with all that was figured out long ago by the web backend and database people, who deal with this constantly. All the major databases that talk SQL have the features for this.

    • Like 1
    • Thanks 1

  4. 40 minutes ago, Mollymews said:

    on this. Its that when we add to a list then a copy of the new added list is created before the old list is freed. Doubling uses less memory in the creation of the new list than does adding items one at a time

    That makes sense.

    All this has been very useful.

    I've written a path planner which does paths of any length. If the goal is far and the route is complicated, it can run out of memory creating a long list of waypoints. The planning is done in steps, so I had the planner stop and return a partial path when low memory was detected. The next planning cycle will pick up from the new position and continue to head for the goal, but redoing it repeats some work, makes it slower, and the motion pauses.  That helped with the stack/heap collision problem.

    But llGetFreeMemory always returned smaller values. Memory looked tight forever thereafter. So the first really long path got the planner stuck doing the job in little pieces until the next script reset.

    Now, when the planner sees low free memory, it uses the forced GC trick:

    integer memlimit = llGetMemoryLimit(); // how much are we allowed?
    llSetMemoryLimit(memlimit-1); // reduce by 1 to force GC
    llSetMemoryLimit(memlimit); // set it back

    and then checks llGetFreeMemory again. So, after handling an extra-long path, it now goes back to normal until the next long path. No more stack/heap collisions from that script, and it doesn't get stuck in slow mode.

    So, working for now. Thanks, everybody.

    • Like 2

  5. 10 hours ago, Nova Convair said:

    And why can I only add 2048? Ok, some more but 8192 is far out of scope 
    It's obviously 16 bytes per element in my example and 4 in your example.

    Try building up the list by doubling, as I did.

    Getting 4 bytes per element hints that there's a more efficient representation that it uses some of the time.


  6. 4 hours ago, Nova Convair said:

    Some math: an integer needs 4 bytes but every list element needs at least a pointer (4 bytes) and most probably some extra info like type flag and stuff not to mention a backward pointer so I don't see how 8192 elements will fit into 64k.

    The wiki article on memory consumption claims 7 bytes per integer in a list. That's 57344 bytes, so it could fit. But the size numbers I got were:

    12 hours ago, animats said:

    [21:50] Free mem count test: Free mem before allocating list: 60628
    [21:50] Free mem count test: Free mem after allocating list of 8192 integers: 27700

    The difference there is 32928. Which works out to just over 4 bytes per integer.

    I wonder how lists in LSL are really stored. They're probably not linked lists. More likely, collections. You can get elements by index, which is really slow for a linked list.


  7. More info.

    //
    //  Memory allocation test - do we get free memory back?
    //
    integer listcnt = 13;
    default
    {
        touch_start(integer total_number)
        {   llOwnerSay("Free mem before allocating list: " + (string) llGetFreeMemory());
            list buf = [1];
            integer i;
            for (i=0; i<listcnt; i++)
            {   buf += buf;    }                         // double length of list   
            ////llSleep(0.5);     
            llOwnerSay("Free mem after allocating list of " + (string)llGetListLength(buf) + " integers: " 
                + (string) llGetFreeMemory());
            buf = [];                                   // release memory
            ////llSleep(0.5);     
            llOwnerSay("Free mem after releasing list: " + (string) llGetFreeMemory());
        }
    }

    Simple test program - allocates some memory, releases it, reports free memory.


     

    [21:23] Free mem count test: Free mem before allocating list: 61140
    [21:23] Free mem count test: Free mem after allocating list of 8192 integers: 56888
    [21:23] Free mem count test: Free mem after releasing list: 56888

    Touch again:

    [21:23] Free mem count test: Free mem before allocating list: 56888
    [21:23] Free mem count test: Free mem after allocating list of 8192 integers: 56888
    [21:23] Free mem count test: Free mem after releasing list: 56888

    This makes no sense. We allocated 8192 integers and memory space only dropped by 4252.

    If the "llSleep" calls are not commented out, we get saner results:

    [21.28] Free mem count test: Free mem before allocating list: 61140
    [21:28] Free mem count test: Free mem after allocating list of 8192 integers: 28216
    [21:28] Free mem count test: Free mem after releasing list: 28216


     

    [21:28] Free mem count test: Free mem before allocating list: 28216
    [21:28] Free mem count test: Free mem after allocating list of 8192 integers: 28216
    [21:28] Free mem count test: Free mem after releasing list: 28216

     

    Above, someone suggested forcing a garbage collection. Turns out that works.

    //
    //  Memory allocation test - do we get free memory back?
    //
    integer listcnt = 13;
    default
    {
        touch_start(integer total_number)
        {   llOwnerSay("Free mem before allocating list: " + (string) llGetFreeMemory());
            list buf = [1];
            integer i;
            for (i=0; i<listcnt; i++)
            {   buf += buf;    }                         // double length of list   
            llSleep(0.5);     
            llOwnerSay("Free mem after allocating list of " + (string)llGetListLength(buf) + " integers: " 
                + (string) llGetFreeMemory());
            buf = [];                                   // release memory
            llSleep(0.5);     
            llOwnerSay("Free mem after releasing list: " + (string) llGetFreeMemory());
            integer memlimit = llGetMemoryLimit();       // how much are we allowed?
            llSetMemoryLimit(memlimit-1);               // reduce by 1 to force GC
            llSetMemoryLimit(memlimit);                 // set it back
            llOwnerSay("Free mem after forcing GC: " + (string)llGetFreeMemory() + ". Memory limit: " + (string)memlimit);
        }
    }
    

    Results:

    [21:50] Free mem count test: Free mem before allocating list: 60628
    [21:50] Free mem count test: Free mem after allocating list of 8192 integers: 27700
    [21:50] Free mem count test: Free mem after releasing list: 27700
    [21:50] Free mem count test: Free mem after forcing GC: 60544. Memory limit: 65536

    Now llGetFreeMemory increases. Changing the memory limit seems to force a garbage collection.

    So it looks like:

    • llGetFreeMemory  gets updated on a "sleep", and
    • llGetFreeMemory does not increase even after releasing memory.
    • Reducing the memory limit, even by one byte, will force a garbage collection, which can increase llGetFreeMemory.

    So, if you really need a free memory count before you allocate something big, that's how to get it. But it's undocumented behavior that might change. Any of the Lindens want to comment whether this is behavior that can be relied on?

    • Like 2
    • Thanks 2

  8. More testing. I let the NPC with this script run overnight. Free memory started around 10KB, and gradually decreased to about 3.5KB over half an hour. And then, over 10 hours, it didn't decrease any further. The script continued to run properly. No stack/heap collisions. So it's not an ongoing leak, it's some kind of slow startup transient or maximum usage.

    I'm pretty sure my code isn't holding onto memory. In LSL, the only way you can do that is with a global list or string. This code (here) doesn't have either of those. I'm wondering if something within the LSL system calls sometimes allocates space and never gives it up. Not losing the space, just allocating a buffer for, say, the biggest llGetStaticPath or JSON parse or queued message. That would explain this. Anyone know?

    Anyway, the take-away for this is that you can't get very close to the memory limit with long-running scripts. If they run busily for a day, they're probably OK.

    As a backup, I now have another script with a stall timer. If the complicated planning scripts stop answering their link messages, the supervising script resets them all with llResetOtherScript. So far, that's tripped twice, for unrelated bugs, now fixed. This sort of supervision is common in real-world robotics. It's part of the price of long-running autonomy.

    Quote

    So there are only 2 possibilities - the recursive call crashes your script - or leaves with a clean stack.

    Right. In LSL event-driven programs, if the script continues to accept events, it's getting all the way back to the stack empty state. LSL's limitations exclude many of the things that can go wrong in other languages.

     


  9. Well, I've been able to reproduce the problem with the same script and a test driver in a prim cube. Before, it was in a moving animesh NPC, and I had to chase it around to be close enough to see which script was getting a stack/heap collision. You have to be within llSay distance to get a DEBUG_CHANNEL popup box. Now the same single script is failing in a nice stationary cube. A little test driver script sends it link messages to make it go, and the results are discarded. Takes about 10-15 minutes to hit a stack/heap collision. The free memory, as reported by llGetFreeMemory, keeps decreasing as it runs. I've never seen it increase. It got down to 922 bytes. Then I printed the long output from a llGetStaticPath as a long string, and that apparently used up the remaining memory, causing a stack/heap collision.

    The script spends most of its time in an idle waiting for event state, but going idle doesn't seem to shrink the memory used. Again, there are no global list or string variables, so it ought to return to its initial memory usage after each use. That's the obvious time for a garbage collection - when the script goes idle. No stack.

    It's possible that some of the LSL calls like llgetStaticPath or the JSON calls allocate some internal space for the biggest item they ever processed, and don't release it. That would show a slow decrease in free space, like a memory leak, but it's bounded. Just speculation at this point.

    This may take a while to chase down. More later.


  10. I have a script which eventually gets a stack/heap collision after about an hour. It's part of a system of scripts, and its input is via a link message. It does lots of computation and list operations, and outputs data to other scripts using link messages.

    It has no global variables of list or string types. All the list variables are local to functions. So it should not be able to leak memory. It does make lots of calls to the JSON functions, and calls llGetStaticPath, and I wonder if there are problems in those areas. Any known or suspected issues? I've checked the JIRA; nothing in recent years.

    I'm logging some info, and here's what llGetFreeMemory is saying:

    john@Nagle-LTS:~/Documents/sl/logs$ grep "Path planner low" lowonmem03.txt
    [22:45] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:46] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:46] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:47] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:47] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:47] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:47] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:48] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:49] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:49] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:50] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:50] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:50] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:53] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:53] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:53] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:54] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:54] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:54] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:55] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:55] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:55] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:55] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:56] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:58] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:58] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:59] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [22:59] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [23:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [23:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [23:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [23:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2986
    [23:03] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:04] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:04] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:05] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:05] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:07] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:07] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:07] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:08] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:09] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:09] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:09] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:10] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:10] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:10] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:12] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:12] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:13] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:14] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:15] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:16] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:16] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:16] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2472
    [23:16] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:17] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:17] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:18] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:20] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:20] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:20] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:24] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:25] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:25] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:27] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:27] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:27] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:29] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:29] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:29] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:30] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:32] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:32] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:32] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:34] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:35] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:35] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:36] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:36] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:36] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 2258
    [23:39] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:39] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:41] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:43] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:46] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:47] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:48] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:48] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:48] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:48] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:49] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:49] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:49] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:49] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:50] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:50] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:52] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [23:54] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:00] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:00] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:00] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:00] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278
    [00:01] Dacy - NPC trainee 2.17c: Path planning: Path planner low on memory: 1278

    And finally, in the debug window:

    [00:03] Dacy - NPC trainee 2.17c [script:Path plan task] Script run-time error
    [00:03] Stack-Heap Collision

    The free memory ticking down looks like a leak. I've read that llGetFreeMemory can reflect free memory before the next garbage collection. When I saw free memory decreasing, I expected it to go back up at the next GC. But instead, I got a stack/heap collision.

    Hm. Anyone seen something like this before?

     

     

     

    • Like 1

  11. Here's a nice demo of the navmesh builder deciding what's walkable.

    walkablering.thumb.jpg.f9c07fb17b534ad02165ff7c55fa307d.jpg

    Walkable hollow ring. Hollow prim. The greyish areas outlined in red are walkable. Walkability is sided; on the inside top, the red outline without grey fill indicates we are looking at the unwalkable underside of a walkable surface.

    This shows the angle at which the navmesh builder treats a face as an obstacle rather than a walkable.

    This part of pathfinding was very well done.

     

    • Haha 1

  12. The static navmesh system for pathfinding can do more than the documentation suggests.

    Set an entire building to walkable, and the horizontal surfaces become walkable, while the vertical surfaces become static obstacles. This is a great feature, and makes setting up a parcel for pathfinding far simpler. I just got rid of my "invisible walkable rugs" and similar hacks.  If the object has a reasonable physics model, including ramps for the stairs, it all just works.

    orvilleairport01.thumb.jpg.e58b95fcacad0e209c70fca7c001f9cc.jpg

    Terminal at Orville airport, Orville sim. This is a Linden sim for seaplane testing. Nice seaplane ramp, terminal, and hangars. Everything is pathfinding-ready. Grey areas are walkable, and red lines bound their edges. All prim, no mesh; this is classic SL.

    bldglayers03.png.f52454da0c3f280da4b2ba75eefb39b4.png

    Another building, one I've modified. This is part prim, part mesh. That works, too. Notice the steps. If the physics model is a ramp, the static navmesh builder figures it out. I used to have "walkable rugs" all over this place, linked into one linkset.They're no longer needed.

    Pathfinding characters can climb the stairs in both of these buildings.

    So it's much simpler to set up a building for pathfinding than previously thought. The "Visual Guide to Pathfinding" says "For instance, if your building is all one object or linkset and you wish to make the floor Walkable, you will need to unlink the floor so you can set the building to Static Obstacle and the floor to Walkable." That works, but is unnecessary for prim buildings, and impossible for single object mesh buildings.

    Incidentally, to be included in the static navmesh, an linkset needs to be at least 10.1m x 10.1m. That's the linkset, not a prim. Small sheds might have a problem, unless you link them to something to make the linkset bigger.

    Key numbers to know about this feature:

    • Below somewhere between 60° and 70° from horizontal means "walkable". Above that, it's a static obstacle. That's also about where avatars can no longer climb something. Normal 45 degree stairs work fine.
    • A vertical break, like a curb or door threshold, remains walkable up to some threshold between 0.20 and 0.35m.  That's for a path 0.5m wide. So most ordinary curbs and door thresholds work fine.

    Related JIRA.

     
    • Thanks 1
    • Haha 1

  13. 10 hours ago, Rahsus Kronos said:

    Think Dark Crystal meets Final Fantasy Meets Tron Meets Ready Player One meets dot hack sign meets Disc World. 

    ? Try to focus.

    cocoonatnight.thumb.jpg.f86346eebfd550acbf84ad838ee74fc0.jpg

    A Sci-fi roleplay sim in Second Life. This is your competition. Can you do better?

    There are some incredibly good SF builds in Second Life, but most lack enough roleplayers to populate them properly.


  14. 1 hour ago, Prokofy Neva said:

    I wonder if you could use the same thing for a car or an animal, but usually they aren't on mod.

    Sure you can.

    I have an alternative system, but it only works for properties right on the water but separated by a strip of Linden beach. It extends a temporary track from the boat storage rack out into the water. Then the boat can slide down the track. When not in use, the track retracts back onto your own property. I want to improve it so it has a boat trailer like thing that carries the boat. These are called "marine railways" in real life.

    marinerailwayfullmed.thumb.jpg.dfeaf16678a35309674349a868e37116.jpg

    Just have to cross that narrow strip of Linden beach...

    • Like 3

  15. Notes on LOD ratios.

    Here's some info from the Unity manual for designing game objects: "Many LOD Groups use three levels, where LOD 1 is active when the GameObject fills between 25% and 49% of the screen height, and LOD 2 is active when the GameObject fills less than 25% of the screen height."

    So where does that take us? That says LOD distances have ratio 1, 2, 4, 8.  Or, if we drop to Medium LOD at 5 meters, we drop to Lowest at 40 meters. OK.

    At twice the distance, an object occupies a quarter of the screen space. So triangle ratios should drop by a factor of 4 from level to level. Animesh drops by a factor of 2, regular objects drop by something larger. Suppose we went with 4 for most objects. So we have 1, 1/4, 1/16, 1/64 triangle quotas. A 60,000 triangle shoe (sadly, quite common) drops to below 1000 at distance. 0.1% of the scene budget. (1 million tris per screen is about typical before the viewer on a midrange PC drops the frame rate below 30, so that's a reasonable number for planning purposes.)

    This kind of makes sense. People want super-high detail at close range, and creators oblige by giving it to them. That implies big drops at distance.

    Discuss.

     

    • Haha 1
×
×
  • Create New...