This is the beginning of a function for a booster pack blueprint, which is supposed to use a while loop to grab random unit stat blocks from a datatable, and fill a booster until it has the required number of pieces, some of which are uncommon, one is rare, one is a special type, etc.
But here at the beginning where I have a breakpoint set, BoosterContents.Length is showing as zero, it’s being compared to 15, and that comparison is returning false.
Thus, somehow, Unreal Engine thinks that zero is greater than or equal to 15.
Equally strange, immediately afterward, whether I choose to resume or to stop the simulation, the entire engine hangs, and I have to force close Unreal Engine completely.
So I’m thinking there might be something else at work, and this is just a side effect of some other problem.
Does anyone have any idea what might cause this behavior?
Seems that you have infinite while loop. Maybe because data from your datatable is not valid, so your “Booster Contents” is not filled.
Try to debug everything: foreach data from datatable and print it before loop, after that put print in while loop.
Why don’t you use for loop instead of while (maybe easier to debug for you)?
The way I have it set up, the loop does not know how many times it will run. so a for loop is not appropriate, but I may change that later once I figure out a faster way to generate specific randoms from the list.
I will check the datatable though, if it’s not getting a list, that might cause all sorts of problems.
Okay it looks like the datatable is broken somehow and it’s impossible to pull the field that acts as the unique key for the table.
Here you can see the datatable as it’s visible in the editor.
The field called “id” is supposed to contain those values of sc1, sc2, sc3, and sc4. But when the datatable is read in, it needs one field to be unique, and I chose that one, and apparently it assigns that to a new value called “RowName” or “Row Name” and then deletes the id values.
Inside the blueprints editor, it was acting like the Row Name field was working, and it acted like it was pulling the whole list, but apparently that’s a lie, because GetDataTableColumnAsString.Length is returning zero, causing a divide by zero error.
I think what Mr. Wood was referring to is a ForEachLoop. This will run the proper amount of times depending on the length of your **Booster Contents **array - you don’t have to do the manual check yourself and it’ll most likely solve the endless loop you’re experiencing that’s causing your engine to crash.
The Loop isn’t running once for each instance in BoosterContents.
BoosterContents starts off empty, and eacch iteration of the loop has the chance to put something in the array, so long as the randomly chosen unit from the datatable is a valid candidate to be inserted into the booster.
That’s why you probably have infinite loop…Your “Booster Content” is always empty (because data from the datatable is not valid) and Booster array is not populated.
First you test your data from the datatable:
Get Data Table Row Names → Foreach → Get Data Table Row → Print your data to see output
But now I have a different problem - the id value of every unit created is wrong.
Is the Row Name handled as a hash? It’s randomizing that value, so everything is coming out with the wrong id.
Here’s a better picture of the new start, should be easy to follow. Just to the right there and barely visible is the “set” for SlotCandidate, the contender that may or may not be added to the booster.
The “id” value is broken up into 3 parts. the first character is either s, d, c, b, or p based on faction, the second character is either c, u, or r to denote rarity, and the third part after that is a number that shows where it is in the data file.
I had fun color coding everything and making the original file super pretty before I started. Productive procrastination or something.
each booster is supposed to contain:
1 location card, either common, uncommon, or rare.
1 set of “core” cards containing 1 each of 7 different types of units, 2 of which are uncommon and the rest are common.
3 more common cards, no restrictions (except it can’t be a location).
3 more uncommon cards, no restrictions (except it can’t be a location).
For a total of 15 cards. Or, in this case, coins.
The above booster breaks those rules, with an extra uncommon instead of a common.
I would suggest you not to get data from the datatable during runtime. Create a new struct variable (array), get all data from the datatable when game start and fill that struct variable.
You can store data in your game instance for example. Also, you can create Blueprint function to return all data you need and call it in your game instance. This is useful because when you change your struct or add more fields in your table some data can be broken if you do not refresh all nodes. So it’s better to create Blueprint func for this and click Refresh All Nodes when you change your structure.
About your problem…you have 2 columns “Row Name” and “id” in your datatable and get data from Row Name to create a new struct where is your column ID = Row Name which is why you get wrong data. You need function that will return data from the datatable based on that ID…or simply connect id with id (instead of rowname) when you break and make a new struct.
The original sheet has “id” as the values such as sc1, etc.
when I create the datatable, “id” is read in as the key to denote unique lines. when that happens, unreal makes that field “rowname” and deletes that information from “id.”
when I create the slotcandidate, “rowname” is read back in and assigned to the “id” value. it’s supposed to be a match. Not sure why it isn’t. I’m thinking now that perhaps the random number is being generated twice, once when pulling a row, and again when assigning the values to the new slotcandidate variable. so perhaps I can promote the randomly generated number to a variable and use it that way. going to test it.