Releases: EvenTorset/fxr
Releases · EvenTorset/fxr
v17.0.0
- Named and documented three actions:
- 700 -
SimulateTermination
- 701 -
FadeTermination
- 702 -
InstantTermination
- 700 -
- Named and documented some fields:
- Action 128 (
NodeAttributes
):unk_ds3_f1_3
is nowdepthBias
. - Action 609 (
PointLight
):unk_ds3_f2_24
is nowmaxViewDistance
.
- Action 128 (
- Renamed "Effects" to "Configs". The old name had a bunch of different issues, including making writing documentation just more annoying because it could be referring to different things. The new name should better descibe what they are (basically a configuration that defines the characteristics of the node that can be swapped out with another by state changes), and isn't used to refer to anything else that is related to FXRs so far. This is the biggest breaking change in this update, so check out the table under the patch notes for things to find and replace if you need to update your scripts.
- The
EffectAge
property argument was renamed toActiveTime
due to this, which is the biggest change in the documentation. No code should need to change because of this, because this is only used to document the argument given to properties, but it's worth mentioning due to how important this might be. The description for it was also updated to say that it is the time since the action (previously "effect") became active, which is also more accurate since this is also used outside of configs/effects.
- The
- Changed the default value of
unk_sdt_f2_32
in some of the appearance actions to 0. (Was previously 1.)- When this is 1, it can cause object seen through particles with the depth blending effect to have some ugly-looking outlines. When it's set to 0, this doesn't happen at all, and it also seems to allow some other fields in the action to work.
- This seems to make the texture on the particle a bit blurry in some cases, but for most particles that shouldn't matter much since they often use textures that are blurry anyway. Just set the property to 1 again if you need the detail in the texture to be visible, but keep in mind that this will cause the outline problem described above to occur again.
- What this field does exactly is still unknown, so if this change has any other side-effects is also unknown.
- Renamed the
unk70x
property in theRootNode
class totermination
to match the actions it can be set to. - Renamed
BlendMode.Screen
toBlendMode.Unk7
. The old name was based on some old, and apparently incorrect, documentation. This blend mode is seemingly identical toBlendMode.Add
. - The documentation site now generates JSON files that contain a lot of the information that is in the library. The main reason behind this addition was to allow the FXR Playground to have easy access to the documentation in the library, but feel free to use these in other tools if you need any of this information.
/data/actions.json
- This is an array of objects that contain information about all action types, including a name, description, what games it works in, the structure of the action in each of the supported games, and detailed information about every field, property, and section10 in the action./data/enums.json
- This is an object that contains various enums, likeBlendMode
,InitialDirection
,OrientationMode
, and so on. Each enum has a description and a members object. Each member has a value and a description.- All of the descriptions are Markdown strings.
- As a bonus for this, more enums are now properly documented, and some documentation errors in some actions have been fixed.
DataAction
s now check if there are any properties that have the wrong type or number of components when they are written to an FXR buffer, and throws descriptive errors if there are any. This should make it easier to find out if and where you put an invalid value.- Added the missing descriptions for the
particleLength
andparticleWidth
properties in actions 10008 and 10009. - Fixed a bug where recoloring actions white would cause them to be randomly extra colorful due to randomization modifiers on the color properties in the action. Recoloring now removes randomization modifiers from color properties.
- Fixed the
delay
field inNodeAttributes
actions not being scaled when using thescaleRateOfTime
method.
If you need to update your scripts, here's a table of things to find and replace which should fix most of the problems:
Old | New |
---|---|
BasicEffect |
BasicConfig |
LevelsOfDetailEffect |
LevelsOfDetailConfig |
NodeEmitterEffect |
NodeEmitterConfig |
.walkEffects |
.walkConfigs |
.effects |
.configs |
.stateEffectMap |
.stateConfigMap |
v16.0.0
- Named and documented action 800:
ParticleForceCollision
. This enables collision with the full 3D environment for regular particles, but also causes the game to crash if a particle despawns. It is most likely an unfinished action, and it only exists in AC6, where it's used just once, in an effect that also causes the game to crash. It seems very stable as long as the particles don't despawn, though. - The
valueAt
method on properties should now give the correct value for sequence properties and component sequence properties with keyframes that are out of order. These properties can be considered invalid in some sense, but they are still functional in-game, and this method should now reflect that.- Any keyframes that are out of order, i.e. their position is less than the position of the previous keyframe, are now ignored entirely, unless the property does not loop and the given argument is greater than the duration of the property, in which case the last keyframe's value is always returned, no matter what its position is.
- Sequence properties and component sequence properties no longer automatically sort their keyframes.
- This allows these properties to be written with their keyframes out of order, which means that reading and then writing an FXR file with such a property no longer has a chance to break that property because of the different keyframe order.
- Sorting the keyframes can still be done using the
sortKeyframes
andsortComponentKeyframes
methods on sequence properties and component sequence properties respectively, and these methods have been changed to return the property they were called on to make them more convenient.
- Fixed the brightness of point lights when converted to or from DS3. Hopefully it's actually fixed this time...
- Renamed
unk_ac6_f1_1
in actions 10008 and 10009 tounk_ac6_f1_2
. The old name did not match the field's index. - Fixed the argument for some properties:
color3
inPointSprite
is nowParticleAge
(wasEffectAge
)lengthMultiplier
inLine
is nowParticleAge
(wasEffectAge
)lengthMultiplier
inQuadLine
is nowParticleAge
(wasEffectAge
)widthMultiplier
inQuadLine
is nowParticleAge
(wasEffectAge
)- This was just a documentation error and should not affect any functionality.
- Updated the description for the
DataAction
class. It was very out of date. - Updated the description for most color properties to mention if the values are clamped or not.
v15.2.0
- Added a
getResources
method to nodes. This does the same thing that theFXR
method with the same name does, except it only lists resources used in the node it is called on, and optionally descendant nodes.
v15.1.0
Highlights
- Added a
depth
argument to theclone
method on nodes that controls how many levels of descendants to clone. It defaults toInfinity
(same behavior as before), and can be set to 0 to not clone any child nodes. - Updated links in the readme to work with the FXR Playground update.
v15.0.0
Highlights
- Added
Game.Heuristic
, which can be used withFXR.read
to let the library figure out what game an FXR file is for.- This is now the default
game
value for theFXR.read
function. (WasGame.EldenRing
previously.) FXR
objects now have a newgameHint
property that stores what game the file was parsed as. It defaults toGame.Generic
, and the only way to set it is using theFXR.read
function. New effects created withnew FXR
orFXR.fromJSON
will have the default value. The hint will beGame.Heuristic
if theFXR.read
function could not determine what game it was from.- The
FXR.toArrayBuffer
andFXR.saveAs
methods now useGame.Heuristic
as the default game value too (was alsoGame.EldenRing
previously), which will cause them to use thegameHint
as the game, unless the hint isGame.Heuristic
. If the hint isGame.Heuristic
, they will look for some AC6-specific things, like action 800, and will use that as the game if anything is found. Otherwise, it will throw an error. I highly recommend still giving these methods a specific game, so the library doesn't need to guess. FXR.read
can detect any DS3 or Sekiro effects perfectly, as long as they're not modified in ways that would make the effect invalid for the game.- It has a pretty high chance of getting it right for ER and AC6, but it is not perfect, because there are a lot of ways to make AC6 effects that would be the same in ER. It will still read the effect correctly, as it doesn't matter if it's for ER or AC6 if they're both the same, but it affects the
gameHint
property, which can then affectFXR.toArrayBuffer
andFXR.saveAs
.
- It has a pretty high chance of getting it right for ER and AC6, but it is not perfect, because there are a lot of ways to make AC6 effects that would be the same in ER. It will still read the effect correctly, as it doesn't matter if it's for ER or AC6 if they're both the same, but it affects the
- This is now the default
- Added a
Recolor.weightedAveragePalette
function, which takes a color palette with weights for each entry and returns a new palette that has the weighted average of all entries for each slot. - Added a
randomSeed
function for generating random seeds to be used with randomization modifiers. The modifier classes already generated random seeds as default values, but this allows you to easily generate seeds that can be used in multiple properties, synchronizing their randomization. - Added a
RandomFractionProperty
function. This was the only missing function to generate properties with randomization modifiers. The other two modifiers have had functions like this one for a while now. - Added a
getValueType
function that returns theValueType
of a given value. This works with numbers, vector arrays, and properties. It's probably not super useful for most people, it's just a utility function used internally that I figured might as well be exported. - All action fields/properties have been sorted in a way to make their order closer to their order in the actual files. It's not going to match exactly, because the actions in the library have all fields and properties from all four of the supported games, and some of the games have things moved around a bit. This order doesn't really affect much in the library or the documentation, but it causes the JSON structure to have the fields/properties in the new order, so it should hopefully make it easier to find and edit unknowns in the JSON.
- Named and documented the
bloom
field (previouslyunk_ds3_f2_4
) in actions 600, 601, 602, 603, 604, 606, and 10012. This is simply a boolean field that toggles the extra bloom effect. (Requires "Effects Quality" to be set to anything but "Low", and thebloomColor
vector field to have a non-zero alpha.) - The behavior of the
unk_ds3_p2_0
property inPointLight
s has been documented. The property is still unnamed. - The
hex
template tag now also accepts strings starting with#
, like#ff0000
. - Fixed the return type of the
hex
template tag. It was previouslynumber[]
, and is nowVector4
like it should be. BasicEffect
andNodeEmitterEffect
can now be constructed without any arguments to make a default effect.
v14.0.0
Highlights
- Added more utility functions:
FXRUtility.box
- Creates an outline of a cuboid shape.FXRUtility.rect
- Creates a rectangle.FXRUtility.ellipse
- Creates an ellipse.FXRUtility.ellipsoid
- Creates three ellipses that form the outline of an ellipsoid.FXRUtility.cylinder
- Creates an outline of a cylinder.FXRUtility.transform
- Wraps a list of nodes in one that has a transform applied to it. The transform is defined by a translation, a direction to align with, and a roll angle. This makes it easier to point nodes in specific directions, or to just move them.FXRUtility.outlineEmitters
- Adds outlines for all node and particle emitters in a node.FXRUtility.animatedNodeRotation
- Creates aNodeSpin
action from a rotation property. Animating the rotation directly is not normally possible, it can only be done by controlling the angular speed. This function makes it possible by converting a rotation property to an angular speed property.
- Added
anyValueDiff
- This function subtracts oneAnyValue
from another. (AnAnyValue
is any scalar or vector value, including all types of properties.) This function simply uses the existinganyValueSum
andanyValueMult
functions to do this, so it works very similarly to those. - The three box size fields in the force volume actions have been converted to a single vector field.
- The fallback for distortion and blur colors when applying a color palette has been changed to just white. This fixes partial palettes making some effects have strange-looking, bright or dark rectangles floating around.
DataAction
s now have a newmeta
property with some information about the action type.meta.isAppearance
- True if the action is an appearance action.meta.isParticle
- True if the action defines a particle appearance.- More is likely to be added to this in the future, if there are other things like this that is useful to have easy access to.
- All of the position offset, speed, and acceleration fields in the GPU particle actions have been converted to vector fields. This got rid of 68 fields in total, so it can simplify things a lot.
v13.0.0
Highlights
- Many new recolor-related features have been added to make recoloring even easier.
- There is now a template tag for converting hex color strings into color vectors for FXRs. This tag is simply called
hex
, so it is now possible to do something likehex`5588ff`
and it would be equivalent to[0.333, 0.533, 1, 1]
. It supports 3-, 4-, 6-, and 8-digit hex values. This can be used anywhere where you would normally put color vectors. - There are now two new functions for generating a color palette from existing effects:
Node.generateColorPalette
- Generates a palette from the node it is called on.Recolor.generatePalette
- Generates a palette from an array of nodes or FXR objects.
- The
Node.recolor
method can now also take a color palette generated from the two functions above. This will apply the palette to the node it is called on, allowing you to copy a set of colors from one effect and apply them to another. This can be very useful if you want to make an effect fit an existing theme or set of effects. - Added a new
Recolor
namespace, which contains many different recolor functions that can be used with theNode.recolor
andDataAction.recolor
methods:Recolor.standardBlend
Recolor.replace
Recolor.multiply
Recolor.add
Recolor.invert
Recolor.grayscale
Recolor.curves
Recolor.mix
Recolor.hueShift
Recolor.replaceHue
Recolor.replaceSaturation
Recolor.colorBlend
Recolor.scaleSaturation
- There is now also a
DataAction.recolorProperty
method that can be used to apply a recolor function to a single color property or color vector field. - Added
Node.colors
andDataAction.colors
generator methods, which yield all unique color values in the node/action.
- There is now a template tag for converting hex color strings into color vectors for FXRs. This tag is simply called
- Added a new
FXRUtility
namespace, which contains methods to simplify various things when creating new effects.FXRUtility.line
- Creates a node with a particle attached that forms a line between two points you give it. This has options for line width, color, and more.FXRUtility.text
- Converts a given string to a node that looks like that string. This has options for font size, text alignment, and more.
- The offset and rotation fields in the node transform actions (35 and 36) have been converted to vector fields.
- The color multiplier and bloom color fields in the LensFlare action (10014) have been converted to vector fields.
- This fixes a bug where these fields were not changed by the recolor functions in the library.
- Converting point lights between DS3 and the other games should now keep the brightness more like the original. DS3 point lights seem to work a bit differently, so it stil won't be perfectly accurate, but it should be much closer than before.
- The rate of time can now be adjusted on nodes or actions using the new scaleRateOfTime method.
- The rate of time in action 10500 is now automatically applied to everything when writing to DS3. This fixes converting effects from newer games to DS3 causing them to play at a different rate than the original effect if the original had a non-unit value for the rate of time.
- The
FXR.toArrayBuffer
method will now throw if the FXR's ID is invalid. - Added an
FXR.name
getter function to FXR objects, which returns a file name for the FXR based on its ID.- For example, an FXR with 1 as the ID would return
f000000001.fxr
. - This is very useful when saving an effect to a file, as now you can just do
await fxr.saveAs(fxr.name, Game.EldenRing)
, for example.
- For example, an FXR with 1 as the ID would return
- Various functions that combine properties will now filter out some keyframes if they are less than a millisecond apart.
- Sequence properties and component sequence properties can now be minified to constant properties if all of their keyframes are the same.
- Some bugs have been fixed, and some improvements have been made to the anyValueSum and anyValueMult functions.
- Various broken links on the documentation site have been fixed.
- The Node.js setup guide has been updated to use the new
@cccode/create-fxr
module to set up the project folder, which eliminates some manual steps that are important to get right. - The editing example in the readme has been updated to use some of the new recolor features instead of doing it the old way.
v12.2.0
Highlights
- The static FXR.read method now returns an instance of the class it was called from instead of the FXR class specifically. This means that it's now possible to extend the class without rewriting the static read method from scratch as long as the constructor is similar.
v12.1.0
Highlights
- The following Node methods now have a new recurse parameter that controls whether or not the method should be applied to descendant nodes:
- scale
- recolor
- remapResources
- The following Node generator methods now have a new recurse parameter that controls whether or not the method should yield objects of descendant nodes:
- walkEffects
- walkActions
- walkProperties
- This new recurse parameter for the Node methods defaults to true, so calling them without it works just like before this change.
v12.0.0
Highlights
- The ComponentSequenceProperty.combineComponents method has been improved so that it should now return an equal HermiteProperty if all of the components have the same number of keyframes and keyframe positions. This method is used internally to, for example, enable correct recoloring of these properties, so the output structure of recolored AC6 effects should now look a lot nicer if they were originally of this type.
- Added .minify methods to all types of properties.
- Modifiers for all properties will be filtered to remove ones that are ineffective, i.e. modifiers that don't change anything about the property, for example a random range modifier with 0 as both the min and max values.
- ValueProperty.minify simply returns a clone of the property with the modifiers filtered.
- SequenceProperty.minify returns a ConstantProperty with the same value and filtered modifiers if the property only has a single keyframe. Otherwise, it returns a clone of the property with the modifiers filtered.
- ComponentSequenceProperty returns a ConstantProperty with the same value and filtered modifiers if all components only have a single keyframe each, and it returns a HermiteProperty if an equivalent one can be constructed with filtered modifiers. Otherwise, it returns a clone of the property with the modifiers filtered.
- The Action.minify and DataAction.minify methods now also minify all properties.
- The FXR.read method now gives a much better error message if given some invalid input.
- Fixed vector fields causing problems in some cases due to not being counted properly. This primarily fixes reading the GPU particle actions, but might have also fixed some other actions.
- Omitted class properties in actions are now handled in a much better way. They will no longer be in the JSON structure for the action class, and they don't cause read actions to end up with some nullish properties.
- Improved how modifiers are combined from or separated into components. This fixes a couple of issues with the combined properties in action 10015.
- Fixed the specular color of spot lights being handled differently depending on the value of the separateSpecular property when writing it for DS3.
- Added an option to the FXR.read method to automatically round floats to 7 significant digits, which should make most floats a lot easier to read for humans.
- Added some missing documentation for the game parameter in the FXR.read function.
- Added a Modifier.isEffective function that can be used to check if a given modifier would have any effect if applied to a property. This is never useful for most people, but it is used internally to filter modifiers when splitting a vector property into its components and when minifying properties.