Remove object from inventory, not 100% being removed

Hello,

In my game, a player collects items, stores them in their backpack, which I write as an array to device permanent memory.
I can retrive such items and use them.

HOWEVER, when I “use” them I want to remove them from the players backpack and inventory.
The item no longer exists ANYWHERE.

This is when I am stuck.

ON SCREEN:
The item remains viewable.

CONSOLE:
When I run through the array, the item has been removed.

JSON FILE:
Partial reference to the object remains, which is why the object is still showing on screen.

Line 11 to 18

CODE:
Line 612 is where I am attempting to remove the item found in the array using its index/key reference.

[{ "myName": "Red Scales", "\_proxy": "\<type 'userdata' is not supported by JSON.\>", "\_class": { "removeEventListener": "\<type 'function' is not supported by JSON.\>", "addEventListener": "\<type 'function' is not supported by JSON.\>", "\_\_index": "\<reference cycle\>" } }, { "\_functionListeners": { "tap": [ "\<type 'function' is not supported by JSON.\>"] }, "myName": "Wooden Wheel" }, { "\_proxy": "\<type 'userdata' is not supported by JSON.\>", "\_functionListeners": { "tap": ["\<type 'function' is not supported by JSON.\>"] }, "myName": "Wheelbarrow", "\_class": { "removeEventListener": "\<type 'function' is not supported by JSON.\>", "addEventListener": "\<type 'function' is not supported by JSON.\>", "\_\_index": "\<reference cycle\>" } } ]

-- remove item from inventory function gfRemoveItemFromInventory(removeItemIn) print("item to remove from array: " .. removeItemIn) -- write inventory to permanent memory for use by inventory overlay whenever necessary local pathFileInventoryArray = system.pathForFile( "fileInventoryArray.json", system.DocumentsDirectory ) local fileInvArr = io.open( pathFileInventoryArray, "r" ) if fileInvArr then -- test it variable holds file/path exists local contentFileInvArr = fileInvArr:read( "\*a" ) io.close( fileInvArr ) local arrInv = json.decode( contentFileInvArr ) if arrInv then print("arrInv") for indexA, valueA in pairs(arrInv) do print("indexA: " .. indexA .. " valueA.myName: " .. valueA.myName) if (valueA.myName == removeItemIn) then print("found item to remove: " .. valueA.myName ) print("found item to remove position: " .. indexA ) table.remove( arrInv, indexA) local fileInvArrWrite = io.open( pathFileInventoryArray, "w" ) fileInvArrWrite:write( json.encode( arrInv ) ) io.close( fileInvArrWrite ) fileInvArrWrite = nil -- break end end else print ("no arrInv") end --test check arrInv to see if item still lives in it or not. print("test full arrInv After update") for indexA, valueA in pairs(arrInv) do print("indexA: " .. indexA .. " valueA.myName: " .. valueA.myName) end end end

It’d be much simpler and efficient if you just dealt with Lua tables. All you need JSON for is saving when something is updated and loading whenever you first need to access the table. There also seems to be a lot of unnecessary details in the JSON file.

With these kind of tasks, it is always best to start out with a clear plan. What kind of data do you actually need to store? Is the backpack just a list of items that are in there? Can there be multiples of some items, and if there are, then are they stored as separate table entries or will you have a quantity count per item, etc.

I’d recommend that you simply create a single variable for the inventory that you load the data into. For simple instructions, you can check out https://docs.coronalabs.com/tutorial/data/jsonSaveLoad/index.html. Then you just need to make changes to said table whenever you update the inventory. Whenever you’ve updated the inventory, you just need to save the inventory and that’s that.

If you follow the tutorial, you could do something like this:

local loadsave = require( "loadsave" ) local inventory local path = system.pathForFile( "inventory.json", system.DocumentsDirectory ) local file = io.open( path, "r" ) if file then inventory = loadsave.loadTable( "inventory.json" ) else inventory = {} -- Array style. inventory[#inventory+1] = { name="some starting item", quantity=1 } -- Key-value pair style. inventory["some starting item"] = { quantity=1 } loadsave.saveTable( inventory, "inventory.json" ) end

Hello XeduR @Spyric

Thank you for taking the time to reply.

The reason I was saving items collected to permanent memory, is if the player quits the app, closes etc.

I wanted what they had “found” so far to be saved.

So currently, as and when an object is being found, I download a copy of the inventory, add item to it, then resave it.

Same in reverse.

I want the overlay to grab the latest version of the inventory stored in memory, display it’s content, allow a player to click on an item, then use it, once used, delete that item from the inventory and then save to memory to revised version of the inventory.

I’ve not touched the JSON file, other then to inspect it. That is what is being created by lua when it is writing to the file.

I will however investigate what you say.

At the moment, I am simply following the “methods” laid out in the tutorials.

Thanks
 

What I just told you does exactly that and it does so much easier.

When you need to update the inventory, you just save the inventory again (as shown in the tutorial and my brief sample code). It will overwrite the previous version of the JSON file. You do not have to load from the JSON file unless you’ve, for some reason, had to clear it from memory. You can make whatever changes you need to the Lua table itself and just save it as JSON afterwards and that’s it.

Thanks again… I’m investigating.

Just reading up on Modules now

Can I ask…

All the examples show a local variable called M inside the file.

Is this ‘M’ reserved name?
As it’s local to that file… I presume, using the same syntax when creating other modules in other files wont be effected?

Sorry if these are dumb questions… until your post today I didn’t know of modules, or a concept of them.

At the moment my understanding is that I can read in their content like I would a php include file.

But it’s the fact that all the examples are using the same approach that has me a bit confused.

Thanks

local M = {} return M

No, I’m presuming that in that particular case,  M is just short for module. I typically use  lib for libraries that I create or some abbreviation of the actual module name that I’m working on.

Anything that you create inside a module is local to that file and won’t interfere with other files (so long as you don’t create globals). You can think of those modules as fancy, yet simple Lua tables. In your sample code, you create a table M that you then return to the other file from where you require the module. So, if you were to add functions to that table M, you can access them easily through it (like in the tutorial).

Whenever you load a module, Lua will cache it. This means that you can require the same module in numerous files/scenes/etc. and if you make changes to it anywhere, then those changes will be accessible to the other scenes too.

For instance,

main.lua

local MM = require("myModule") -- you can name the variable almost anything you want MM:getName() --\> Susan MM:changeName( "Bob" ) MM:getName() --\> Bob

myModule.lua

local mod = {} -- You can name this anything you want as well, e.g. M, mod, lib, etc. local name = "Susan" -- "name" is local only to this file,. function mod.getName() print( name ) end -- Since "name" is local to this file, and this file is cached, updating it would change it for -- all scenes/files where you've required this file (or will require the file). function mod.changeName( newName ) name = newName end return mod -- By returning "mod", main.lua gets access to the table and the two functions in it.

And that’s my 1000th post on these forums, making me an official Corona Geek! Now I shall bask in my interwebz glory!

Hopefully my explanation cleared things up.

I just want to say thank you very much for taking your time to explain.

In a strange way I had also created my own version of modules.
I had main >>> loadPrerequisities >>> scene1

I had put a composer timer to instantly forward the player on, so I could bring into memory any of my own global variables/functions I needed to repeatedly call.

So thank you.
I need to spend the evening now shifting and rearranging my code, (and fixing anything that now gets broke), but as a result I will have a much more manageable game with the ability to forward use code in other ventures.

Congratulations on your 1000th post.
Glad I could have been of service :slight_smile:

Angela

Congrats on thousand!