MC Bingo

MC Bingo

50.9k Downloads

Players sometimes spawn in previously used locations

LucilleTea opened this issue Β· 46 comments

commented

I haven't tracked down a particular cause for this currently, wanted to note it down for now.
Players will spawn in a previously used location sometimes, which seems absurd considering the size of the minecraft world in play. I haven't particularly kept track of the seeds in use, but we've been generating random cards so there shouldn't be duplicate seeds to this extent either. I've also noticed that the spawns are not exactly the same - the other day I as yellow team spawned 2 blocks away from a previous green team spawn point.

I'm assuming something in the seed based randomization code may be leading to far fewer possibilities than there should be? But I'm unsure.

2021-11-02_16 02 43

commented

Hmm, that is quite strange, the spawnpoints are tied to the seed so there could be an issue with the code for that.
But the bigger question is the fact that it was two different coloured teams spawnpoints at the same location at different times. For a seed, each time you use that seed, the same spawnpoints are used for every team, always, forever. So I'm incredibly confused as to why this is happening. The only thing I can think of is that somehow the location was chosen twice, for two different seeds. Which is so crazy!

The code that chooses the spawnpoints is based on set locations, so I could see it as being possible. However, I put in a very large amount of possible locations (295 x locations and 295 z locations, both chosen randomly)

To be honest I'm quite at a loss for what to try and do for this as I'm not sure the causal factor/issue. I guess it's time to go over the seed code again.

Also as another question, is the PVP Mode on during this? That messes with the spawnpoint placements slightly so it could be due to that.

And thank you for bringing this to my attention

commented

We played with PvP on briefly, but usually do not use it.
I feel like 295^2 spawn locations sounds like a lot, but might not actually be?
This is 87025 total options. When 4 teams are playing, this is only 21756 unique games with no reuse. It still does seem weird to hit collisions over the course of say 100 games, 250 spawn points, but not that absurd? Especially if the RNG isn't perfectly distributed.

87025 is also an order of magnitude less than your number of seeds, 1000000, so it sounds worthwhile to bump that up anyway?

commented

How would you feel about a PR where I replace the seeded randomisation logic with this implementation, and the "true-random" logic to generate the seed with this implementation? Both MIT.
I would then generate spawns in the full range of available coordinates, with perhaps a 10k block buffer around 0,0 and worldborders.
I do not know if the prng implementation here is inherently "more" or "less" random than your current implementation, since I don't know what kind of rng you've implemented. Using these functions will clean up the code though, and the customizable bounds will let us conveniently get numbers in any range required.

Wanted to get your thoughts on this before working on it. I don't understand what kind of PRNG algorithm your code currently implements since the comments don't specify, and I don't know much about this. Requesting a random number from the JVM itself seems like a very suitable replacement for the step where you currently get minecraft to randomly shuffle some AOCs though - and shouldn't need your extra processing, we can just get a seed with the correct bounds.

commented

I do apologise for the incredibly late reply on your previous message.

So when work and life hasn't been getting the best of me, I've been trying to figure out a way to redo the seed system, but I frustratingly couldn't get some of my ideas to work. I do have to say I'm not the best at math which makes doing that more difficult lol.

The simplest way I found to try and get around only having like 250 spawn points was to just simply increase the number of command blocks for the x & z tp location, but there's only so many and you still run into the same issue of eventually you'll have just looped back around after playing the max number of games for spawn points available (250 as you said currently).

To answer your second point, I'm always happy to have help on this project! When making this, the seed randomisation was the 2nd most super frustrating part to work out (1st being the custom dimension json file to give the small biomes)
The first datapack you showed was very cool and quite simple for what it does which is awesome. The second one is also really interesting, I've not seen it done like that before. If you'd like to make a PR then please do, I'd love to see what can be done to help fix the spawn location issues as I've not had the time to come up with much myself.

To answer the other part of your question, I really should comment what I do better for the seed randomisation code, there's 3 main parts to it - first is calculations for the seed itself, second is using that number/seed to work out the bingo card items, and third is using the number/seed to work out the team spawn locations.

So here's a run down what I do currently for the seed randomisation to get the actual seed for the Bingo game:

  1. choose 1 of the 60 area of effect clouds (AOC)
  2. add that AOC value (1-60) to the dummy player "Z"'s score in the scoreboard "Calc"
  3. then multiply Z's score by A's score (A is a dummy player with a fixed score of 1103515245, really just a super big number so it causes overflow in the scoreboard system when used in numeracy operations) and sets Z's score to the product of that.
  4. then add C's (C is another dummy player with a fixed score of 12345) score to Z's score.
  5. then multiply Z's score by 2.
  6. then divide Z's score by 2 (this seems like it'd just undo the previous step but if the previous step caused an overflow in the scoreboard score then this step creates a new number)
  7. at this point we have the dummy player "K" this is now set to the same value/score as Z.
    we now work with "K"'s score.
  8. K's score gets multiplied by 2.
  9. K's score gets divided by 2 (see step 6 for reasoning)
  10. K's score then gets divided by 65536 (2¹⁢)
  11. another dummy player "seed" has it's score set to the value of K's score.
    we now work with "seed"'s score.
  12. then some modulus happens - the score of "seed" is divided by 899, the remainder of this calculation is then set as the score of "seed"
  13. "seed"'s score then gets 899 added to it.
  14. then more modulus. "seed"'s score is divided by 899, with the remainder of this calculation being set to "seed"'s score
    we now go back to Z.
  15. Z's score is multiplied by A's score (1103515245)
  16. C's score (12345) is added to Z's score
  17. Z's score is multiplied by 2.
  18. Z's score is divided by 2 (see reasoning in step 6)
  19. K's score is now set to Z's score.
    we go back to working with K's score.
  20. K's score gets multiplied by 2.
  21. K's score gets divided by 2 (see step 6 for reasoning)
  22. K's score then gets divided by 65536 (2¹⁢)
  23. we have a new dummy player "tmp". "tmp"'s score is set to that of K's score
    now we work with "tmp"'s score
  24. more modulus - "tmp"'s score is divided by 999, the remainder of this is then set to "tmp"'s score
  25. 999 get's added to "tmp"'s score.
  26. even more modulus - "tmp"'s score is divided by 999, the remainder of this is then set to "tmp"'s score
    we go back to working with "seed" now
  27. "seed"'s score is multiplied by 1000
  28. "tmp"s score is added to "seed"'s score
  29. 100000 is added to "seed"s score

"seed"s score is now the final seed used in the Bingo game.
"seed"s score is now set to "Seed" a viewable number on the scoreboard "Score" so players can see what the seed actually is
"Z"s score is now set to "seed"s score. ready for the choosing the Bingo Items process and the choosing the starting location process.

Randomly choosing the Bingo Card items and also the spawn points for each team follows roughly the same setup, albeit with some small changes in the randomisation process, if you want me to go over how I do that I can.

At the end of the day for choosing the x & z numbers for each teams spawn location, I have to use AOC and command blocks as you can't do teleport commands using scoreboard values and you can't insert numbers into the tp command from anywhere (at least not that I could figure out)

Again, I'm very open to anything you can come up with as I know my system might not be the best/most ideal. Thank you again for all your interest in my project πŸ˜„

commented

Ah ok, that hitch on teleport commands not being able to use scoreboard numbers does seem like an issue.
My other concept for more variability on spawns was some thing along the lines of:
If random = true, location += 2000
If random = true, location += 4000
If random = true, location += 8000
If random = true, location += 16000
If random = true, location += 32000
... etc, for a while
then, if random = true, -= (radius of the entire world, for negative coords)

You could apply these movements directly to an in world entity, but that seems like it would be awful in terms of worldgen...
I guess I'll have to look into other options.

commented

Perhaps something could be done in the worldgen json, adding an extra void dimension for this system to propagate through, then giving it a little /execute in overworld run tp ~ ~ ~ at the end. Though I think this would only work if the datapack is added on world creation, not added later...

commented

Yea, it's very frustrating that there isn't a better way to do teleport commands. I guess there's the option of writing out many many functions, instead of using the in-world command blocks. It'd allow for more coordinate locations but it'd be a bit more tricky to implement randomly (I think)

commented

So the void world I think might be an option. It'd certainly reduce the amount of lag generating new chunks as there'd be nothing to load. And at that point, every time a new seed is created we could run the first part of the spawn point calculations, so that the locations will be chosen before the game starts (so when that players hit Start, they'll just instantly be teleported out, instead of having to wait for the calculations to be done first).
But yeah I think you're right, though it's worth testing to make sure, that the world would need the datapack pre-world creation

commented

Perhaps we could rotate an entity randomly then use local coordinates to teleport it forward relative to itself by a large distance? A few different options for distance, multiplied by every random rotation possible, would be a lot to work with! If we have a system to get an entity rotated to a seed based degree... not sure what idea I have other than timing, which seems slow...

commented

That sounds very workable. We could use the randomisation code that I have currently to choose the distance and the rotation too and it'd only really need some minor changes I think

commented

Hm, the teleport command can make an entity face another entity, so perhaps randomly placing a target could work. This system would give rotations * distances results, where we still have to set up all the rotations and distances, but that seems like it scales better?

commented

Currently there's 2 selection processes for each team 1 for the x-coord and then 1 for the z-coord. As far as I can remember they are interdependent and don't interact with one another (other than the x location firing first and then the z location). So the x-coord doesn't get multiplied by the z-coord
For example 2 command blocks are chosen 1 for each coord (x & z)
tp @A[tag=oneGuyToTeleport] ~ ~ 910000
tp @A[tag=oneGuyToTeleport] 960000 ~ ~
they get activated one after the other so it ends up with the first person on a team being teleported to 960000 ~ 910000

commented

No, if your current system gives x-coord * z-coord results, that seems the same, lol

commented

and lol it's alright! I'm glad we're both here/awake to bat ideas back and forth! πŸ˜πŸ˜†

commented

My concerns with the incrementally teleporting through a void world concept are:

  • will we lose track of the entity if the chunk unloads?
  • will generating all those void chunks and teleporting through them still be laggy?

I think both of these answers may be yes.
Sorry for my rapid fire comments by the way πŸ˜…

commented

yeah the losing track of the entity is what worries me too. We have the /forceload command but that is a little awkward to work with (especially with the entity constantly moving so quickly).
I'm sure that once the chunk unloads we won't be able to track the entity at all using commands which sucks

I think that generating void chunks will be a lot less taxing that regular chunks that'd need propagating and such with terrain and features and such, but it'd still have an effect of the system

commented

Well, if you have 15 options for an x-coord, and 15 options for a z-coord, that's 225 different locations.
If we have 15 options for a rotation, and 15 options for a distance forward from there, that's also 225 locations.
So it's the same x*z kind of result.
Perhaps we can apply two rotations, to get an x*y*z situation? Then for 10 rotation-As, 10 rotation-Bs, 10 distances, we get 1000 results with the same number of parameters.
Could probably scale to more parameters. Just gotta make sure the rotations stack nicely?

commented

yeah in that regard it'd be the same outcome more or less as the x*z.

I think that an x* y* z situation sounds feasible, at the end of the day it's just more randomisation

commented

I think multiple rotations is the way to go, and could give a fantastic degree of randomisation from few predetermined rotations stacking in randomised ways. I think stacking enough rotations is effectively the same as my very methodical +=2000, +=4000, etc concept without the pain of managing chunks.
If I were to work on this I would still like to replace the actual randomisation with the separate functions to make it easier for me to understand, but it sounds like these are two changes that don't have to be related.

commented

Also I think I just found an error with my command blocks, which might be what caused the issue you reported! I have a whole line in the z-coord command block chain that has x-coords in them (not z-coords) πŸ€¦β€β™‚οΈ I'm fixing that now

commented

The rotation sounds perfect really, especially if it can be stacked in some way.

And lol, that's very fair, I know my code can be quite messy at times πŸ˜… I really should get better at commenting what does what

commented

So to explain rotation stacking clearly:
RotationA: one of 0, 36, 72, 108, ... 324 (1 step shy of 360, which is just 0)
RotationB: one of 0, 3.6, 7.2, 10.8, ... 32.4
RotationC: one of 0, 0.36, 0.72, 1.08, ... 3.24
RotationD: one of 0, 0.036, 0.072, 0.108, ... 0.324
Distance: one of 50000, 100000, 150000, 200000, ... 500000
The entity should receive a random one of each rotation, then teleport forward by the distance.
this is 10+10+10+10+10 parameters we have to put in, 50 parameters, which act multiplicatively for 100,000 results.
That is, a lot less than the 295*295 results than bingo currently offers, but 50 pre-programmed parameters is also a lot less than 590. You'd have to go bigger.

Someone good at maths would probably know how to balance more stacks (A, B, C, D) vs more options within the stacks, for optimal scaling. Idk if I have this yet :p

If we have 9 rotations stacks of 10, plus the distance stack of 10, we get 10^10 results from 100 parameters which is a tidy upgrade. I suppose we need to watch out for how precise rotations can be in minecraft before floating point inaccuracy ruins it πŸ˜…

commented

Also I think I just found an error with my command blocks, which might be what caused the issue you reported! I have a whole line in the z-coord command block chain that has x-coords in them (not z-coords) πŸ€¦β€β™‚οΈ I'm fixing that now

Hmmm, that might be enough to fix issue, making this rework irrelevant anyway, hah.

commented

So how would the entity teleport forward? Is that using ^^^ instead of ~~~?

Yeah I'm not the best at maths so a lot of this kinda flies over my head, but I do think I'm grasping what you're saying.

commented

and yeah lol that was really derpy on my part. It will probably solve some issues, but as you say it's not like Bingo has a lot of spawn point possibilities currently. So I think it might be a good idea to at least look into other possibilities

commented

The wiki gives /tp ^ ^ ^5 as an example to teleport 5 blocks forward, so just have a few options in that form yeah. We probably shouldn't mess with teleporting left and right in this system.
My instinct says things along the lines of 5^5, 10^10, etc will be most efficient, just balance them. I don't know if this is true.

commented

Ahhh okay I see that makes sense. Yeah I was worried about trying to teleport left and right lol, that's what got me confused.

Honestly I could just change on of the sets of command blocks I have now to use ^ ^ ^ instead of ~ ~ ~ and remove the other line. Then just add in the system for the rotation 4 sets of rotations

commented

10*10*10*10*295 is also a pretty big upgrade, so that works! 2,950,000 options up from 87,025 (uh this is lower than I remembered, 100k was bigger it turns out.)

commented

Oh yes, that's a massive upgrade! 😁 I'm just trying to flesh out the commands and functions need for it now. It'll take me a bit but I should hopefully get a testable version done soon ℒ️

commented

Perhaps it is best I leave this to you, I'm reading xzblue.mcfunction and I don't think I'm getting the full story :p
I guess the command blocks are somewhere physical, and this AOC is navigating that physical space...?

commented

yeah, the command blocks run under the bingo hub, and the AOC is moving along them to find the corresponding one to be chosen for the teleportation. It's really weird but it works XD

commented

That makes a lot of sense tbh, though it's a shame to have so much "code" you have to edit in the structure rather than in code

commented

It truly pains me every time I have to work with those long long command block chains in world rather than in code form

commented

So my initial idea is to change the x-coord command block chain into the distance one.
Then remove the z-coord command block chain (cries inside)
Then add in 4 new chains each with 10 command blocks in them (for the rotation)
Then change the code in xzblue, xzred, xzyello and, xzgreen to reflect this

commented

Do these chains operate such that only 1 block from the chain runs? That's how I've imagined the stacks. If that works, sounds good. Sounds like it could be lighter on the server too.

commented

Yeah, the AOC goes along each chain and selects 1 of the command blocks. Those command blocks get cloned over to an area where why get activated in turn. For example currently only 2 command blocks per team get activated, in the new version it'll be 5 command blocks per team, but that's still not too bad at all considering 4 of the 5 are done in the hub area/spawn chunks

commented

Ah ok, more command blocks, but less selecting. No idea if that'll be an optimization but it sounds cheap.
I've noticed for the rotation component of teleport commands, the wiki says this:
Tilde notation can be used to specify a rotation relative to the executor's rotationβ€Œ[JE only] or the target's previous rotationβ€Œ[BE only].
I suppose this means you have to execute as the entity you're rotating, to get them to stack?

commented

Exactly, I think it'll definitely help reduce lag (as you're only going in 1 direction not going to x location and then z location)

Yea, all the command blocks will be written as execute commands so it'll be both at and as the entity

commented

Wait, I saw your commands and had no issue at first, but.
You're using execute at @a[tag=oneGuyToTeleport] run tp @a[tag=oneGuyToTeleport] 930000 ~ ~
I've realised, if this is the player, you're going to have to reset their facing direction to 0 first, and, hope they don't manage to sneak any more rotations in there? I suppose if all the commands are running instantaneously the player can't fudge that, but player input seems like a potential issue that could lead to seeds not being consistent.
Maybe you could work around this by teleporting a non player entity, though, hopefully we don't lose track of it in unloaded chunks?
Perhaps an entity that the player is a passenger of, though, I don't know offhand if that plays nice with teleport?
Or maybe all being instantaneous removes the player's option to interfere and it's fine :p
I'm going to sleep now, so that's all from me for the moment.

commented

It does use the player for teleporting, which is an issue. I've been trying to revise it so that either it'll happen too quickly to be able to be changed by the player (like you say try to make it as instantaneous as possible), or it'll be an entity connected to the player somehow.
Either way this is going to require a lot more testing. But I feel that though it's still worth it, and will work out alright in the end

Have a good sleep! I'm off to work now lol so I'll try and get more work done on this tomorrow when I get some time

commented

Since we can do rotations relative to the executor, I suppose you can apply the rotations to a dummy entity at spawn, then make the player's rotation match it and teleport forwards? Seems like it could reduce risk.
If the rotations are all happening in the same tick then idk how risky it is anyway.

commented

I've been doing some tests and managed to get the randomised chooisng of the 4 rotations and 1 distance sorted.
That's a really good idea, about matching the players rotation to an entity like an armour stand or AOC or something. I think I'll try and do it that way to just make doubly sure that the player can't interfere in anyway with the random rotation.

I also looked a little into updating the custom dimension used to get the tiny biomes and that was quite frustrating. I'll most likely have to redo that from scratch which sucks. I just hope it won't be too frustrating lol

commented

So I've got everything working for the new rotation based spawn location and all the small errors and such I found in the code along the way I fixed too. So in the next day or so I'll release a new (final?) version for 1.17 with these changes.

So now the only thing that's keeping a 1.18 update for Bingo from going ahead is the inability to do small/tiny biomes in the custom dimension. I've tried so much and still not found a way around it to get it to work 😞

commented

Well the first part sounds good!
I know some people who are good with worldgen, so I could probably call in some help if needed. I know a lot of biomes changed in 1.18, do we still want the same subset?

Offtopic to this issue, there are also two features I'd like to implement when I have time - double, triple bingo, where multiple lines are required (this looked pretty straightforward in the code to me?). More complicatedly, I'd like to do a banned item system - so when cards are generated, any items that players have banned will be rerolled. My vision is to do this as a second pass, so the seed integrity is still intact for all items that aren't banned.
Such a system could also let us implement slightly more controversial item sets and have them off by default, which would be cool. Future plans though, just wanted to let you know what I had in mind.

commented

Thank you, I'd certainly appreciate the help. I've been pulling my hair out the last few days with this lol

That does sound cool! I'd love to have those be a part of Bingo. I don't have much time this coming month but I'll try to pull some things together for that. But my top priority is the biome code, as that's the thing keeping a 1.18 release from happening.

commented

So after a month of trying to figure out 1.18 biome code for Bingo, I've just been hitting dead ends and road blocks. It's been quite frustrating. I just don't know what to do. Everything else for Bingo 1.18 is done, all the other code, pixel art and such, it's just this tiny biome code. πŸ˜•
Also I totally forgot to release the new 1.17 version with the new teleportation changes in it, which I've now done.πŸ˜