Skip to content

Releases: EvenTorset/fxr

v17.0.0

12 Nov 19:44
fa5149a
Compare
Choose a tag to compare
  • Named and documented three actions:
    • 700 - SimulateTermination
    • 701 - FadeTermination
    • 702 - InstantTermination
  • Named and documented some fields:
    • Action 128 (NodeAttributes): unk_ds3_f1_3 is now depthBias.
    • Action 609 (PointLight): unk_ds3_f2_24 is now maxViewDistance.
  • 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 to ActiveTime 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.
  • 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 the RootNode class to termination to match the actions it can be set to.
  • Renamed BlendMode.Screen to BlendMode.Unk7. The old name was based on some old, and apparently incorrect, documentation. This blend mode is seemingly identical to BlendMode.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, like BlendMode, 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.
  • DataActions 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 and particleWidth 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 in NodeAttributes actions not being scaled when using the scaleRateOfTime 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

13 Sep 21:38
13d45e6
Compare
Choose a tag to compare
  • 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 and sortComponentKeyframes 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 to unk_ac6_f1_2. The old name did not match the field's index.
  • Fixed the argument for some properties:
    • color3 in PointSprite is now ParticleAge (was EffectAge)
    • lengthMultiplier in Line is now ParticleAge (was EffectAge)
    • lengthMultiplier in QuadLine is now ParticleAge (was EffectAge)
    • widthMultiplier in QuadLine is now ParticleAge (was EffectAge)
    • 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

01 Sep 03:46
3b833ac
Compare
Choose a tag to compare
  • Added a getResources method to nodes. This does the same thing that the FXR 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

01 Sep 01:51
7fffa9f
Compare
Choose a tag to compare

Highlights

  • Added a depth argument to the clone method on nodes that controls how many levels of descendants to clone. It defaults to Infinity (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

28 Aug 15:12
5c28cc8
Compare
Choose a tag to compare

Highlights

  • Added Game.Heuristic, which can be used with FXR.read to let the library figure out what game an FXR file is for.
    • This is now the default game value for the FXR.read function. (Was Game.EldenRing previously.)
    • FXR objects now have a new gameHint property that stores what game the file was parsed as. It defaults to Game.Generic, and the only way to set it is using the FXR.read function. New effects created with new FXR or FXR.fromJSON will have the default value. The hint will be Game.Heuristic if the FXR.read function could not determine what game it was from.
    • The FXR.toArrayBuffer and FXR.saveAs methods now use Game.Heuristic as the default game value too (was also Game.EldenRing previously), which will cause them to use the gameHint as the game, unless the hint is Game.Heuristic. If the hint is Game.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 affect FXR.toArrayBuffer and FXR.saveAs.
  • 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 the ValueType 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 (previously unk_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 the bloomColor vector field to have a non-zero alpha.)
  • The behavior of the unk_ds3_p2_0 property in PointLights 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 previously number[], and is now Vector4 like it should be.
  • BasicEffect and NodeEmitterEffect can now be constructed without any arguments to make a default effect.

v14.0.0

07 Aug 17:25
2300a40
Compare
Choose a tag to compare

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 a NodeSpin 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 one AnyValue from another. (An AnyValue is any scalar or vector value, including all types of properties.) This function simply uses the existing anyValueSum and anyValueMult 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.
  • DataActions now have a new meta 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

04 Aug 02:40
6ba3684
Compare
Choose a tag to compare

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 like hex`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 the Node.recolor and DataAction.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 and DataAction.colors generator methods, which yield all unique color values in the node/action.
  • 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.
  • 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

14 Jul 07:23
d42dc28
Compare
Choose a tag to compare

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

11 Jul 02:41
fbce654
Compare
Choose a tag to compare

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

27 Jun 22:08
ed8fff0
Compare
Choose a tag to compare

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.