Skip to content

Conversation

@oversword
Copy link
Contributor

@oversword oversword commented Jun 25, 2021

On BlS we have been re-working the gravelsieve, I think it's time to put these changes back up to the original repo if possible.

Ideally these changes should not change the default behaviour, or run any significantly different code if the settings have not been changed.

I do not expect this to be merged soon, or without discussion, as a lot has changed for a variety of reasons and some of it may not be desirable.

Changes:

  • Licence and credits added - unsure if these are really needed here...
  • An API file has been created for registering and removing transformations from the gravelsieve
  • Interoperability has been extracted from the init file (where possible) and moved to separate files
  • A unified inventory craft type has been added for sieving, with the registration API registering these transformations automatically
  • A probability API has been added for dealing with tables of probabilities
  • Added tests using my test suite "mod"

Output Types:

  • Relative
    The default output type, if you are to register four relative outputs for an input, all with the same probability, say 2, they will all be proportioned to "fill the space", in this case they will all have a 1/4 chance of occurring. In this sense, a relative probability is more like a "weight" than a true 0-1 probaility
  • Fixed
    This must be a true 0-1 probability, it will not change based on the probability/weight of other outputs, if these add up to more than 1 you may find the outputs are not what you expected
  • Dynamic
    These will also be true 0-1 probabilities, but they can be dynamically generated at runtime based on the situation - for instance, you could pass in player data or the surrounding nodes to modify the probability depending on them. Instead of registering a number probability, register a function that returns a number when called, you can do whatever calculation is required inside this function to produce unique probabilities.

Run order:

  1. First, fixed probabilities are checked, if the random selector is within the fixed probability total one of them will be chosen
  2. Next, dynamic probabilities are checked, if the random selector is within any of the values the generators return then one of these will be chosen
  3. Finally, if nothing has been chosen, a relative output will be chosen with a new random selector, scaled to match the total probability of the relative outputs

API:

  • gravelsieve.api.after_ores_calculated(callback)
    Will call callback once all mods have loaded and the rarity of ores has been calculated - this is useful if you want to proportion your transformations based on the rarity of ores

  • gravelsieve.api.reset_config()
    Will reset all configs, should probably only be used for testing purposes

  • gravelsieve.api.register_input(input_name[, outputs])
    Register an input item, outputs is optional, it allows you to register outputs while registering the input. outputs can be:

    • A string, this will be the only output for the input (so far)
    • A 1D table of string=probability pairs, these will become the "relative" output of the input
    • A 2D table of output_type={string=probability} pairs, this will set outputs by their output type
      Notes:
    • You cannot register an input via this method twice
    • You cannot register an input item that does not exist
  • gravelsieve.api.override_input(input_name[, outputs])
    Delete all outputs for the given input and replace them with the new outputs (if given)

  • gravelsieve.api.remove_input(input_name)
    Delete all outputs for an input and un-register it

  • gravelsieve.api.swap_input(input_name, new_input_name)
    Swaps all the outputs registered for input_name and registers them for new_input_name

  • gravelsieve.api.get_outputs(input_name[, output_type])
    Get the table of outputs for a given input, if output_type is given it will only give the table for that type

  • gravelsieve.api.get_output(input_name, output_name)
    Checks if output_name is one of the outputs for input_name, returns the probability and output type if found

  • gravelsieve.api.register_output(input_name, output_name, probability[, output_type])
    Registers an output for a given input_name with the given probability for output_type if given, if not it will be the default output type (relative)

  • gravelsieve.api.register_relative_output(input_name, output_name, probability)
    Registers an output for a given input_name with the given probability for the relative output type

  • gravelsieve.api.register_dynamic_output(input_name, output_name, probability)
    Registers an output for a given input_name with the given probability function for the dynamic output type

  • gravelsieve.api.register_fixed_output(input_name, output_name, probability)
    Registers an output for a given input_name with the given probability for the fixed output type

  • gravelsieve.api.override_output(input_name, output_name, probability, output_type)
    Removes and re-registers an output with the new probability and output type

  • gravelsieve.api.remove_output(input_name, output_name)
    Un-registers an output from an input

  • gravelsieve.api.swap_output(input_name, output_name, new_output_name)
    Swaps one output for another in the given input

  • gravelsieve.api.can_process(input_name)
    Checks if an input is registered with the gravelsieve

  • gravelsieve.api.get_random_output(input_name[, dynamic_args_generator, args])
    Chooses a random output for a given input, dynamic_args_generator and args are only required if you're using the dynamic output type, dynamic_args_generator(args) will produce the first argument to be passed into the value generator function that should have been set as the dynamic probability value, they are passed in to avoid calling them when not needed - to avoid any unneeded effort from complex dynamic calculations that might not actually be used.

Probability API:

  • gravelsieve.api.get_ore_frequencies()
    Calculates the rarity of ores in the world - should be the same as existing logic

  • gravelsieve.api.report_probabilities(probabilities)
    Prints out probabilities as a list of 1/n, separated from the original ore frequencies functionality

  • gravelsieve.api.sum_probabilities(probabilities)
    Adds up all probabilities in a table of item=probability pairs

  • gravelsieve.api.scale_probabilities_to_fill(probabilities, fill_to)
    Multiplies all probabilities in a table of item=probability pairs so that, when summed, they add up to the given fill_to level - useful for turning a bunch of "weights" into true probabilities by scaling them to fill 1

  • gravelsieve.api.scale_probabilities(probabilities, scale_factor)
    Multiplies all probabilities in a table of item=probability pairs but the given scale_factor

  • gravelsieve.api.merge_probabilities( ... )
    Merges multiple tables of item=probability pairs, adding up probabilities if they exist in more than one table

@joe7575
Copy link
Owner

joe7575 commented Jun 27, 2021

Oh holy shit ....this is more than a simple PR :)
Give me some time to check this

@oversword
Copy link
Contributor Author

Give me some time to check this

Absolutely, please take your time, there is no urgency to fix any bug, this code just adds features, and we are already running it on our server so there is no pressure of people depending on you!

@joe7575 joe7575 added the wontfix This will not be worked on label Sep 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants