[Mike's suggestion. (Of course. Why's he get all the good ideas? :) )]
Here's a radical thought: how about eliminating vector-based mixtures [i.e., liquids which keep track of their components (in a vector) as per the present mixture model], and allowing only pure liquids? I don't mean that we prohibit mixing two unlike liquids - instead, I mean that we require the author to define a "closed" chemical algebra: for every pair of pure liquids that can be mixed, a chemistry operation must be defined that yields a new pure liquid that's part of the set of all possible liquids in the game.
This might sound like it would turn rapidly into an intractable combinatoric explosion, but I think it might actually work well in practice. Consider some examples:
If you have "water" and "oil" liquids that you can mix, you'd have to define a "water and oil mixture" liquid as well to represent the combination - it's not a vector of water and oil subliquids, but rather a whole new liquid class with its own unique characteristics.
(A side benefit is that this class can properly handle the characteristics of the combination - our oil+water object can describe the oil and water as separating into layers, for example.)
If you want to mix a "water+oil" object with water or with oil, you get another "water+oil" object, so our algebra is closed - mix any two elements from the set and you get an element from the set. (An individual water+oil object could keep track internally of the relative quantities of its subcomponents, of course.)
If you have "water" and "purple dye" liquids, you could have a "water+dye" object that properly deals with diluting the color.
Mixing "water" and "water+dye" yields another "water+dye" with further diluted color; mixing "water+dye" and "water+dye" yields "water+dye" with volume-weighted average color. Or, you could have
a general "colored water" liquid with a parameterized RGB color and dye concentration, and mixing two of these yields a new object of the same type that adjusts its color and concentration by doing a
volume-weighted average the inputs. Again, the algebra is closed without combinatoric explosion.
The more I think about it, the more I like this approach. Note that this doesn't preclude an author from implementing a vector-based mixture mechanism - it just moves it out of the basic framework,
which means that the framework doesn't have to make assumptions about how properties combine in mixtures. If the library provided the basic "colored water" class described above, I think you'd have
most if not all of the functionality that the vector-based mixture mechanism would be capable of at the library level, but it would be a heck of a lot simpler.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I don't think this is a good approach - as I see it, it _will_ cause an explosion of classes, to handle all possible combinations. It'll also be prone to bugs - if the author forgets just one possible combination, the library would have nothing to do but to complain with a nasty "I don't know how to mix these two liquids" message.
Furthermore, I think it's important to keep the distinction between what the player can percept as different liquids, and what he can't.
In my aproach, oil and water would separate into two different Liquid objects, making the player able to type "x water" or "x oil". However, if the water was tainted with poison, the player should not be able to type "x poison" - because the poison and the water appears as one liquid to him.
That's the whole idea of the liquid component framework.
Having imperceptible liquid-parts will be common enough that the library has to deal with it, and components are the best approach there, I think.
> the framework doesn't have to make assumptions
> about how properties combine in mixtures
It wouldn't have to - there'd be a set of default implementations for colour, etc.
Any properties defined by the author would have author-defined mixing behaviour.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>I don't think this is a good approach - as I see it, it
>_will_ cause an explosion of classes, to handle all
>possible combinations.
The number of needed combinatorial classes does indeed rise somewhat sharply. With two elements, we need only one combination class; with three elements, we need four combination classes (a+b, a+c, b+c, a+b+c); with four elements we need ten combination classes; with five elements we need twenty combination classes.
This technique might nevertheless work well in practice. If the user wants two or three liquids, he has a simple model. And even if the user wants to make a chemistry set, this setup might still be less complicated.
There are some nice things about this model, but the main problem to which this is a solution is this: how are combinations are supposed to handle actions which their components know how to handle? How do actions get overridden or modified by other components in the mixture, for example? How is it determined which action method gets called when two or more components have action methods? If we have four or five elements, this is likely to be more straightforward with 10 or 20 combinations, each of which has its own unique action routines, than it will be if we pass all action calls through a mixture handler to decide which action routine to choose, which then presumably checks some properties in the components to see which component governs the action (at this specific component ratio), which then calls the action which again has to check for the presence and relative volume of other components before deciding what action to make. (It wouldn't always be so complicated, but also I am probably missing some steps, and most of this has to be done thrice so we can get the right verification and check routines for each action.)
So I'm agnostic.
>In my aproach, oil and water would separate into
>two different Liquid objects, making the player able
>to type "x water" or "x oil". However, if the water
>was tainted with poison, the player should not be
>able to type "x poison" - because the poison and the
>water appears as one liquid to him.
Yes, that's true. Presumably the combination class PoisonWater would not have "poison" as one of its nouns or adjectives, and would be described so as to conceal the poison in whatever desirable way.
>> the framework doesn't have to make assumptions
>> about how properties combine in mixtures
>It wouldn't have to - there'd be a set of default
>implementations for colour, etc.
>Any properties defined by the author would have
>author-defined mixing behaviour.
Good point.
What concerns me most about the components solution is the difficulty involved in getting to the right (verify &c. and) action routines. I think the user would prefer to have this stuff defined in a single liquid object, rather than in a component object which he then has to instruct how to get along with the handler and the other component objects.
If we decide to go the component route, I think we might still provide a mechanism by which the user can simply substitute a multi-component liquid object with a single-component liquid object which he has coded to behave as it should based on the ratio of its components.
Either way, we need to keep track of which components go into the new liquid, so that action routines can refer to the relative volume of the components when they decide, for example, how much poison is being ingested.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>[This solution is] also be prone to bugs - if the
>author forgets just one possible combination, the
>library would have nothing to do but to complain
>with a nasty "I don't know how to mix these two
>liquids" message.
We could make a debug preinit object which complained if there were any combinations left out of account by the author.
If the author doesn't heed the complaint, presumably some "You can't mix those two liquids." message is desired.
I don't know if this will make things more complicated for the user. My feeling is that the "pure liquid" model will make more sense to the user, who would otherwise have to resolve conflicting action methods through the component handler rather than defining the right behavior directly in the liquid.
The component liquids idea sounds like it would be more streamlined in the more complicated cases, but I need to think about it some more before I can decide.
I mailed Mike about our discussion. Maybe he'll have some further suggestions.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
[Mike's suggestion. (Of course. Why's he get all the good ideas? :) )]
Here's a radical thought: how about eliminating vector-based mixtures [i.e., liquids which keep track of their components (in a vector) as per the present mixture model], and allowing only pure liquids? I don't mean that we prohibit mixing two unlike liquids - instead, I mean that we require the author to define a "closed" chemical algebra: for every pair of pure liquids that can be mixed, a chemistry operation must be defined that yields a new pure liquid that's part of the set of all possible liquids in the game.
This might sound like it would turn rapidly into an intractable combinatoric explosion, but I think it might actually work well in practice. Consider some examples:
If you have "water" and "oil" liquids that you can mix, you'd have to define a "water and oil mixture" liquid as well to represent the combination - it's not a vector of water and oil subliquids, but rather a whole new liquid class with its own unique characteristics.
(A side benefit is that this class can properly handle the characteristics of the combination - our oil+water object can describe the oil and water as separating into layers, for example.)
If you want to mix a "water+oil" object with water or with oil, you get another "water+oil" object, so our algebra is closed - mix any two elements from the set and you get an element from the set. (An individual water+oil object could keep track internally of the relative quantities of its subcomponents, of course.)
If you have "water" and "purple dye" liquids, you could have a "water+dye" object that properly deals with diluting the color.
Mixing "water" and "water+dye" yields another "water+dye" with further diluted color; mixing "water+dye" and "water+dye" yields "water+dye" with volume-weighted average color. Or, you could have
a general "colored water" liquid with a parameterized RGB color and dye concentration, and mixing two of these yields a new object of the same type that adjusts its color and concentration by doing a
volume-weighted average the inputs. Again, the algebra is closed without combinatoric explosion.
The more I think about it, the more I like this approach. Note that this doesn't preclude an author from implementing a vector-based mixture mechanism - it just moves it out of the basic framework,
which means that the framework doesn't have to make assumptions about how properties combine in mixtures. If the library provided the basic "colored water" class described above, I think you'd have
most if not all of the functionality that the vector-based mixture mechanism would be capable of at the library level, but it would be a heck of a lot simpler.
I don't think this is a good approach - as I see it, it _will_ cause an explosion of classes, to handle all possible combinations. It'll also be prone to bugs - if the author forgets just one possible combination, the library would have nothing to do but to complain with a nasty "I don't know how to mix these two liquids" message.
Furthermore, I think it's important to keep the distinction between what the player can percept as different liquids, and what he can't.
In my aproach, oil and water would separate into two different Liquid objects, making the player able to type "x water" or "x oil". However, if the water was tainted with poison, the player should not be able to type "x poison" - because the poison and the water appears as one liquid to him.
That's the whole idea of the liquid component framework.
Having imperceptible liquid-parts will be common enough that the library has to deal with it, and components are the best approach there, I think.
> the framework doesn't have to make assumptions
> about how properties combine in mixtures
It wouldn't have to - there'd be a set of default implementations for colour, etc.
Any properties defined by the author would have author-defined mixing behaviour.
>I don't think this is a good approach - as I see it, it
>_will_ cause an explosion of classes, to handle all
>possible combinations.
The number of needed combinatorial classes does indeed rise somewhat sharply. With two elements, we need only one combination class; with three elements, we need four combination classes (a+b, a+c, b+c, a+b+c); with four elements we need ten combination classes; with five elements we need twenty combination classes.
This technique might nevertheless work well in practice. If the user wants two or three liquids, he has a simple model. And even if the user wants to make a chemistry set, this setup might still be less complicated.
There are some nice things about this model, but the main problem to which this is a solution is this: how are combinations are supposed to handle actions which their components know how to handle? How do actions get overridden or modified by other components in the mixture, for example? How is it determined which action method gets called when two or more components have action methods? If we have four or five elements, this is likely to be more straightforward with 10 or 20 combinations, each of which has its own unique action routines, than it will be if we pass all action calls through a mixture handler to decide which action routine to choose, which then presumably checks some properties in the components to see which component governs the action (at this specific component ratio), which then calls the action which again has to check for the presence and relative volume of other components before deciding what action to make. (It wouldn't always be so complicated, but also I am probably missing some steps, and most of this has to be done thrice so we can get the right verification and check routines for each action.)
So I'm agnostic.
>In my aproach, oil and water would separate into
>two different Liquid objects, making the player able
>to type "x water" or "x oil". However, if the water
>was tainted with poison, the player should not be
>able to type "x poison" - because the poison and the
>water appears as one liquid to him.
Yes, that's true. Presumably the combination class PoisonWater would not have "poison" as one of its nouns or adjectives, and would be described so as to conceal the poison in whatever desirable way.
>> the framework doesn't have to make assumptions
>> about how properties combine in mixtures
>It wouldn't have to - there'd be a set of default
>implementations for colour, etc.
>Any properties defined by the author would have
>author-defined mixing behaviour.
Good point.
What concerns me most about the components solution is the difficulty involved in getting to the right (verify &c. and) action routines. I think the user would prefer to have this stuff defined in a single liquid object, rather than in a component object which he then has to instruct how to get along with the handler and the other component objects.
If we decide to go the component route, I think we might still provide a mechanism by which the user can simply substitute a multi-component liquid object with a single-component liquid object which he has coded to behave as it should based on the ratio of its components.
Either way, we need to keep track of which components go into the new liquid, so that action routines can refer to the relative volume of the components when they decide, for example, how much poison is being ingested.
>[This solution is] also be prone to bugs - if the
>author forgets just one possible combination, the
>library would have nothing to do but to complain
>with a nasty "I don't know how to mix these two
>liquids" message.
We could make a debug preinit object which complained if there were any combinations left out of account by the author.
If the author doesn't heed the complaint, presumably some "You can't mix those two liquids." message is desired.
I don't know if this will make things more complicated for the user. My feeling is that the "pure liquid" model will make more sense to the user, who would otherwise have to resolve conflicting action methods through the component handler rather than defining the right behavior directly in the liquid.
The component liquids idea sounds like it would be more streamlined in the more complicated cases, but I need to think about it some more before I can decide.
I mailed Mike about our discussion. Maybe he'll have some further suggestions.