secondlife / jira-archive

2 stars 0 forks source link

[BUG-230263] Shape-changing vehicles broken after the February 1 update #7980

Closed sl-service-account closed 8 months ago

sl-service-account commented 3 years ago

What just happened?

I sell a popular line of vehicles that transform into various shapes on demand. This worked perfectly for many years, until February 1. Basically, my Type 100 TARDIS turns into a brick after transforming. Debugging code confirms that vehicle params are applied, and controls are active, but it won't move. Physics is reengaged properly, but the vehicle plummets from the sky instead of flying.

This started after the February 1 patch, and can be temporarily fixed by shift-copying the vehicle. Not an ideal solution, especially if people are seated on it.

What were you doing when it happened?

I boarded a Type 100 TARDIS and flew around for a few minutes. Changed to another form (a car), and drove for a bit. On the third transformation, the TARDIS stopped moving, though physics was on, and keyboard controls.

What were you expecting to happen instead?

The system should work as intended, and did for 14 years. When a new form is is selected, an object is rezzed, linked to the root prim, and physics reengaged.

Other information

Links

Related

Original Jira Fields | Field | Value | | ------------- | ------------- | | Issue | BUG-230263 | | Summary | Shape-changing vehicles broken after the February 1 update | | Type | Bug | | Priority | Unset | | Status | Closed | | Resolution | Duplicate | | Reporter | Cheshyr Pontchartrain (cheshyr.pontchartrain) | | Created at | 2021-02-20T17:54:05Z | | Updated at | 2021-03-03T20:47:42Z | ``` { 'Build Id': 'unset', 'Business Unit': ['Platform'], 'Date of First Response': '2021-02-22T12:11:43.074-0600', 'ReOpened Count': 0.0, 'Severity': 'Unset', 'System': 'SL Simulator', 'Target Viewer Version': 'viewer-development', 'What just happened?': "I sell a popular line of vehicles that transform into various shapes on demand. This worked perfectly for many years, until February 1. Basically, my Type 100 TARDIS turns into a brick after transforming. Debugging code confirms that vehicle params are applied, and controls are active, but it won't move. Physics is reengaged properly, but the vehicle plummets from the sky instead of flying.\r\n\r\nThis started after the February 1 patch, and can be temporarily fixed by shift-copying the vehicle. Not an ideal solution, especially if people are seated on it.", 'What were you doing when it happened?': 'I boarded a Type 100 TARDIS and flew around for a few minutes. Changed to another form (a car), and drove for a bit. On the third transformation, the TARDIS stopped moving, though physics was on, and keyboard controls.', 'What were you expecting to happen instead?': 'The system should work as intended, and did for 14 years. When a new form is is selected, an object is rezzed, linked to the root prim, and physics reengaged.', } ```
sl-service-account commented 3 years ago

Maestro Linden commented at 2021-02-22T18:11:43Z

Hi Cheshyr, given that duplicating the object (which would reset all the scripts in the duplicate to a fresh state) fixes the issue, it seems like one or more of the scripts inside might be getting into a bad state. Could you please attach a script which shows the issue? If you're uncomfortable including that in jira, you can alternatively let us know where a copy of it is, so that a Linden can inspect it directly.

sl-service-account commented 3 years ago

Cheshyr Pontchartrain commented at 2021-02-23T01:46:26Z

Thank you Maestro. The TARDIS is a complex system with dozens of scripts, but it's only one that's breaking. I will try to make a simplified repro for you.

sl-service-account commented 3 years ago

Cheshyr Pontchartrain commented at 2021-02-23T03:09:50Z

Good news and bad news. Bad news, it's proving difficult to create a simple test case for you. But good news, I found the cause and a solution.  When the Type 100 switches between vehicle modes, physics is disabled, the old script is deleted and a new one installed via llRemoteLoadScriptPin(). In the old days, this worked perfectly, but now the deleted script is somehow retaining control. I fixed it by clearing vehicle parameters before the script deletes itself. I was doing that in State Exit, but apparently that's not sufficient anymore.

Does this help?

sl-service-account commented 3 years ago

Maestro Linden commented at 2021-02-23T18:17:29Z

That information is an interesting lead - what do you mean by "the deleted script is somehow retaining control", exactly? Is it that the deleted script had taken some of the agent's controls with llTakeControl(), and somehow prevents input from reaching other scripts? Or is it something to do with permissions that had been granted to the script?

sl-service-account commented 3 years ago

Cheshyr Pontchartrain commented at 2021-02-23T20:13:43Z, updated at 2021-03-02T04:40:21Z

All vehicle scripts apply a set of vehicle parameters. If I don't clear those before deleting the script, the new vehicle script is unable to move the object. It is receiving inputs and enabling physics, but it just falls out of the sky. This is new behavior.

sl-service-account commented 3 years ago

Mazidox Linden commented at 2021-03-01T18:28:16Z

Hi Cheshyr,

We're working on this issue and appreciate your patience as we troubleshoot.

sl-service-account commented 3 years ago

Rider Linden commented at 2021-03-01T18:37:28Z

I thought TARDIS were supposed to fall out of the sky... https://www.youtube.com/watch?v=sVEY5AL5zzk

sl-service-account commented 3 years ago

Cheshyr Pontchartrain commented at 2021-03-02T04:40:01Z

Very funny! :)

sl-service-account commented 3 years ago

Maestro Linden commented at 2021-03-02T19:32:08Z

Hi [~cheshyr.pontchartrain], I was able to reproduce this in a modified version of the "Kart 1.0" vehicle, like so:

  1. Rez "Kart 1.0" from Library
  2. Edit the "Kart" script in the root prim, and save a new version of the script:

    • // Kart with Scripted Camera
      //
      // by Ben
      // Some help from Casval and Dave
      
      //
      // This is a simple, fun vehicle meant for offroading. 
      // 
      // It is meant as an example to use in making your own vehicle.
      //
      //
      rotation rot;
      key owner;
      
      // Defining the Parameters of the normal driving camera.
      // This will let us follow behind with a loose camera.
      list drive_cam =
      [
           CAMERA_ACTIVE, TRUE,
           CAMERA_BEHINDNESS_ANGLE, 0.0,
           CAMERA_BEHINDNESS_LAG, 0.5,
           CAMERA_DISTANCE, 3.0,
           CAMERA_PITCH, 10.0,
      
           // CAMERA_FOCUS,
           CAMERA_FOCUS_LAG, 0.05,
           CAMERA_FOCUS_LOCKED, FALSE,
           CAMERA_FOCUS_THRESHOLD, 0.0,
      
           // CAMERA_POSITION,
           CAMERA_POSITION_LAG, 0.3,
           CAMERA_POSITION_LOCKED, FALSE,
           CAMERA_POSITION_THRESHOLD, 0.0, 
      
           CAMERA_FOCUS_OFFSET, <0,0,1>
      
      ];
      
      list jump_cam =
      [
           CAMERA_ACTIVE, TRUE,
           CAMERA_BEHINDNESS_ANGLE, 0.0,
           CAMERA_BEHINDNESS_LAG, 0.5,
           CAMERA_DISTANCE, 3.0,
           CAMERA_PITCH, 10.0,
      
           // CAMERA_FOCUS,
           CAMERA_FOCUS_LAG, 0.05,
           CAMERA_FOCUS_LOCKED, FALSE,
           CAMERA_FOCUS_THRESHOLD, 0.0,
      
           // CAMERA_POSITION,
           CAMERA_POSITION_LAG, 0.5,
           CAMERA_POSITION_LOCKED, FALSE,
           CAMERA_POSITION_THRESHOLD, 0.0, 
      
           CAMERA_FOCUS_OFFSET, <0,0,1>
      
      ];
      
      reset()
      {
       vector pos = llGetPos();
       pos.z = pos.z + 2.0;
       llMoveToTarget(pos, 0.3);
       llRotLookAt(rot, 0.1, 1.0);
       llSleep(1.0);
       llStopLookAt();
       llStopMoveToTarget();
      }
      
      start_vehicle(key agent)
      {
       if (agent != llGetOwner())
       {
           llSay(0, "You aren't the owner");
           llUnSit(agent);
           llPushObject(agent, <0,0,100>, ZERO_VECTOR, FALSE);
       }
       else
       {
           llSay(0, "Motor started.");
           llSetStatus(STATUS_PHYSICS, TRUE);
      
           llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_CONTROL_CAMERA);
      
           llMessageLinked(LINK_SET, 0, "on", "");
           llSetTimerEvent(1.0);
       }
      } 
      
      default
      {    
      
       state_entry()
       {
           llSetSoundQueueing(FALSE);
           llPassCollisions(TRUE);
      
           llSetSitText("Ride");
      
           llSitTarget(<-0.2, 0.0, 0.5>, <0.00000, -0.25882, 0.00000, 0.96593>);
           llSetCameraEyeOffset(<-6.0, 0.0, 2.00>);
           llSetCameraAtOffset(<0.0, 0.0, 1.0>);
      
           llSetVehicleType(VEHICLE_TYPE_CAR);
      
           llSetVehicleFlags(VEHICLE_FLAG_NO_DEFLECTION_UP | VEHICLE_FLAG_LIMIT_ROLL_ONLY | VEHICLE_FLAG_LIMIT_MOTOR_UP);
      
           llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.01);
           llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.15);
           llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 1000.0);
           llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.1);
      
           llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0);
           llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.1);
           llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1);
           llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.1);
      
           llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1000, 1000, 1000.0>);
           llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <100.0, 100.0, 100>);
      
           llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.0);
           llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1000);
      
           llSetVehicleFloatParam(VEHICLE_BUOYANCY, 0);
           llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, 0.0);
           llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 3.0);
      
           llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0);
           llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.01);
           llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 1.0);
      
           llCollisionSound("", 0.0);
      
           llSetRemoteScriptAccessPin(42);
           llListen(0, "", llGetOwner(), "inject");
      
           if(llGetStartParameter() == 1)
           {
               llSay(0, "it looks like this script was injected - automatically starting the vehicle.");
               start_vehicle(llAvatarOnSitTarget());
           }
           llSay(0, "state_entry() completed.  Say \"inject\" in chat to replace this script with another script.");
       }
      
       listen(integer channel, string name, key id, string msg)
       {
           llSay(0, "Disabling physics & removing myself (" + llGetScriptName() + ") from prim " + (string)llGetLinkNumber());
           llSetStatus(STATUS_PHYSICS, FALSE);
           llReleaseControls();
           llRemoveInventory(llGetScriptName());
       }
      
       on_rez(integer param)
       {
           if(owner == llGetOwner())
           {
               owner = llGetOwner();
               llGiveInventory(owner, "GO KART Instructions");
           }
       }
      
       changed(integer change)
       {
           if (change & CHANGED_LINK)
           {
               key agent = llAvatarOnSitTarget();
      
               if (agent)
               {
                   start_vehicle(agent);
               }
               else
               {
                   llSetStatus(STATUS_PHYSICS, FALSE);
                   llReleaseControls();
                   //llStopAnimation("motorcycle_sit");
      
                   llMessageLinked(LINK_SET, 0, "off", "");
                   llSetTimerEvent(0.0);
                   llStopSound();
               }
           }
      
       }
      
       run_time_permissions(integer perm)
       {
           if (perm)
           {
               //llStartAnimation("motorcycle_sit");
               llSay(0, "Got permissions from " + llKey2Name(llGetPermissionsKey()) + " - taking controls.");
               llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN, TRUE, FALSE);
               llSetCameraParams(drive_cam);
           }
       }
      
       control(key id, integer level, integer edge)
       {
           if(edge)
           {
               llSay(0, "control agent:" + (string)id + " level:" + (string)level + " edge:" + (string)edge);
           }
           vector angular_motor;
           if((edge & CONTROL_FWD) && !(level & CONTROL_FWD))
           {
               llMessageLinked(LINK_SET, 0, "stop", "");
           }
           if((edge & CONTROL_FWD) && (level & CONTROL_FWD))
           {
               llMessageLinked(LINK_SET, 0, "burst", "");
           }
           if(level & CONTROL_FWD)
           {   
               vector pos = llGetPos();
               if(( pos.z - llGround(ZERO_VECTOR) ) < 2.0)
               {
                   llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <50,0,0>);
               }
           }
           if(level & CONTROL_BACK)
           {
               //llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, <0,0,1,0>);
               llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <-40,0,0>);
           }
           if(!(level & CONTROL_BACK))
           {
               llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, <0,0,0,1>);
           }
           if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
           {
      
               angular_motor.z = -PI * 0.5;
      
           }
           if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
           {
      
               angular_motor.z = PI * 0.5;
      
           }
           if(level & (CONTROL_DOWN))
           {
               reset();
           }
           llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor);
       }
      
       timer()
       {
           vector pos = llGetPos();
           if(( pos.z - llGround(ZERO_VECTOR) ) < 0.8)
           {
               rot = llGetRot();
               llSetCameraParams(drive_cam);
           }
           else
           {
               llSetCameraParams(jump_cam);
           }
      
       }
      
       touch_start(integer detected)
       {
           vector pos = llGetPos();
           llSay(0, (string)(pos.z - llGround(ZERO_VECTOR)));
       }
      
      }
  3. Save the same script in one of the other prims of the vehicle (I used the rear spoiler). Set this script to not enabled when saved.
  4. Add this script to the same child prim: ```Java string VehicleScript = "Kart";

    default { state_entry() { llSitTarget(ZERO_VECTOR, ZERO_ROTATION); llListen(0, "", llGetOwner(), "inject"); llSetScriptState(VehicleScript, FALSE); }

    listen(integer channel, string name, key id, string msg) {

       llSleep(1.0); 
       llSay(0, "Injecting script \"" + VehicleScript + "\" into th e root prim.");
       llRemoteLoadScriptPin(llGetLinkKey(LINK_ROOT), VehicleScript, 42, TRUE, 1);

    } }

  5. Sit on the kart and drive around. Observe that things are working
  6. Say "inject" in chat. This causes the scripts to:
    • The "Kart" script in the root prim disables vehicle physics and deletes itself
    • The other script in the child prim injects the child prim copy of "Kart" into the root prim
    • The newly injected "Kart" script detects that it was injected, and initializes the vehicle
  7. Attempt to drive around

    Expected results: The vehicle should move in (7) - the injected Kart script should work.

    Actual results: The vehicle does not move in (7). However, the vehicle is physical and the injected 'Kart' script prints the debug chat about control events coming in properly.

    That said, I'm not seeing any evidence that this issue is new with the Feb 1 simulator build ( https://releasenotes.secondlife.com/simulator/2021-02-01.555570.html ) - I can also reproduce it on an older simulator that I found running on a dev grid - 2020-12-01.553168.

    I believe this issue is actually a dupe of the year-old BUG-228399 appears to be the same issue. The general issue with BUG-228399 seems to be that replacing one vehicle script with another causes the vehicle parameters to be lost, unless the vehicle type is toggled back and forth with llSetVehicleType(), as in Rider's last comment in that bug. If you modify the Tardis so that the outgoing script sets it to VEHICLE_TYPE_NONE, and injected script sets it back to VEHICLE_TYPE_CAR (or whatever is appropriate), do the vehicle controls behave?

sl-service-account commented 3 years ago

Cheshyr Pontchartrain commented at 2021-03-03T20:15:49Z

Thank you Maestro. Yes, clearing vehicle type before deleting the injected script solves the problem. It's new behavior to me, as nobody reported an issue until last month. But it certainly could have begun earlier without anyone noticing. I've already fixed my vehicle scripts to work around the issue.

sl-service-account commented 3 years ago

Maestro Linden commented at 2021-03-03T20:47:42Z

Thanks for confirming - I think we can call this a dupe of BUG-228399 after all.