NokiMo
__ess__
__ess__

patreon


Drag & Drop Inventory Tutorial, Completed Series, Now Available On Youtube! [OUTDATED - NO LONGER UPDATED]

Important notice! This script is no longer updated to work with newer versions of Ren'Py. It does still work with Ren'Py 8.1.1 though. Over time as Ren'Py has changed, the script lost some functionality where saving and loading things within the script and possibly other things no longer work well. It was not feasible to keep updating it at this point as the code would have needed a large overhaul to work. Instead, I have two newer and better structured inventory scripts you may want to have a look at: Drag & Drop Inventory v.2 and Inventory with context menu.

A complete video-series of how to create a drag & drop inventory system in Ren'Py is now available on my Youtube channel! Check it out if you haven't already! It will fit well for point-and-click type of visual novel games.

It consists of 6 videos where we'll create an inventory at the bottom of the screen that can be opened and closed. Each of the inventory items has it's own overlay menu that triggers when you hover over the item, and allows you to choose if you want to inspect the item closer or drag the item around.

If you choose to drag the item, you can then combine it with another item in the inventory or in the environment by clicking with the mouse on the second item you want it combined with.

We also implement our own say screen that will make sure that no interactions can happen on buttons or items while the dialogue is showing. This will also ensure that the dialogue will work nicely together with the inventory functionality.

The artwork provided for this tutorial is made by me by either my own imagination or by using public domain images, usually vintage ones, that I have edited and/or combined in different ways. If you want to know more about the artwork, you can read the behind-the-scenes post available for paying patreons only.

Check it out on Youtube!

You can download the complete script and artwork below for free, but if you're able to, I would appreciate if you considered joining my Patreon in any tier to show your support for as long as you can or am comfortable with.

Enjoy!

UPDATES

Important notice! This script is no longer updated to work with newer versions of Ren'Py. It does still work with Ren'Py 8.1.1 though. Over time as Ren'Py has changed, the script lost some functionality where saving and loading things within the script and possibly other things no longer work well. It was not feasible to keep updating it at this point as the code would have needed a large overhaul to work. Instead, I have two newer and better structured inventory scripts you may want to have a look at: Drag & Drop Inventory v.2 and Inventory with context menu.

UPDATE (Jul 18, 2022):

The file has been updated (version 1.0.1) to work with Ren'Py version 8. Ren'Py has changed how float values work for positioning displayables which makes the overlay menu not showing correctly. Read the quoted comment below from part 6 of the series to learn more.

Link to video where I posted the comment: https://www.youtube.com/watch?v=5kI2PUELgsE&lc=Ugw4wRCEeG7hLzwtRPp4AaABAg.9d8sIfNNS549dboORG7kGU

"The reason for this seems to be how Ren'Py now handles positioning values.

Float values (decimal values: 0.5, 25.36 etc.) have been treated for a long time by Ren'Py "as a fraction of the size of the containing area" (quoted directly from the documentation). So for example, writing 1.0 as the xpos value will place the displayable at the right edge of the window, 0.5 would be in the middle and 0.0 is the left edge.

If one writes an integer value (ex: 10, 25 etc.) it is treated as pixel coordinates. However, one has been able to get away with, for some reason, to enter in a large value like 468.5 and it be treated as a pixel coordinate instead for a while now. But since the update to version 8, one cannot get away with this anymore, and it is treated as a fractional value instead.

So the reason why the overlay menu doesn't show on top of the second item is because its positioning values item.x and item.y contains float values instead of integers for the second item, and we have to typecast them to integers instead of floats for it to work."

UPDATE (Jul 26, 2022):

Updated the script (version 1.0.2) to show how you can switch between different scenes without having environment items carry over from scene to scene. Please watch the tutorial video for this update to follow along with what has been changed and why. Watch it here: https://www.youtube.com/watch?v=gXfNHbSfnbo

UPDATE (Dec 13, 2022):

The script has been updated (version 1.0.3) to fix an issue in the "repositionInventoryItems" function as reported on the last video in the series (switching scenes). The items wouldn't position themselves correctly in some circumstances.

That's because I had mistakenly written "inventory_sprites[-1].original_x = item.x" in the "if i == 0" statement, as well as inside the following else block. So the fixed code now looks like this inside the function:

for i, item in enumerate(inventory_sprites):
   if i == 0:
       item.x = inventory_first_slot_x
       item.original_x = item.x
   else:
       item.x = (inventory_first_slot_x + inventory_slot_size[0] * i) + (inventory_slot_padding * i)
       item.original_x = item.x

UPDATE (March 07, 2023):

The inventoryArrow's function wasn't updating the 'original_x attribute' of the inventory sprites after being shifted to the left or right, resulting in that items would snap back into their old slots when being dropped. This has now been fixed in version 1.0.4.

Project files attached below (version 1.0.4).

UPDATE (October 07, 2023)

When saving while being in one scene, then loading the game back up and going into another scene, the items would carry over. This has been fixed by adding "renpy.retain_after_load()" as the last thing in each scene setup label inside the if statement "if item not in environment_items_deleted:". You can see this by going to line 471 and 518 in the main script.

Project files attached below (version 1.0.5).

Drag & Drop Inventory Tutorial, Completed Series, Now Available On Youtube! [OUTDATED - NO LONGER UPDATED]

Comments

Hello! Thanks for becoming a patron and welcome.😊 I first want to mention, in case you're not aware, that I'm working on a new and improved inventory system that will be much easier to work with. It wont have drag & drop however. I reckon it wont be too long until it's completed, but I also have to create a video tutorial for it to explain how to use it. So I don't have a release date for it yet. You can read the post for it here: https://www.patreon.com/posts/new-inventory-in-78009711 But, if you're still set on using the drag & drop one, I think I'll have to see how your code looks like to be able to help you spot the problem as I don't know how you've set it up. If you wish, you can upload your project to for example dropbox or google drive and send me a link via PM if you don't want to share it here in the public comments.

Sara

Hi _ess_! Thank you for making such great tutorial which I was able to follow and complete even though my basic python knowledge is very limited. I was able to learn quite a bit from this. My script works fine as far as the tutorial goes, but I have a couple of issues which I was wondering if you could help me with. 1. I understand that we use a custom say screen to make sure that no interactions can happen on buttons or items while the dialogue is showing, but can we still use the default say screen elsewhere in the game? Currently I have this inventory system set up as a demo within the game in an "inventory.rpy" label which the player can jump to to try out, but when I jump back to my original script, I get an exception as soon as a character talks: [code] I'm sorry, but an uncaught exception occurred. While running game code: File "game/inventory.rpy", line 1087, in script t "This is a test." TypeError: __call__() got an unexpected keyword argument 'interact' -- Full Traceback ------------------------------------------------------------ Full traceback: File "game/inventory.rpy", line 1087, in script t "This is a test." File "renpy/ast.py", line 721, in execute renpy.exports.say(who, what, *args, **kwargs) File "renpy/exports.py", line 1419, in say who(what, *args, **kwargs) TypeError: __call__() got an unexpected keyword argument 'interact' Windows-10-10.0.22621 Ren'Py 7.4.11.2266 Feed My Affection 0.26.0 Mon Feb 20 11:37:22 2023 [/code] This is fixed as soon as I go back to the main menu and start the game again though. What is happening here and how can I prevent it? 2. The second problem I am having is with the snap-back. If I fill the inventory with items, click the right arrow to slide the items across, drag an item and then allow it to snap back to the inventory, it snaps back to wrong slot, often on top of another item. For example, if click the right arrow then drag and release the item from slot 2, it still snaps back to the second slot even though it should snap to first now, as all the items have shifted to the left. If I then click the left arrow and drag it, it will return to its original position in slot 2. I'm thinking I must have missed a line or made a mistake somewhere with item.original_x?

Nampot

To use it in a label you would need to create a for loop (in a python block for example) that loops through the "environment_sprites" or "inventory_sprites" list depending on from where you want to remove an item. Then you have to compare each item in the for loop to see if it's the item you're looking for and remove it. Example: python: for item in environment_sprites: if item.type == "shoe": removeEnvironmentItem(item) The name that you put in the if statement (shoe) should be the name that exists in the "environment_items list". To add an item, you could use one line of code: $addToInventory(["hat"])

Sara

I haven't thanked you for your recent replies, so let me thank you here. But now I have another question. Using this work of yours as the baseline, how to remove an item from inventory or environment while in the middle of a label? Like this for example. label cutscene1: Character: "blahblah yadda yadda." "Something happens." **[item] is removed from inventory** Character: "oh noes I just lost the [item]." "Something else happens." **[item2] is removed from environment** Character: "What, where did that [item2] go when I wasn't looking?" inserting removeInventoryItem or removeEnvironmentItem function into the label throws "not defined" error so I guess it's not that simple unless I messed up somewhere. In relation to that matter, how to instead add items in both cases?

BladeGrip


Related Creators