PiRate

Moving Objects PSA: Concerning write_vector(obj+0x5C, ...)

This post is one part plug for a library I am writing and one part conveying a particular danger that arises when moving objects by the traditional method.

If you've ever written a SAPP script that teleports an object, you may have written something to the effect of

write_vector3d(obj + 0x5C, x, y, z)

The danger of this method is captured in the video below.

(This server was running with vehicle_incremental_rate set to 1, to better present what the server sees.)

 

If you've ever visited the A§H clan servers, you may have noticed some vehicles bugging out upon joining, as they run a vehicle blocker script on a few of their servers that teleports vehicles in this way. Hopefully, by the end of this post, you will understand why this method of teleporting objects results in this problem and how to alleviate the issue.

 

WHY DOES IT HAPPEN

Given a possible interaction (explosion, projectile, player pressing the action key, etc) with objects (in some cases, object markers), Halo will check a set of clusters relevant to the action as a means of reducing the number of objects checked.

In order for an action A to interact with an object O, it must meet at least the following:

  1. Object O must belong to at least one cluster that also belongs to the set of clusters relevant to action A, and
  2. Object O (or relevant markers) must be within a certain Euclidean distance of the action.

When one teleports objects using the code snippet above, the cluster structures do not get updated automatically nor on an update pretick. The object's cluster references may be updated on the tick itself, but the video above demonstrates this will not always happen.

 

In the video, the grenades thrown while inside the base do not interact with the vehicle because, although they are in the correct cluster, the grenade is simply too far away from the vehicle.

Furthermore, the grenades thrown where it is teleported to do not interact with the vehicle because, although they are close enough, the grenades are not in the correct cluster.

As a result, this vehicle is effectively in limbo until a map reset, because nothing can interact with it.

 

It should be mentioned that the above snippet is *OK* to use for player bipeds, as the cluster-object bi-map seems to get updated each tick for them.

 

HOW TO ALLEVIATE (FOR VEHICLES)

One can force the cluster-object references to update for a vehicle by giving it a bit of momentum (e.g. give it a little speed in the x, y, or z direction) and clearing the physics deactivation bit. I cannot guarantee that this will work all the time nor can I comment on its side-effects, but at the very least it will help prevent vehicles from being stuck in limbo.

 

write_vector3d(vehicle + 0x5C, x, y, z) -- Update position
write_vector3d(vehicle + 0x68, 0.0, 0.0, -0.015) -- A little -z momentum
write_bit(vehicle + 0x10, 5, 0) -- Activates physics for the vehicle

If this method does not satisfy you and you do not mind adding a few dependencies to your scripts just to teleport vehicles safely, read on.

 

HOW TO SOLVE

When Halo teleports or reorients objects, it performs roughly the following steps:

  1. disconnect the object from the map, by detaching the object from its parent and clearing its cluster references;
  2. write to the position and/or direction vectors;
  3. recalculate the object's node data, which may require reading from (possibly compressed) animation tag data;
  4. connect the object to the map, by reinserting the appropriate cluster references for its new position.

Steps 3 and 4 are quite lengthy to describe in detail, but I have provided a module you can use with SAPP as part of hlm that provides the functions corresponding to steps 1, 3, and 4 for your SAPP scripts.

Additionally, hlm itself provides a function that wraps these steps, so you can just write

hlm.object_reposition(obj, {x, y, z})

from within your scripts. The video below uses this function to safely teleport the vehicle:

 

That being said, if you're only concerned about teleporting vehicles safely, I would recommend the alleviation method unless you need to reposition an object in parity with Halo.

Edited by PiRate
Devieth, Chalwk, aLTis and 1 other like this

Share this post


Link to post
Share on other sites

Tiddy-bits:

Been a long time since I looked at anything halo, but if I remember correct you can use write_bit(vehicle + 0x10, 5, 0) to re-enable the physics to a vehicle, causing it to reset without having to give it velocity (its been a long time so maybe I am wrong?)  I do know if you write this every tick vehicles spawning on slops will gradually slide (and if you get int he way, it will trigger a death by vehicle), stationary vehicles will just momentary reset.  This can also be used as a method to stop frozen vehicles when running servers/maps that require a tickrate of 60 by writing this at a specified interval and or when a player or explosion are in the specified radius of the vehicle.  Sadly more maps that could have used this trick were never made.  Never thought to use this in the script that I wrote for ASH though since normally at the time of moving the vehicle the vehicle is in motion and has physics, and when moving the vehicle I had to reset its rotation and velocity (again if i remember correct.)

Cool stuff.

Takka and Enclusion like this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.