<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Preacher</title>
    <description>The latest articles on DEV Community by Preacher (@preacher).</description>
    <link>https://dev.to/preacher</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F665192%2F0b1a4333-af87-4379-a553-94838a256d71.jpg</url>
      <title>DEV Community: Preacher</title>
      <link>https://dev.to/preacher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/preacher"/>
    <language>en</language>
    <item>
      <title>DEVBLOG #3: Ballistics</title>
      <dc:creator>Preacher</dc:creator>
      <pubDate>Sat, 16 Apr 2022 05:17:02 +0000</pubDate>
      <link>https://dev.to/preacher/devblog-3-ballistics-6f4</link>
      <guid>https://dev.to/preacher/devblog-3-ballistics-6f4</guid>
      <description>&lt;p&gt;Here's a photo of my current ballistics solution, involving penetration &amp;amp; penetration refraction, elastic ricochets, air drag, terminal velocity (color = velocity):&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_aOellvQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykosqi6li4bb2pey6cpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_aOellvQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykosqi6li4bb2pey6cpn.png" alt="Image description" width="880" height="685"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since almost all of the games I've worked on involved some sort of ballistics, being either projectiles such as bullets or aerodynamics for planes, I've put quite a lot of time into them. In this article I'll go over my process of creating the system I use today.&lt;/p&gt;

&lt;p&gt;In a lot of games, such as Call of Duty (before MW19), your bullets were hit scanned: that means they form a ray that would immediately hit whatever you aimed at no matter how far away your target is. In a lot of other games (MW19, Battlefield), your bullets have velocity and are affected by gravity, just like in real life. Not only does the latter make the game feel more realistic, it also helps to balance weapons with larger maps.&lt;/p&gt;

&lt;p&gt;However, just having velocity and gravity isn't enough (at least for me). In Battlefield, the damage rolls off based on distance. This helps force the combat to happen at closer ranges, and also mitigates people who are really good at the game from killing others across the map. It is also missing a key feature that's present in ballistics on the surface of the Earth in real life: aerodynamic drag. This will slow your projectile down based on the square of its velocity. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8nBj4Jrg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59wkezym38bck8f5hfea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8nBj4Jrg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59wkezym38bck8f5hfea.png" alt="https://www.grc.nasa.gov/WWW/k-12/airplane/drageq.html" width="721" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image is the source of the equation I use, however it looks more complex than it is, since you can assume that Cd and the surface area for the projectile are constant (unless you want to simulate tumbling), and the air density can just be 1 (unless you want your game to take into account high altitudes). Great, so now I can just paste that into the game? Well, yes and no. Because I also have other things in place for the ballistics in my game: zeroing.&lt;/p&gt;

&lt;p&gt;Arma 3 ACE mod does all of this for their ballistics. It models velocity, gravity, ballistic coefficients of projectiles, temperature, pressure, humidity, wind, altitude, air friction, barrel twist, Coriolis effect, and probably more. (&lt;a href="https://github.com/acemod/ACE3/blob/master/extensions/advanced_ballistics/AdvancedBallistics.cpp"&gt;https://github.com/acemod/ACE3/blob/master/extensions/advanced_ballistics/AdvancedBallistics.cpp&lt;/a&gt;) However this is overkill for what I wanted, which was simply just velocity, gravity, drag, and perhaps wind. The issue with the ACE implementation is that &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It has to iteratively estimate the zeroing for the projectiles and asymptotically arrive at the correct answer&lt;/li&gt;
&lt;li&gt;It is a discrete solution, it depends upon its last position to calculate where it will be next at discrete time steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most important one is #2. This is because a continuous solution is ideal, as you can easily find where a projectile will be at a given time with a single calculation instead of stepping through time intervals and calculating it over and over again. This makes it easier and faster to do things such as zeroing and trajectory prediction. It also makes it easier and faster for other clients to simulate a copy of your own client projectile, because they know exactly where your projectile will be at what time (When they hit obstacles, I simply reset their velocity / position on the other clients).&lt;/p&gt;

&lt;p&gt;So, the first thing I did was look at the math that requires this, and also search the internet for solutions. As stated previously, the force of air friction on a projectile primarily relies on its velocity squared. In turn, it will slow down its velocity. This is messy, because you have a variable that's dependent upon itself. The first thing that came to mind was calculus 2, however I never took a class past calc 1 and I didn't want to bother learning it exclusively for this. So I looked into hacking it to get the desired results. Here are the requirements I made:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I needed a solution where the velocity variable didn't rely on itself to slow itself down&lt;/li&gt;
&lt;li&gt;The solution must be easy to calculate&lt;/li&gt;
&lt;li&gt;The solution must asymptotically reach a terminal velocity which also means reaching 0 acceleration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I did a bunch of thinking in my head and plotted it in desmos and I eventually came up with this equation:&lt;/p&gt;

&lt;p&gt;drag = 1 / (t * d + 1)&lt;br&gt;
where:&lt;br&gt;
t = time&lt;br&gt;
d = ballistic coefficient&lt;/p&gt;

&lt;p&gt;All you have to do is multiply the projectile's position equation by this. A d of 0 is a vacuum, and a d of 0.5 would mean that the velocity cuts in half after 2 seconds. Since the drag is calculated off of a constantly increasing value (time) instead of a dynamically changing variable (velocity), it makes it much easier to calculate. At first I believed this would have unintended effects, since slowing the velocity based on time instead of velocity seems completely unrelated. However, I graphed it and it checked off all three requirements I had. (Short video of me changing d value here: &lt;a href="https://i.gyazo.com/b26f41219a239d3a59fbe6083529dd78.mp4"&gt;https://i.gyazo.com/b26f41219a239d3a59fbe6083529dd78.mp4&lt;/a&gt;) As a side effect, I can also make the drag negative, which could be useful for accelerating projectiles such as rockets.&lt;/p&gt;

&lt;p&gt;I took this equation and implemented into my game to exceptionally well results. It was extremely cheap to calculate, and made it very easy to balance weapons. It was incredibly easy to make sub-machine guns great at close quarters and unfeasible at long ranges. I also didn't have to come up with a system for bullet damage dropoff like what battlefield uses, as I could just directly use its current velocity to calculate damage. I also compared the trajectory to real life trajectories and found that it was fairly accurate. The only thing it doesn't model is the transition of a projectile from supersonic to transonic to subsonic as the amount of drag on the projectile will vary. Nonetheless it was accurate for a purely supersonic and also for a purely subsonic projectile.&lt;/p&gt;

&lt;p&gt;However, next I have to solve problem #1: zeroing. Right now I've quickly put together an iterative solution for this that's quite accurate, however eventually I'll put time aside to properly solve it. I've also been working on implementing wind into it, because why not, and I've made some substantial progress with it. I didn't go over my ricochet or penetration system, but I suppose that can be for another article.&lt;/p&gt;

</description>
      <category>physics</category>
    </item>
    <item>
      <title>DEVBLOG #2: More Building Destruction</title>
      <dc:creator>Preacher</dc:creator>
      <pubDate>Thu, 19 Aug 2021 05:44:40 +0000</pubDate>
      <link>https://dev.to/preacher/devblog-2-more-building-destruction-3jci</link>
      <guid>https://dev.to/preacher/devblog-2-more-building-destruction-3jci</guid>
      <description>&lt;p&gt;In the last post I talked about making a tree-based destruction system instead of a voxel-based system. This will give me much more creative freedom and visual fidelity than the old system. I just finished a prototype, you can see it &lt;a href="https://twitter.com/preacher_online/status/1428205991061954564"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works quite well, is extremely flexible, and is faster than the old system. To negate I simply subdivide the part into multiple smaller parts. I also have a minimum axis size for the parts. This helps with annoyances of blasting a hole in a wall and having a slither of a part block the entrance, and also reduces the overall amount of parts created. I do a simple &lt;a href="https://en.wikipedia.org/wiki/Depth-first_search"&gt;depth-first search&lt;/a&gt; through a part tree and search for any parts marked as "grounded", which to mark parts is as simple as just putting a folder in a part named "ground" and then caching those in the beginning. This system is very flexible, I simply inserted a few free models from the toolbox and then inserted a folder into the bottom part with the neighbor "ground", and that's all that's needed to set it up.&lt;/p&gt;

&lt;p&gt;I decided to store each part's neighbors in an unordered dictionary instead of an ordered list. I did some benchmarking and lua is much faster at inserting and removing with dictionaries, as well as O(1) table indexing instead of having to search through the list for the neighbor I want (O(n)). This is very important for scalability where a part will have lets say 6+ neighbors. The downside to this is that I cannot order them. Originally I had it where neighbors positioned below a part will be at the the front of the ordered list, so we visit those first, since we want a downwards-biased search. This is obviously because buildings are usually in contact with the ground at the bottom. So while I gain some performance with using dictionaries, I also lose some since the search method is unbiased and searches the tree in a random matter, which means we could have a part near the bottom searching upwards for a while before reverting back down. The new system is better for smaller and more dense buildings, while the older system is better for very large buildings with lots of spaced out parts. To counter this I can just keep this in the back of my head while I make the buildings. I could always implement an A* algorithm or check the positions and sort them into a table when we check the neighbors, but I'm sure these will be slower than just the current naive search.&lt;/p&gt;

&lt;p&gt;I had another issue where when you put a hole in a part marked as grounded, the subdivided parts wouldn't be labeled as grounded and the whole building would fall apart. I get the bottom y value of the global &lt;a href="https://en.wikipedia.org/wiki/Minimum_bounding_box"&gt;AABB&lt;/a&gt; of the part. I used the lowest AABB y of the original part being negated, and compared that to the lowest reach of the new subdivided parts, and if they were about the same (fuzzy equals to take into account floating point inaccuracies) then the new subdivided parts were considered grounded. This is so that if you have a big lamp post and you cut it in half, the top part wouldn't be considered grounded since its bottom is way above the bottom of the original lamp post. I guess I could've just explained it in layman's terms using that analogy instead of this whole paragraph though, haha.&lt;/p&gt;

&lt;p&gt;The next step is doing debris. In the twitter video I simply unanchored the parts that are no longer connected to the tree, but I plan on making a cool debris system to make it look a lot better.&lt;/p&gt;

</description>
      <category>roblox</category>
      <category>robloxdev</category>
      <category>lua</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>DEVBLOG #1 : Building Destruction</title>
      <dc:creator>Preacher</dc:creator>
      <pubDate>Tue, 03 Aug 2021 15:13:00 +0000</pubDate>
      <link>https://dev.to/preacher/devblog-1-5di2</link>
      <guid>https://dev.to/preacher/devblog-1-5di2</guid>
      <description>&lt;p&gt;&lt;em&gt;PRELIMINARY: I decided to start a devblog. Hopefully I remember to actually make these posts. They will describe any projects I'm working on. If it's been a while since I've made one please bug me on twitter @ preacher_online&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DEVBLOG #1: BUILDING DESTRUCTION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the past few weeks, I've been working on building destruction. There are many ways to approach this but I prefer to take a procedural approach instead of making premade chunks of a building like what battlefield does. Obviously the first thing that should come to anybody's mind is minecraft, and that's absolutely what I tried to do last year for a different project (&lt;a href="https://twitter.com/preacher_online/status/1238651653680771078?s=20"&gt;https://twitter.com/preacher_online/status/1238651653680771078?s=20&lt;/a&gt;). It uses pre-defined "grounded" voxels that voxels will path to to figure out if they're connected to the ground or not. If the building takes damage and afterwards voxels are not connected, then they get destroyed. It turned out quite well, but they were 4x4x4 cubes and for this project I need more detail. The old project also used a global grid, so every part had to be globally axis aligned. I rewrote it to use 2x2x2 voxels, as well as let each building have its own local grid. The parts inside the buildings had to be locally axis aligned but allowed me to rotate the buildings around globally. It turned out really well but was too slow since its 4x more voxels, and scaled horribly. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XBVvdY4i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgrocg7rpa37xgpzu9o9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XBVvdY4i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgrocg7rpa37xgpzu9o9.png" alt="building picture" width="880" height="688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now I thought, why do I even need a 3d grid like minecraft? Sure, it helps find neighbors of voxels (if you don't know if they have any), and let's you add and remove voxels easily. You might think you'd want to use a 3D table to store 3D voxel data, and maybe octrees. But lua tables are slow at indexing and even worse with memory. So I did one big 1D table and just hashed the vector3s into it since its integers. (hash is just pos.z + pos.y * gridSizeZ + pos.x * gridSizeZ * gridSizeY, dont ask why its zyx, also it starts at 0) This allows me to only have to index the table once instead of three times, at the cost of some very simple math. But I soon realized that 3d voxels scale poorly if I want many large buildings, since most buildings are pretty hollow, which means they are basically sparse 3d arrays and would waste alot of memory using my solution. So I thought of instead of using a grid, why not just use a big tree?&lt;/p&gt;

&lt;p&gt;So that's what I did. I pre-cache each part's neighbor using EgoMoose's rotated Region3 that uses GJK (&lt;a href="https://devforum.roblox.com/t/rotated-region-3-module/334068"&gt;https://devforum.roblox.com/t/rotated-region-3-module/334068&lt;/a&gt;). It would be a little faster (1.4-1.6x) if all the parts inside of the building are axis aligned and I just used Roblox Region3, however that would limit the visual fidelity of the buildings if I can't rotate the parts. I used the same grounded labeled voxels. When damage takes place, I destroy the parts that get damaged. The neighbors of the destroyed parts that are still alive get their references to the destroyed parts nil'ed (nilled?). I use a depth-first search and loop through neighbors recursively until one of them has the grounded label. It works really well and is a lot faster, since a part can span multiple voxels. The best part is that they don't have to be aligned in any way, and they can be any size. The one optimization that I need to do is have a biased order for the neighbors. Most buildings should have a biased search downwards since its looking for the ground. So neighbors that are below a part should be in the beginning of the neighbor table. Here's a gif of it first checking upwards then resorting downwards: &lt;a href="https://i.gyazo.com/31c2971e3b016b536327d589f7cfd2e4.mp4"&gt;https://i.gyazo.com/31c2971e3b016b536327d589f7cfd2e4.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall I'm happy with this solution so far, it allows the most creative freedom and the least computation. It'll be interesting the different ways I can do destruction with this since it won't have to be grid aligned. I'll have to look into some more graph theory and search algorithms since that's exactly what this system is, a big visual graph. Directed acyclic graphs caught my eye but I don't think it'd work well for parts dangling only from their top edge.&lt;/p&gt;

</description>
      <category>lua</category>
      <category>roblox</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>DEVBLOG #0: Creating a Custom Cframe Animation System</title>
      <dc:creator>Preacher</dc:creator>
      <pubDate>Mon, 12 Jul 2021 01:39:15 +0000</pubDate>
      <link>https://dev.to/preacher/creating-a-custom-cframe-animation-system-3elm</link>
      <guid>https://dev.to/preacher/creating-a-custom-cframe-animation-system-3elm</guid>
      <description>&lt;p&gt;I've been trying to create a custom animation system using cframe for some time. This is for a shooter, so the requirements aren't too complicated. Animations need to do the following:&lt;/p&gt;

&lt;p&gt;-leg walk cycles, leg prone cycles&lt;br&gt;
-swing arms when nothing in hands&lt;br&gt;
-swapping between weapons&lt;br&gt;
-hold a gun when its equipped&lt;br&gt;
-reload the gun&lt;br&gt;
-lean left/right&lt;/p&gt;

&lt;p&gt;additional requirements I wanted to include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rolling when prone&lt;/li&gt;
&lt;li&gt;emotes even when you have a gun equipped (hand signals)&lt;/li&gt;
&lt;li&gt;stances of varying amount (half crouching, crawling on all fours, etc)&lt;/li&gt;
&lt;li&gt;procedural walk cycles of varying stride length in all directions, also reusing same walk cycle for varying stances (crouched, half crouched, standing)&lt;/li&gt;
&lt;li&gt;possibility of footplanting&lt;/li&gt;
&lt;li&gt;procedural hand positions for interacting with self and world (reaching up to your NVGs to raise/lower them, holding a door handle when opening it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, why not just use roblox animations? They could accomplish the first set of requirements. You can do some really cool spline animations in blender. However, they can't be used for all of the additional requirements such as procedural interactions with self and the environment. You also have to use blending and weights to get varying stride lengths. Roblox animations require you to upload them all to the platform and have all of them accessed through the cloud instead of locally, so iterating them is tedious. Also, I believe keyframe animation is a clunky way to do animations. In fact, I've noticed a lot of games and animators moving away from this system and using motion matching.&lt;/p&gt;

&lt;p&gt;So, I decided to use a custom cframe animation system. This gives me immense freedom of the animations, and allows me to use procedural animations. It doesn't require me to use Roblox's or an external animator and upload all the animations to the platform, instead I can save them in a script. Now that I decided what tools to use, I have to actually make the animation system. First I'll make the rig, and I decided to call animation points nodes. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--58uLjDEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6cn1lldmhmtriy80a0h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--58uLjDEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6cn1lldmhmtriy80a0h.png" alt="nodes of a simple character"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first I thought it would be best to closely match regular animation systems. I decided that for procedural animations to be a possibility, each animation will be its own function that manipulates the data of the nodes, which also gives them the freedom to change a plethora of things such as their weights. They would be called every frame. I planned that animations would create a layer (layer = {cframe, weight}) in each node's table of layers which is ordered nodeLayers = {layer1, layer2...}. Then I realized what would happen if I wanted to override the arm walk cycle to hold a gun? I would have to set the walk cycle weight to 0 in each hand and also any other animation moving the hands around. However, this was tedious and I had to change the weight of each of these layers in the node, remember their original weights when we stopped holding a gun, and come across the possibility of these weights wanting to change themselves while we are holding a gun and having to stop them and track their changes. This was obviously a no go, so I took a step back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hohqb4KY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgl2jm1w750zcgl51uj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hohqb4KY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgl2jm1w750zcgl51uj0.png" alt="plan 1"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SbBB07mL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpyh7f5xeewk28ojzv0b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SbBB07mL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpyh7f5xeewk28ojzv0b.png" alt="plan 2"&gt;&lt;/a&gt;&lt;br&gt;
(I later solved that issue in red from simply switching from table.remove to table[i] = nil)&lt;/p&gt;

&lt;p&gt;I began by drawing some sketches of what I thought it should do.&lt;br&gt;
The biggest issue I had was whether to iterate over the animations and let them iterate over the nodes they animated themselves, or iterate over the nodes, find their animations, and call them. The first is an animation-oriented approach, and the second node-oriented. Animation-oriented has the benefit of having easy access to the animation weight, and also sharing calculations and variables between nodes, such as left and right leg, since they will obviously be accessing similar data. However, the override animations act per node, So I would have to check if the node is overridden, otherwise its not worth computing the animation, since it'll never show. This involves me accessing the node table to see if there is an override animation and an override weight greater than 0. In a node-oriented approach, you easily know if the animations are overridden and can just call the animation that is overriding the others. The downside is that to share computations between nodes with the same animation, it requires more design to share a table. One of the nodes has to be delegated to calculate everything and then let the nodes read from it, or have an extra function that runs before that'll pre-calculate. It is also costs O(n) where n = nodes involved in the animation the amount of table indexing for animations, such as x2 for a left and right foot walk cycle. Table indexing is one of the things lua is quite slow at.&lt;/p&gt;

&lt;p&gt;I figured that animation-oriented was the way to go for the performance gains, since all the required cframe lerping that was needed to apply all the animation weights is quite expensive as it is. However, I still had to create workarounds for the problems it created, such as knowing if a node is overridden to save compute time. So I decided for an animation script to have a separate table solely to keep track of which nodes were being overridden, and the standard animations could check each node in the table before it updates them. I also decided to not have a table of layers in each node for each of its animations. Instead there is one variable for the standard animation cframe and one for the override animation cframe, as well as a weight for the override animation. At the beginning of an animation update, the cframes get blanked out, and each animation would add their calculated cframe to the nodes with their desired weights. Then an animation script will lerp between the standard cframe and the override cframe if the weight wasn't 0 or 1, else we would use the respective cframe. This massively speeds up the animations, since worst case each node will only has to lerp once, ex. O(n) where n = #nodes, since each animation can apply its weight to the components that make up the cframe rather than the cframe itself. Originally it was O(l*n) where l is #layers in a node, because weights would be applied to the cframe afterwards. It also speeds it up since the animation script wont have to loop through a table at the end for final cframe calculations.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
