Vallar's Recent Forum Activity

  • Feeling this was right up my alley I took a stab at it using the provided recipes JSON exemple.

    I use an array to store the currently owned components. "Crafting" recipes in this exemple simply remove the components, but in real use case you'd add it to your inventory of course !

    https://drive.google.com/file/d/1F1jzwfNWpln8CbLtyPz5jnK6pyh9uwJm/view?usp=sharing

    Thanks for the .c3p. I have been reading over it and a few things went over my head, if you don't mind a few questions:

    1- The function "getRecipeIndex", is this the function that checks what kind of recipe is the player targeting? If that is the case, could you explain what is the second condition (the JSON one)? I don't understand what that does at all.

    2- Is there a reason why you're using For loops instead of For Each loops on the JSON object? Specifically in the "possibleRecipeCraftCount" function. Is it because then you can use the Stop Loop action?

    3- In "possibleRecipeCraftCount" does this line "JSON.Get("recipes." & recipeIndex & ".components." & loopindex("components") & ".name"" means Get the key that is recipes.recipeIndex.components.loopindexcomponents.name? How is that constructed? Like in my mind say first index of the loop this would mean "recipes.0.components.0components.wormwood" But I am not sure how that works in JSON. Could you explain this in plain English, please?

    4- I am guessing this line here "recipeAvailability = -1 ? 0 : recipeAvailability" is similar to C#'s terenary operator? Does this mean if recipeAvailability equals -1 then set it to 0 and if not, leave it as is?

    Thanks

  • So, Kyatric and I have had a bit more of a think about this, and if you're still interested, this blog briefly outlines the project he came up with. It also contains a download link for the project.

    At some point, I plan to turn it all into a tutorial, but that's a looong way off!

    Oh, thanks a lot Laura_D and Kyatric that definitely looks interesting and is what I wanted to do at first. I read your blog and checked the .c3p file. I can't say I understand it all -- specially the part where you're checking if the recipe exists or not. But I think I have a good overall gist of how this is done.

    I'll see if I can attempt to replicate this.

  • Hi everyone,

    I have a few dictionaries and arrays in the Files folder of my project. They were created inside C3 not imported.

    Now the information I get from those files are loaded into their respective objects at runtime. The information gets updated as the game is played.

    What I want to do is write back the information (the new updated one) into the files I read them from previously. Is there a way to do that?

    Thanks.

    Tagged:

  • Afraid I know nothing of overheads - at that point I'd usually try and create mini versions of what I was trying to test and compare the two.

    Usually I just chuck everything into as few files as possible so I only have to fetch the file once when the game/project loads. I've never tried looking at multiple files at runtime!

    It is more sensible to put all the recipes in a crafting system into one file or if the system has different categories (potions, weapons, armor, etc...) it would be each a file. But right now if they are all in one file I can't tell which recipe is which. Apparently in JSON you can't tell the For Each to stop when you found something and the System > Stop Loop action doesn't work with it. So it seems you can work with the entire lump of data not chunk it and work on pieces of it. Could be wrong though.

  • I'm still getting used to working with JSON, Arrays etc so I'm kinda figuring it out as I go along, but I'll try and answer what I can!

    In terms of the For Each loops, you can nest them like this:

    See now that answers one of my big questions, how do I access the components list. I didn't know that I needed a nested For Each loop. I kept trying to use the For Each loop with "recipes/components" or "recipes.components" and neither worked. So that is interesting.

    If you don't mind a tangent question (but is definitely related); do you know the overhead of using AJAX to load a project file, do stuff with it (like checking the components listed inside and loading that file into a dictionary) then clear and load another file and so on and so forth for like 10-15 files? T

    Reason I am asking is because this is my current setup, I have a Dictionary File for each recipe, I load into a dictionary with AJAX then use the KeyCount to check if it is correct, if so, I start comparing components. Rinse and repeat for every recipe (which means every Dictionary file in the project since each recipe = a file).

    If the overhead is big, then what you just presented might actually work better -- one big JSON file that I load chunks off into a dictionary and use the dictionary's KeyCount, still won't solve the loop over the JSON 3-4 times to get what I want, but at least if AJAX has a big overhead, I saved that.

  • Not 100% sure if this will help you Vallar, but I've been messing around with crafting system ideas myself. This test project might be a bit too simple for what you're looking for, but it may give you an idea of how the JSON events could work if you wanted to go down that route. Depending on how many crafting ingredients you have, you could probably swap out the Global Variables for an Array, but I've not gotten that far yet.

    Ignore the filename, the project started as a drag/drop thing, and I've not gotten around to renaming it!

    Crafting Test Project

    Thank you very much Laura for sharing it. There are a few key differences between what I saw in your project and what I am attempting to make:

    - In my crafting system the player can slot the ingredients in any order. So before hand I have no idea what order the player will slot the ingredients in. So that requires that I loop over the ingredients in a recipe and check each ingredient separately. This is why I add all my ingredients to an array as suggested.

    - In my system, there aren't a set amount of slots to craft from. For example, right now the player has 5 slots to fill (the number of slots was completely arbitrary) so this may change in the future and the system needs to adjust for this. It could be 8 slots available or only 3. Either way, while that isn't a big deal, not all recipes use all the slots. So right now while I have 5, some recipes have 3 or even 2 slots only used. Some have the full 5.

    - In my system each of the ingredients have a specific count and if that count isn't available I can't craft. Example 10x wood + 5x stone + 50x iron will make an Iron Breastplate (absurd ingredients but it is for the sake of example). So I need the recipe to have that kind of data so I can check if the player has that amount or not.

    What your .capx showed me however is that I can loop over "recipes", I wonder however how can I loop over a list of ingredients INSIDE one of the recipes? Would it be same for each but instead I do something like "recipes/ingredients"? In that case, is there an action in the JSON object that can quickly tell me what the current ingredients count without manually iterating and adding 1 to a local variable that counts them?

    Like let's say I have this JSON:

    	{
     "recipes":[
     {
     "recipeName":"Blinding Flash Potion",
     "components":[
     {
     "name":"Wormwood",
     "count":2
     },
     {
     "name":"Sulfur",
     "count":5
     }
     ]
     },
     {
     "recipeName":"Potion of Sweet and Savory",
     "components":[
     {
     "name":"Salt",
     "count":5
     },
     {
     "name":"Sugar",
     "count":5
     }
     ]
     }
     ]
    }
    

    How do I then check the "count of components" without iterating? How to then iterate over Components for ONLY the potions that match the "count of components" I am targeting? How do I iterate over those components to confirm the name matches and then grab "count" to deduct what I want?

    Sorry for the wall of text but these are the issues that I ran into with JSON and I wasn't able to resolve/answer them.

  • ==> watch out with rules here. I always use a local variable called "result_value" or something, and in the very last action of the function (outside of any loop or condition) I just return that value. That's handy because you could debug this using console.log for example, and see what your result value becomes as you loop through. Debugging loops is always a bit of a hassle, but I usually use either a debug label and append some text as the loop goes on, or use console.log to track what variables become all through the loop.

    Handy advice thank you very much. I ended up finding out the issue a couple of hours after posting. Apparently there are two Function systems in C3 and I was using the black one not the blue one (the new one). However, I didn't think they were completely different and had my return value code as the blue one while the function is the black one.

    I presume that what you mean is where the "hasValue" needs to check if a recipe contains an ingredient? I would use a separate function for that returns true or false

    I already do. The entire thing is divided into 3 main functions. The first one checks what kind of dictionary (potion) this is, the second checks if the ingredients are available. The third does the deduction and then returns to the first to make the actual crafting process.

    I ended up finding out that the interchanging use of actions and conditions from both Functions system is what messed up the whole thing.

    Hard to see without the c3p file, but I get the feeling that you should first loop through the crafting stations and add the ingredients to the array. And then UNINDENTED go loop trough the choosen ingredients. If you have 3 stations, and they all have 1 ingredient... You loop through the stations: in the first iteration, the ingredient array will have one value, and will never match a recipe, the second time round, still not, the third time round, maybe.

    So, again, I don't know exactly the circumstances, and game logic, but I would think that you would first do the filling of the array. and then, NOT as a sub event, on the same level as the for each loop, do the rest?

    That is exactly what I am doing right now. First I loop over the slots and get the ingredients there and add it to an array. Then I loop again (unindented) over the array (now populated with the ingredients player chose) and find out if the ingredients have enough to craft the potion. Then I loop a third time (unindented) to actually do the deduction if the previous loop checks out.

    My question is, is this normal or common that you end up looping a few times over the same data?

    Personally, I'm a huge fan of functions and separating parts of the logic into functions even though they only get used once.

    I am trying to do the same. Right now that process is divided into 3 main functions. But it gets a bit messy with the two functions systems and I did't know their rules yet (I knew the old one only) so I messed up a few things.

  • Hi everyone,

    I am working on a crafting game. I spent the past few days trying to figure out how to deal with data manipulation (i.e. how to store crafting recipes and how to work with them). From my little search, I found that most tutorials related to data manipulation are very basic "find all data and display it". Maybe I didn't search well, I don't know.

    Anyway, I ended up going with a dictionary for each recipe. I loaded it up with AJAX (created as a file from the Files section in the project) when a player crafts something.

    So I ended up with this messy bit of events:

    First the player drags and drops the ingredients into the crafting slots (there are a total of 5 and player can use 2 or more in a recipe so no set number of ingredients per recipe). After that player hits the craft button and I load the first recipe using AJAX in a dictionary like below

    https://i.imgur.com/7AKJu3W.png

    I check the ingredients the player used and the dictionary keys and see if the length matches and if the keys (names of ingredients) match:

    https://i.imgur.com/BbOhZw8.png

    https://i.imgur.com/oLBoSuY.png

    And here is the first problem -- as you can see in the second screenshot I have it where if the elementAmount (parameter) is less than or equal the element I am targeting it should return TRUE (a global constant variable set to 1) if not it returns FALSE (another global constant variable set to 0). The problem here is that no matter what happens inside the function itself it shows that the return value is true (I set it up that way and gave the elements very high numbers while the requirements are low for testing) but when outside of the function (i.e. when I store the return value) it is false for some odd reason. I don't know why this happens.

    I am setting the variable called "ingredientAvailableResult" to the result of the function IsIngredientAvailable and that variable gets set to 0 ALWAYS. Even if the element I am checking has a value of 50 and the amount I am requesting is only 2. I don't even know why this is happening.

    Anyone knows what is wrong?

    That is the first issue. The second issue is the events themselves. For some reason I have to store a return value before I test it (as you can see each time I call a function) if I don't, the test is always false. Again, don't know why...

    The final issue is related to code structure. Right now the way I am testing all of this is:

    - Check which sprite is overlapping the slot sprite. Pick those from the ingredients family.

    - Iterate over them and find if they are present in the dictionary keys.

    - If they are iterate over the dictionary a second time to see if the ingredient amounts are enough to be able to deduct the amount.

    - If they are enough, I iterate over the dictionary a third time to actually deduct the amount I want.

    Here is the final loop to deduct the needed amounts:

    https://i.imgur.com/bRFOsUi.png

    I feel this is just wasted resources and coming from C# this could've been done in one loop pretty easy. Any ideas how do I fix these?

    One that is all done and say if this isn't the correct recipe I load the next dictionary from the Files folder to the same dictionary I had before (after clearing it of course) and then run the entire thing again.

    So TLDR/Summary of issues:

    1- Why is the function IsIngredientAvailable returning FALSE even though inside the function the return value is reported TRUE?

    2- Why is it that I have to store the return value of a function in a variable and then run conditions over that instead of directly running conditions over the function?

    3- Anyway to structure the code so I don't have 3 loops over the same data just to get to what I want?

    Tagged:

  • You can use for each element for each X as an option, or you can use a system for loop from 0 to n where the data 'loopindex' can be the current X or the current Y. So if you have 5 rows and run for 0 to array.width, it will run 5 times and each time you have the loopindex of 0,1,2,3,4 to refer to each row.

    I would definitely take the item references from a global variable as there's really no need. You can use global var for the amount like numWood numStone collected for the player. The way you will design the crafting events is kind of based on how it works in the game, you can just throw any items into a place and hope it makes something seems a little wild for the player.

    Maybe for the crafting it's easier in the end to use a sprite with instance variables which are named by item name and the value is the number dropped in. It really depends how this crafting would work, I can't imagine it as a player.

    Thanks for the explanation but I couldn't figure it out to be honest how to do it in actions. I reverted to using a dictionary for each of the recipes so each dictionary has a few keys (ingredients) and their amounts (values).

    My issue right now is how do I tell Construct 3:

    - Loop on AxeDictionary and check if it has all the keys matching the objects that overlap with the GUI icons. If all the keys are present, then craft the item. If not, exit and check the next dictionary.

    Elaborating on the "objects that overlap with the GUI icons", I have the ingredients as sprites placed as a row at the top and there are slots midway through the screen (where the player puts the ingredients), player then drags the ingredient on to the slot. I have a family of ingredients created which I check to overlap with and thus pick the ones that only are slotted not everyone of them on the layout.

    As a side note, I tried to use JSON as well but I couldn't figure out how to iterate over a JSON list and ask "does all these values exist? Then do X".

  • There's a lot going on here, I'm not sure how the ingredients are listed,

    Basically from the array screenshot; a column is an ingredient and a row is an item that can be created (a recipe basically). So row 0 has 3 ingredients to create the object; ingredient 0, 1 and 6.

    i thought you said its crafting from 2 item types.

    No, the crafting system can have any number of objects to create an item. What I said was related to the data needed to be saved; two data points: the ingredient and the count. I gave an example of the axe using wood and stone for explanation not for exact count of ingredients making an item.

    Also I wouldn't use IDs for items theres no need, should be strings for the item names and numbers for the amount required.

    Ah, interesting, I didn't even know that you can have an array of strings and numbers thought it is like C# where you have only one data type. That said, even if that is the case. I can't really put the name of the ingredients as I can't reference it either like a dictionary. Perhaps maybe that is the better option? Have a dictionary representing recipes? So each recipe is a separate dictionary? Since I can use "Key" to reference the exact ingredient and "Value" for the count of said ingredient required to make the item?

    In general you move through the array by using the array object and for each X to check each recipe, but within this you need to check certain Y (columns) to see if it's matching.

    How do you go through each X only and ignore Y or vice versa (since it seems Arrays in Construct 3 are reversed). I've only found "For Each Element".

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Fill out an array file, under Files. Use AJAX to request the file. On AJAX completed, load lfrom JSON ajax.lastdata.

    Oh, I didn't know that C3 had that option -- create an array and populate it so easily. Nice. Thank you very much for that.

    However, I am still stuck. How do I iterate over my array to check if they have the current selected ingredients and if so, to extract each ingredient's required value?

    Basically I have my array as you mentioned setup like this:

    https://i.imgur.com/P5NGrZj.png

    The columns (0 to 8) are the ingredients while the rows (0 to 14) are the recipes

    My ingredients have their "id" saved in global constants like this:

    https://i.imgur.com/A1BNwSj.png

    Each of the ingredients object (i.e. sprite in the game) has an ID too which corresponds to the ID in the previous picture as well.

    I also have another array I created with width equal to the recipes array and height 1. But I am unsure how to do what you mentioned I should do really.

    Player then drags these ingredients and puts them inside an inventory like slots then hits "Craft". I don't know before hand what the player will drag so I need to check the stuff in the slots against the array and find out what potion is this and give the player the appropriate result (or if they dragged nonsense to show them that too).

    Thanks in advance.

  • Each recipe is a row of one array, like a spreadsheet. When you craft, this is a separate array to compare back to the recipe one.

    Ah, I see what do you mean. How do you populate the array then? Do I have to make a specific EventSheet and use the Insert/Push action to create them manually?

Vallar's avatar

Vallar

Member since 24 Mar, 2014

None one is following Vallar yet!

Trophy Case

  • 10-Year Club
  • Forum Contributor Made 100 posts in the forums
  • Regular Visitor Visited Construct.net 7 days in a row
  • RTFM Read the fabulous manual
  • Email Verified

Progress

14/44
How to earn trophies