Skip to content

Custom Generic Reactions

petrolpark edited this page Jul 18, 2024 · 11 revisions

The information on this page will become irrelevant in an upcoming update due to a rewrite of the chemistry API!

This whole thing is going to be pretty chemistry-intensive. To understand more about this subject area I recommend such platforms as a college education.

Most Reactions in Destroy are 'hard-coded' - the reactants and products are unambiguous, certain ("specific") species, for example:

Methyl Acetate + Carbon Monoxide -> Acetic Anhydride

All three species here have defined structures. Adding unambiguous Reactions to your Destroy add-on is easy and there is sufficient documentation in the source.

However, organic chemistry is modular and so Reactions can be 'generic' - taking place between any members of homologous series (groups of chemicals containing the same motif). An example of a generic Reaction would be:

Carboxylic Acid + Alcohol -> Ester + Water

In this example, the first three species are not specific molecules, but rather entire sets - there are an infinite number of molecules which are carboxylic acids. The way Destroy deals with Reactions like these is by identifying 'Groups' - analogous to functional groups in chemistry. Carboxylic acids are all Molecules containing the 'Carboxylic Acid Group'. If you haven't already, read about implementing Groups before continuing.

Implementation

To add your own custom Reactions, you must create a class extending either SingleGroupGenericReaction or DoubleGroupGenericReaction, which are actually more akin to reaction generators. These classes have one mandatory method, generateReaction. This method has one or two parameters respectively, which are of the class GenericReactant<T>.

GenericReactant<T>s contain a Molecule and a Group of class T. When these objects are passed to generateReaction they contain the specific Group which is participating the Generic Reaction and the whole Molecule. The job of generateReaction is to return a Reaction object with specific reactants, products and kinetic constants.

I will use the example of the substitution of a chloride for a hydroxide, which would be declared thusly:

//(1) naming convention is plural of Generic Reaction                 (2) generic class is reacting Group
public class HydroxideSubstitutions extends SingleGroupGenericReaction<ChlorideGroup> {

    //(3) constructor supers supplier
    public HydroxideSubstitutions(Supplier<ChlorideGroup> supplier) {
        super(supplier)
    };
}

You can see that (1) the conventional name is the plural of the type of reaction this reaction generator generates, (2) that the generic class of the parent should be the type of Group which participates in this Reaction, and (3) that the constructor takes a Supplier of this Group, which it should just super.

The story is not so different for Generic Reactions which feature two functional Groups.

public class Esterifications extends DoubleGroupGenericReaction<AlcoholGroup, CarboxylicAcidGroup> {

    public Esterifications(Supplier<AlcoholGroup> alcoholSupplier, Supplier<CarboxylicAcidGroup> carboxylicAcidSupplier) {
        super(alcoholSupplier, carboxylicAcidSupplier);
    };
}

As for the contents of generateReaction, there is no boilerplate to go over, but note that you will find the methods of ReactionBuilder and Formula useful - I have hopefully given sufficient information for the use of them in their JavaDocs. For the hydroxide-substitution-of-chlorides example, check the source.

Registering

Finally, so Destroy actually knows your Generic Reaction exists, you will need to instantiate it. For this, I would recommend adding this parameterless constructor to your Groups:

public class SomeGroup extends Group {

    public SomeGroup() {
        super();
    };

    //...

}

Then instantiate your Generic Reaction in an index you register after all your custom Group Finder and Molecules:

public class MyModGenericReactions {

    public static final MyGenericReactions MY_GENERIC_REACTIONS = new MyGenericReactions(MyGroup::new);

    public static void register() {};

}

No, it's not a pretty way of doing it, but it's very late and I'm tired.

For reference, your main mod file should look like this (i.e. have all these things registered in this order):

    //...
    MyModGroupFinder.register();
    MyModMolecules.register();
    MyModReactions.register();
    MyModGenericReactions.register();
    //...

For Developers

   FROWNS
   Chemistry Definitions
   Custom Groups
   Custom Generic Reactions

Changelogs

It'll Get Beta

   0.0.1
   0.0.2
   0.0.3
   0.0.4
   0.0.5
   0.0.6
   0.0.7
   0.0.8

Beta Still

   0.1.0-snapshot-1
   0.1.0-snapshot-2
   0.1.0-snapshot-3
   0.1.0-snapshot-4
   0.1.0-snapshot-5
   0.1.0-snapshot-6
   0.1.0-snapshot-7
   0.1.0-snapshot-8
   0.1.0-snapshot-9
   0.1.0-snapshot-10

Clone this wiki locally