Equivalent to summoning stacked (riding) mobs?

What would be the equivalent programmatic process in Sponge to create, for example,a pig riding a bat at location x,y,z …which is the command
/summon Pig x y z {Riding:{id:Bat}}

Has been discussed here:


Oh wait riding… . whoops …

I guess this is what your looking for:

okay, so the idea is simply spawn a bat with the special data on it, I guess?
(Well, having a pig object as well before that)

So I tried the following code, but I get “NoSuchElementException: No value present” for both code attempts to set the key… Looking at the “Data manipulator checklist” it appears that the passengerdata is not implimented yet, explaining the error?

Once it is implimented, would this code work, or is something missing still?? Which of the two methods - getorcreate(class) or the straight offer(k,v) method is appropriate to use in this case, and why is the other method not, out of curiosity :slight_smile: (This is my biggest challange with the data manipulator understanding, is this whole involved-construct-requiring-knowing-the-class-name-and-a-lot-of-optionals vs the straight-in key,value offer, what the difference is for using one over the other, when does one work vs not)

 public boolean doFlyingPigSpawn(Location<World> location, Entity flierpig) {
        Bat batMobile;
        Optional<Entity> entityOptional =
            location.getExtent().createEntity(EntityTypes.BAT, location.getPosition());
        if (entityOptional.isPresent()) {
            batMobile = (Bat) entityOptional.get();
            // which of these - getOrCreate()... vs offer() is the right way?
            batMobile.getOrCreate(PassengerData.class).get().set(Keys.PASSENGER, flierpig);
            batMobile.offer(Keys.PASSENGER, flierpig);
            // neither work , "no such element present, no value present" for both
            location.getExtent().spawnEntity(batMobile, Cause.of(this));
            return true;
        return false;


For your code: If you are just setting one value, use

batMobile.offer(Keys.PASSENGER, flierpig);

Getting, changing and offering a DataManipulator and just offering the Key and a value are both valid. A Key will only be accepted if the corresponding DataManipulator is supported and vice versa.
The differences (performance-wise) are small.
Each time you call offer(key, value), a lookup is performed to locate the appropriate ValueProcessor. Then the offered value is validated, and - if valid - set.
Each time you call offer(dataManipulator), a lookup is performed to locate the appropriate DataProcessor. Then all data on the passed DataManipulator is validated, and, if valid, set.

Performance differences are neglectable, so in most cases you’ll be better off just setting each key individually as that requires less code.


  • You want to pass the data on somewhere along your / another plugin’s API. A DataManipulators benefit is that it retains some more context than just blank numbers. And it is able to perform validation (e.g. against accidently setting negative health)
  • You want to store the data for later use. Example: A mini game uses the players hunger bar to represent a resource for the game. Therefore it stores each players FoodData on entering the game and restores it when the game is finished (or the player disconnects).
  • You want to serialize the data. This is best done on DataManipulators as they can be serialized to a DataContainer which could then be written to a configurate node using the ConfigurateDataTranslator.

tl;dr: when in doubt, use offer(key, value). its shorter.

That starts to take some of the cloudiness out of the system now, thanks.
Is the following summary understanding basically correct?
offer keys- quick and dirty, but limited to what is hard-coded as connected to the object (IE a granite block being a type of stone)

offer datamanipulator – same as above, and more, adding foreign state/properties not intrinsically inherant to the object, more complex than single data…

There is only one case where a data manipulator can be applied but a key cannot: adding custom data manipulators to an existing data holder for the first time.
If the custom data manipulator is added, the keys used by the data manipulator can also be used directly.

Also, there is nothing dirty about keys. Our keys are produced by a KeyFactory adhering to universally recognised health and safety standards. However, intergalactic law requires me to state that it is not suitable for the production and/or processing of FLARD and/or any FLARD based products.