26.09.22
Compatibility
Changes
If you use the Raycast functions, please check the patch notes for version 26.08.14.2. The Raycast module was changed in a way that WILL NOT work with code written for older versions. This pack is unfortunately not yet tested to be compatible with Minecraft version 26.3. An update to fix this is on the way.
Parse Module Changes
The Parse module now accepts negative inputs for both prepend_position and append_position. These will place the prepend or append text however many spaces to the LEFT if prepending, and to the RIGHT if appending.
Additionally, the parse module will now extend the output value, if the prepend or append positions are larger than the number itself, and will add zeroes to compensate. For example, an input of 123, append of !, and append_position of -2 will result in the output value of 12300!. This can be used conversely with prepending.
This change is intended to allow for more flexible decimal scaling. More detailed information can be found in the README file of the parse module itself.
Elixir Framework / Custom Potion Effects
Although this wasn't publicly alluded to, the Elixir Framework is now finished! This is a module that sets up the framework necessary for fully custom potion effects, including stacking applications, which is difficult to do with just scores. The Elixir Framework lets you apply an effect at any time, and intelligently orders the active applications so that they match vanilla potion effects, e.g., the application with the highest amplifier is the one that's prioritized.
Elixir is written in a way so that it can be easily accessed and used by other datapacks, without having to write anything in the Silver Star Library itself. In order to add your own custom potion effect, you need to create two functions:
- The function that is run on entities which have the custom effect active
- The function that is run when an application expires For example, one of the preset effects, or "statuses" for clarity, is called Lightweight. The active function applies attributes that reduce gravity and knockback resistance, and the expire function removes these attributes.
YOU WILL ALSO NEED TO RUN TWO PREMADE FUNCTIONS: elixir:custom/load_status and elixir:custom/tick_status. As the names indicate, load_status only needs to be run once, and it creates all the scores necessary to run your custom effect, and tick_status MUST be run on every tick (or the status timer will be inaccurate).
elixir:custom/load_status takes two input parameters: source and status. source should be the name of YOUR datapack, or a nickname, anything that will identify where the status is defined. For example, the premade statuses use elixir as the input for source. status, on the other hand, should be the name of the effect itself; for example, lightweight or frostbite or whatever.
IMPORTANT: Both of these input parameters must have valid characters for the purpose of creating scoreboard objectives. Essentially, no spaces, and no custom characters that you couldn't have in the name of another scoreboard objective. The scores created use the format of $(source).$(status).score, so just keep this in mind.
elixir:custom/tick_status takes four input parameters: source, status, status_function, and expire_function. source and status are used identically to how they're used in elixir:custom/load_status.
status_function is the name of the function that contains the actual effects of your custom potion effect. For example, the premade status "lightweight" uses elixir:status/lightweight/main for its status function. The status function will be run on every tick for every entity that has an active application of your status.
expire_function is the name of the function that will be run whenever an application expires, INCLUDING when a higher-amplifier application expires and is replaced by a lower-amplifier application. This should include any code that is run, well, whenever an application expires.
And this is all you have to do! Create your status and expire functions for each custom potion effect you want to create, run elixir:custom/load_status on load and elixir:custom/tick_status on every tick, and your potion effect is up and running.
Deprecated "Status" module
Although the ss_status module still exists, and the code is still there, it should be considered deprecated, and will not receive any more updates or support. Although not all statuses have moved over yet, most of them will be moved over as custom effects in the Elixir module.
Binary Dissection / Bitpacking
Another big update today, covering something I've wanted to automate for a long time: Bitpacking, using an integer to store a bunch of true/false conditions by reading it as a binary number.
What this does is allows you to store up to 32 boolean conditions, 0-31, in a single score, by adding a value to the score that represents an exponential multiple of 2. For example, if you want to set condition #10 and condition #14 to true, and leave all others false, the disambiguation value would be set to 17408 (2^10 + 2^14), which can only be created when those two conditions are true. The Binary Dissection file then dissects this value, reads that conditions #10 and #14 are true, and executes functions based on those files.
Condition 31 is stored by making the dissection value negative.
The function is stored at ss_lib:binary/dissect. It takes three inputs: score, which refers to the score that will be read and dissected, namespace_1, which is the first part of the executed functions' namespace, and namespace_2, self-explanatory. The score input itself will not be changed, rather, it's copied over into the generic_a score, which is used for the dissection. A sample of the code is below:
$execute as @s[scores={generic_a=1..}] run function $(namespace_1)0$(namespace_2)
scoreboard players remove @s[scores={generic_a=1..}] generic_a 1
This means that, if your score is over the exponential multiple of 2 (in this case, 2^0, which is 1), it runs a function with an ID based on the EXPONENT required to get to that number. So, this particular line of code runs a function with an ID of 0.
This ID can be used a couple different ways. If you want to execute a whole function, for example, you can have a namespace_1 of example:function/id_ and a namespace_2 that is just empty, or "". This would execute the function example:function/id_0 if condition #0 is true.
You can also pass it as an input to another function, for example, with a namespace_1 of example:function/boolean {id: and a namespace_2 of }. This will execute the function example:function/boolean {id:0}.
Conditions can be written to the disambiguation value by using the following function: ss_lib:binary/assign. It takes two inputs: score and id. score is the score that will be written to, and id is a value from 0 to 31, which represents which condition will be written as true. Conditions are removed with the function ss_lib:binary/unassign. Assignment will only assign the condition if it is not already true, and unassign will only unassign if the condition is true. The function ss_lib:binary/toggle can be used to toggle conditions.
Other Changes
The ss_lib:fetch/absorption function now takes a new input parameter: bypass_check, which is boolean (true/false). Setting bypass_check to true means that this function will fetch the player's absorption, even if it was already fetched this tick. This allows you to be certain that the absorption value you have is current, for example, if you've recently dealt damage or given more absorption hearts in this tick. Generally, you can safely set this to false, and at worse, your absorption value will take an extra 0.05 seconds to catch up.
This function still takes s as an input parameter for the selector, so it now takes two input parameters in total: s and bypass_check.

