How to pick up object with spacebar?

How to make an object that can be picked up with a spacebar? Like this?
Gather Town pick up object

1 Like

Same question here too…

The answer here is through custom extensions using the websocket API. You can use the spacebar input to trigger a check for what a player is standing nearest to, then add that image to their character as a held item. Then you do the reverse to put it down. There is not currently default support for spacebar interactions outside of the Escape Room.

2 Likes

Thanks Bill_Uncork-it! Where can I learn about the websocket api. Appreciate the pointers!

Here, the discord, and the API office hours are a good start. However, none of these are “beginner” level sources, as they all assume a level of understanding JS,TS, npm, etc.

1 Like

Is there any sample can show how to useing the extension of the websocket API?
Or the document of official websocket API have any explane about it?

I cant exactly give you the actual code, as there are a lot of considerations as to player behavior, object preferences, etc, but from a pseudo-code standpoint, you would:

Connect to the space using game.connect()

Set up a subscription to the 'playerTriggersItem' event

Inside the event, code for if they are allowed to pick up the item. If they are, add it to their character.

Also check if they already have an item, and if they do, drop it, or maybe swap it with the other close one.

When they pick up an item, be sure to delete the object on the ground too. (Unless multiple can be picked up)

When they drop an item, create an item with the proper characteristics on the ground, somewhere.

Technically, those are all the parts you would need for spacebar interactions.

Edit: didnt expect the bolded words, those don’t mean anything specific.

2 Likes

Fantastic! Thank you
I will try it.

Hi sir,

Is it possible to provide a little more hint for it?

Thanks!!

I’ll see what I can do to provide a more concrete example. It will likely not be a runnable script, due to all the decisions I referenced in my earlier post, but it should provide a little bit of a midpoint to get you there.

This is a very rough snippet for the process. I have not tested nor refined the calls, so some oddness may occur if you run this as written.

interface ObjectHolder{
    [playerId:string]:{
        mapId: string,
        obj:MapObject|undefined
    }
}

let objects:ObjectHolder = {};

game.subscribeToEvent("playerTriggersItem", async ({playerTriggersItem}, context) => {
    if(context.player!.itemString && objects[context.playerId!]){
        let temp = objects[context.playerId!]
        let newObj = {...temp.obj,
            key: Object.keys(game.completeMaps[temp.mapId].objects!).length,
            x: context.player!.x!,
            y: context.player!.y!
        }
        game.setObject(temp.mapId, temp.obj!.id!, newObj)
    }
    
    if(playerTriggersItem.closestObjectTemplate && playerTriggersItem.closestObjectTemplate === "Special Object"){
        let {mapId, obj} = game.getObject(playerTriggersItem.closestObject!)!;
        game.setItem(playerTriggersItem.closestObjectTemplate!, obj!.normal, context.playerId);
        objects[context.playerId!] = {mapId, obj};
    }
})
1 Like

Hi sir,

I will try in later!
Thanks for your help!

Hi,
Sorry for the late reply…

I have tried using game.subscribeToEvent("playerTriggersItem",....) before, but it gave an error below:
error TS2345: Argument of type '"playerTriggersItem"' is not assignable to parameter of type '"info" | "warn" | "error" | "ready" | "serverHeartbeat" | "disableV....
Seems it could not go furthur.

But if I change playerTriggersItem to playerMoves or playerInteracts, then the code can run with some of the exmpla on the github.

Any suggestion? In the mean while, I will try to get more familiar with node.js.

Any help would be appreciated! Thanks!

I think you probably need to update your @gathertown/gather-game-client npm package. You can run npm i @gathertown/gather-game-client@latest to update to the current one.

I managed to almost get this working, but not quite.

  • The playerTriggersItem event seems to be gone. There’s a playerTriggersInventoryItem, but it doesn’t trigger on spacebar. playerTriggersObject seems to work.
  • Picking up the item doesn’t seem to remove the previous item on the board. I’m not sure what the right event to send to remove the item from the map without also removing it from the player.
  • When dropping the item, you have to still manually clear out the player itemString via some sketchy itemString: '' event, or else the player still holds onto the item.
game.subscribeToEvent(
  "playerTriggersObject",
  async ({ playerTriggersObject }, context) => {
    console.log("playerTriggersObject", playerTriggersObject);

    // drop item if player has an item
    if (
      context.player?.itemString != null &&
      context.player?.itemString !== ""
    ) {
      const objectId: string | undefined = JSON.parse(
        context.player.itemString
      )?.id;
      if (objectId != null) {
        const object = game.getObject(objectId);
        const map = context.player.map;
        const x = context.player.x;
        const y = context.player.y;
        if (object != null && map != null && x != null && y != null) {
          console.log("dropping balloon");
          game.setObject(map, objectId, { x, y });
          game.sendAction2("setItemString", {
            itemString: "",
            targetId: context.playerId,
          });
        }
      }
    } else {
      // pickup item
      const object = playerTriggersObject?.key
        ? context.map?.objects?.[playerTriggersObject?.key]
        : null;
      if (object != null && object.templateId === BALLOON_TEMPLATE_ID) {
        const objectId = object.id;
        if (objectId != null) {
          console.log("picking up balloon");
          game.setItem(objectId, object.normal, context.playerId);
        }
      }
    }
  }
);

ezgif-5-6f61a01ec3