Interestingly, I've just implemented such a library for Inform, so
I've been thinking about just this problem. I've not used the ordinary
containment system for liquids, so I don't need to dynamically allocate
objects: one prototype object is needed for each different liquid in the
game. An amusing set of parsing rules moves the names of liquids into
scope at the right times.
Broadly speaking, I whittled down the requirements to a minimum:
drinking, filling a container, pouring onto something, and pouring away.
Each liquid-container has a capacity, which can be "infinite" (e.g.
a fountain is inexhaustible, a bottle is not).
Finally, actions are generated when liquid 1 is added to liquid 2
(and this is not assumed to be symmetrical), when a liquid is added
to a solid (e.g. water added to a beanstalk plant) and vice versa
(e.g. a lump of sodium dropped into a bucket of water). These last
three can all happen in various different ways, so I think it's useful
that the rules can be written once only. For instance, the prototype
"water" object contains a generic rule for what happens when water is
added to oil.
This is minimal, but I can't think of any way it's restrictive, given
the usual library rules. It more or less works now; I'll post it soon
for anyone who's interested.
Graham Nelson
Oxford, UK