Open byorgey opened 3 years ago
If we end up switching to a specific entity
type instead of just using string
, as described in #455, the types of a bunch of the above functions should of course change to match.
Given an entity
type, and the fact that entities must be immutable, as discussed in #455 , here's my current thinking on the types the above commands should have:
insert : entity -> entity -> cmd entity
will insert the first entity into the second, throwing an exception if you don't have either one, or if the second entity is not a container. It returns a new reference to the container entity, since entity values are immutable.remove : entity -> entity -> cmd entity
for : entity -> (entity -> b -> b) -> b -> b
. Note that unpack : entity -> cmd entity
can be implemented in terms of for
: unpack = \ctr. for ctr (\item. \unpackRest. ctr' <- unpackRest; remove item ctr') (return ctr)
We will also need versions that don't do anything to your inventory but simply describe a container with some entity inserted or removed, like inserted : entity -> entity -> entity
and removed : entity -> entity -> entity
.
Would it be okay to consider the container placed in the current cell available just like those in the inventory? :thinking:
With scan
and atomic
, I think this could be pretty useful to create fast robot pipelines.
If I have robots running around my future base storage, I do not want them to pick up boxes and then not return them. :sweat_smile:
Hmm, I like that idea, though I'm not sure how exactly it would work in practice. Maybe it would be cleaner/less confusing to just have special commands for manipulating a container in the current cell?
We will also need versions that don't do anything to your inventory but simply describe a container with some entity inserted or removed, like
inserted : entity -> entity -> entity
andremoved : entity -> entity -> entity
.
@byorgey why? We now have itX
variables to make it easy to access past results. I can not imagine a scenario in which a "dry run" of the operation would be necessary. I would prefer if we could avoid functions like maked
, painted
, described
, etc. for each of the modifying entity functions.
It would be harder for the player to understand and for us to maintain twice as many entity functions.
I don't really like the idea of having two versions of every command either, but I haven't had any better ideas. The purpose of inserted
, removed
, etc is not for doing dry runs, but rather to be able to describe entities, even ones you don't have. For example if you're looking for a box that contains a tree, you can search for an entity equal to inserted (entity "tree") (entity "box")
or something like that.
I'm very open to other ideas.
Crazy idea: what if we make a function something like hypothetical : cmd entity -> entity
(or perhaps asif
) which runs the given command in a hypothetical inventory with infinite copies of everything, like in creative mode? It would fail if the command tries to do anything like move
. So if you want to describe a box containing a tree, you could say hypothetical (insert (entity "tree") (entity "box"))
. Then we don't need any of the Xed
variants.
I assumed we would provide predicates for testing that a container contains something? Why would you compare hypothetical entities?
I don't know, a box containing a tree was just a random example. Sure, we can have predicates for testing that a container contains something. But the bigger point is that you should be able to create entity
values representing descriptions of entities you don't have in your inventory. Or even if you could potentially have them, you might want to be able to talk about certain entities without actually modifying your inventory to construct them. #455 has some examples, like if you want to write a program that says "move
until you see a purple tree" you have to be able to talk about purple trees even though you don't have any at the moment.
Every entity is in theory capable of holding an inventory of other entities, but at the moment we only take advantage of this with robots themselves. However, the idea has always been to have other entities besides just robots that can contain other entities. As a first example the plan is to make a
box
capable of holding (possibly a limited number of) other entities. This will be useful for several reasons:give
command takes a single tick to execute, so it takes a while to give a bunch of entities one at a time. Using a box, you can instead put the items you want to give into a box (putting an item in a box will not take a tick), and then justgive
the box in one tick.So we need some commands for manipulating container entities; here's what I propose.
container
property, which governs entities that can contain other entities.insert : string -> string -> cmd ()
will insert the first entity into the second, throwing an exception if you don't have either one, or if the second entity is not a container.remove : string -> string -> cmd ()
is the converse. Note that the entity to be removed gets taken out of the container and placed in your inventory.unpack : string -> cmd ()
unpacks a container, rendering it empty and placing its entire contents in your inventory. This way you don't have to know in advance what you expect to get in the box.for : string -> (string -> cmd ()) -> cmd ()
.grabber
.