Vallar's Forum Posts

  • ==> 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:

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • 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".

  • 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?

  • So there is an array object, and you can load the array files in or sure import as JSON too. The idea is the recipes are listed in the array in whatever format you want so something like :

    item 1 | amount 1 | item 2 | amount 2 | makes what

    Then the crafting area relates to a separate array with the same structure, as you drop in items into slot 1, the item 1 and amount 1 updates, as you drop items into slot 2, the item 2 and amount 2 update.

    When you click on 'craft', you compare this array with the recipe array to see if anything matches.

    So if you drop in 2 wood and 2 stone, it would then look in the recipe array for

    wood | 2 | stone | 2

    and then this makes the item at column 5

    Something like this would be my approach

    So let me see if I understand this correctly, so each recipe is a separate array? So if I want the axe recipe that is an array, if I want a door recipe, that is a second array object? Am I understanding you correctly?

  • Create an array of recipes and compare against them when you try and craft. Recipe would contain 2 items and the amount required so can look something like 2 | Wood | 4 | Stone, then when you drop the items in you compare to a craft array which has the current items and amounts dropped in, in a similar structure.

    I am sorry I am not following, how do you create an array of recipes? I come from Unity and that statement means I'd need to make a struct/class and make the array/list out of that. How do I do that without using JS here?

    Also I thought of saving the recipes in JSON format an loading that in, but I still wasn't sure how do I correlate data from JSON to global variables. I checked the example JSON in C3 and it shows how you can extract a value, but it doesn't show something like "check your JSON to see if this recipe has what the player wants and if so, equate the ingredients in the recipe to global variables to deduct the amount and THEN spawn the correct potion". I feel there is a way using that (or XML for that matter) but I am not sure how I get "Wood" from the JSON to understand wood from the global variables.

    I think global variables are only useful for total item amounts that you would display in a HUD UI.

    So right now the global variables are used for the player's inventory instead of using instanced variables on a sprite. That way I can access them from different layouts without issue.

  • Hello everyone,

    I recently started migrating from C2 to C3 and I reached a point where I need to seriously develop a data structure for my crafting system.

    Here is how the system functions:

    First off, you have to learn a recipe before you actually craft the item in this recipe. I may implement experimenting (i.e. you randomly put items and see what happens) but for now let's assume that is not the case.

    Each recipe has two data points:

    1- What ingredients to use?

    2- The count of each ingredient used.

    So something like "10x stones + 15x wood" would create an axe. The player has to then drag the wood from their inventory and the stone to put it into a crafting station then hit "craft"

    Right now I have global variables representing the ingredients; stone, wood, iron, leather, etc...

    How do I structure a data set that basically has the recipes and the game would then read this data and see "player put stone and wood, which recipe has stone and wood? Oh, that one, OK, then the player wants an axe, here is an axe made"

    Thank you very much.

    Tagged:

  • Hi,

    My game has a tilemap and I'd like the player to move based on these tiles. A similar approach is available in Construct 3 as a behaviour but uses the keyboard for movement.

    What I'd like to do is for the player to click on a tile on the tilemap. The player object would then check if the distance between that tile on the tilemap is within a certain limit. If yes, then the player then moves to that tile (i.e. setting the position to the center of the tile).

    So far what I was able to do is get the object to move to the mouse position within a certain distance, but I can't get the center of a tile in a tilemap to set it as the potion of the player.

    Is this possible in Construct 2? Any idea how I can achieve this?

  • The upper limits for modern computers for objects in a layout is anywhere between 5000 to 10000 depending on hardware with limited to moderate movement.

    Less, and a wider range for mobile of course.

    There are a few optimizations like Render Cells, and mixed objects(part tilemap, part sprites, part tiled background ect.)

    I have just run a test and I was able to put 10K objects (not in the same screen of course) and it worked just fine (web). Mobile isn't a very big concern right now. But if worse comes to worst, I can always separate those into like 4 levels or something.

    I didn't know about Render Cells. Just read about them, super useful. Thank you very much.

    I would suggest making a simple level editor. Just a separate capx where you can click on a tile to change its type and enter specific info about this tile into a few text boxes. Save this info in an array, and then export Array.AsJSON and Tilemap.TilesJSON.

    I thought of this at one point but then felt the hassle is going to defeat the purpose of making this prototype/demo in Construct 2 (quick easy, couple of days work). Unless level editors in Construct 2 are a quick 1-2 hours thing.

    Another option is similar to newt's suggestion - put sprites on your tilemap, but you probably don't need to cover the entire map, only the tiles which have any valuable resources. And this sprite may be a single invisible square.

    Thanks for the suggestion between yours and Newt's I think I'll choose this actually. Have a layer with a Tilemap and then another layer on top of it some squares that On Click or something do some stuff.

    If I want to change the tilemap's tile, I can just simply do that still (since it is a tilemap and don't have to detect what object I am on) using the tilemap.At or I can be lazy and spawn a sprite right on top of that part of the tilemap to render on top as if it replaced it :D

    Thank you both very much!

  • If the map isn't huge like thousands and thousands of tiles, I would go with sprites, and store the data in their instance variables instead of a tilemap.

    You get relative xy's as well as other benefits of frames, collision poly's etc.

    I wondered about that, but I was worried about performance. Do you know what is the upper bounds of something like that rouhgly? Like for example would a map of about 6K tiles be OK? Would that be too much?

  • Hey,

    So I have this tilemap where I create manually in the editor (not generated at runtime).

    What I want is something similar to what is in the game Neo Scavenger, I can click on "Scavenge" and get loot/information based on the tile type. Expanding on that, it is like if you're on a forest tile you get bushes and ropes. If you're in a mountainous area, you get rocks and maybe some iron.

    Now how do I add data to each tile (i.e. each tile knows what kind of text to display and what kind of loot to provide?) and how do I check which tile is which when the player clicks on "Scavenge" on it?

    One way I thought about this was storing data in a JSON/XML/CSV file. But that basically makes the whole create the map in editor moot and I have to generate it at runtime and I don't want that.

    Since I use Unity mainly, the equivalent to this in Unity is to create a data object (doesn't live in the level) and put all the data a tile type needs in it. Then each tile (also a data object) is then given an attribute of type "tile data" and then linking both. Does Construct 2 have something like this? Any ideas how I can do this?

    Tagged:

  • You probably need to add "Pathfinding Stop" action to event #4.

    By the way, instead of checking the distance in that event, you can set the distance in LOS properties.

    Huh! Nice catch, I thought I had that there. Thanks for the solution.

    As for not checking the distance, that is a good point. It is a test at the moment as this AI is basically following the player from the moment it spawns; another might be just far and won't move until it actually sees the player and up till it reaches its attack range then attack.

    But for this one, spot on, yes, thanks for that. I'll remove the distance and depend on LOS' range.

  • Add "For each BasicMeleeFollowEnemy" as a second condition, directly under "BasicMeleeFollowEnemy has LOS.." in event #3. It should fix the issue with attacking and chasing.

    Gotcha, thank you very much! Would you know why the enemies won't stop where the distance is set and they go directly to the player location?