Jump to content

Recommended Posts

Posted

I'm playing with a dynamic spawning system, but having trouble finding an approach to test spawn points to reject / move them prior to spawning. the most obnoxious issue for me is that if the player is near water, I see no good way to reject spawn points landing in the water. Ideally, the xmarker placed dynamically (x,y offset from some point) should see if it's in water and try other spots (rotate 30 degree increments e.g.). But the obvious issue is that water is a giant horizontal slab so using PO3's extended isRefInWater check doesn't help because the shore near the water also has the water volume beneath it and at the same height (ie. false positive for water)

I tried thinking about an approach like: place xmarker at x,y offset from point, move z value to height of navmesh, then test isRefInWater(), but there's no way I can see to 'move z value to height of navmesh'.

Anyone have any suggestions here ?

Posted

Traditionally, finding the navmesh Z is done by placing an object or marker and using havok to make it settle to ground level.

In some other context, I need dynamic spots where to safely teleport NPCs.  I mark previous positions of the player for that purpose.  They are all obviously appropriate for my purpose, and you can easily add a isSwimming check in your case.  Though, admittedly, it's not ideal for "randomly" placing encounters.

 

Posted
  On 6/1/2025 at 10:37 AM, Qvorvm said:

Traditionally, finding the navmesh Z is done by placing an object or marker and using havok to make it settle to ground level.

In some other context, I need dynamic spots where to safely teleport NPCs.  I mark previous positions of the player for that purpose.  They are all obviously appropriate for my purpose, and you can easily add a isSwimming check in your case.  Though, admittedly, it's not ideal for "randomly" placing encounters.

 

Expand  

Really appreciate the ideas. I had no idea about using havok in that way !

The direction I think I'm going is the following: use my normal method (random angle, random distance between a min and max = x,y offsets from a center point) UNLESS the player's position -500 on the z is in water (PO3's function). if it's in water -- ie. if the player is proximate to a lake or the sea -- revert to the method employed by Tonycubed (genesis spawns), meaning: 

spawnPoint = Game.FindRandomReferenceOfAnyTypeInListFromRef(LandSpawnFallbacks, PlayerREF, maxDist)

where landspawnfallbacks is a formlist of tree/bush types. This very effectively avoids spawning in the water for obvious reasons.

I then WHILE through 5 such checks until finding a valid one far enough from the player (getdistance(playerREF). If nothing found, no spawn, which is fine.

This method is a little hinky, though it only runs on a (chunky) edge case. In most cases the player isn't standing on the shore of a lake or the sea of ghosts.

Posted

i'll just leave this for anyone looking for a solution re spawning. The problem I encountered with the approach I outlined above is that Game.FindRandomReferenceOfAnyTypeInListFromRef isn't as 'random' as it's name suggests. It seems to be so efficient it's apt to find the same REF (tree, bush in world) in multiple searches, rather than it choosing from the REFs randomly. This meant that spawns were generally biasing to one side, correlating to 'hits' it was constantly getting from wherever it started its search.

My solution: make an imaginary circle around the player out some distance (2700u radius in my case), and create points at 45-degrees along the circle (8 points). Each one is then the source for actually independent FindRandomRef searches. Then I store a set of known valid spawn points (where it found a tree/bush). Then i choose among them randomly when ready to call the spawn.

Result: fairly natural spawns in interesting spots, never in the water.

Note: my context is a peculiar one--so may not be useful to many. I'm generating spawns around a fixed objects and creating this array of valid spots only when the player puts down a tent. More dynamic spawning--eg. around the player as they're walking around--would require a different approach probably.

Posted
  On 6/2/2025 at 6:59 PM, csbx said:

Game.FindRandomReferenceOfAnyTypeInListFromRef isn't as 'random' as it's name suggests.

Expand  

There no such thing as random on a PC mate, it just smoke and mirrors, and clever math!

This is just for fun, not for actual use as an example demonstrating the math using papyrus for you

Careful the magic will gone for forever..  if you look

  Reveal hidden contents

disappointing is it not?

  Reveal hidden contents

 

I like your solution to increase the randomness.. 🤣 too

Posted
  On 6/4/2025 at 2:11 AM, PeterMartyr said:

There no such thing as random on a PC mate, it just smoke and mirrors, and clever math!

This is just for fun, not for actual use as an example demonstrating the math using papyrus for you

Careful the magic will gone for forever..  if you look

  Reveal hidden contents

disappointing is it not?

  Reveal hidden contents

 

I like your solution to increase the randomness.. 🤣 too

Expand  

Peter, I would be a weepy mess right now EXCEPT for the fact that when I was a wee lad I looked under the Wizard's robe when learning to script in Pascal. 7th grade, I think.  So yeah, you're right, but also pedantic in a sense, because the effect is good enough to work as random in most situations. I know you know this !

Seriously, though, knowing what you know, do you actually employ strategies when needing a 'random' number ?

Posted

I have never had the need in papyrus to fix it, plus the Utility Script RandomInt function would use epoch time

https://en.wikipedia.org/wiki/Epoch_(computing)

not real game time, plus all the math of C++, so it already its is better than anything we could do with papyrus, all we have is real game time, and basic math

https://ck.uesp.net/wiki/GetCurrentRealTime_-_Utility

it does not compare, like I said in my post, it is not for actual use, just a math demo, and I stand by that

We would also need not only a Random but an Array of refs to select from, thinking.... OGM this is Youtube algorithm 

OK idea

cell location = player.getParentCell()

https://ck.uesp.net/wiki/GetNumRefs_-_Cell

the example look on the wiki is auto harvest, but the gist is there

https://ck.uesp.net/wiki/GetType_-_Form

using SKSE make a super form array of all the refs in your list, if you get over 128 refs from all your forms

https://ck.uesp.net/w/index.php?title=CreateFormArray_-_Utility&action=edit&redlink=1

https://ck.uesp.net/w/index.php?title=ResizeFormArray_-_Utility&action=edit&redlink=1

You may break the Array 128 limit here, welcome to the club brother

Shuffle it like deck of cards mixing them up real nice, pretend it is blackjack game, and they are a deck of cards

then Waste some elements like dealer at the casino to stop blackjack player counting cards, and increase the randomness

Stopping here but there is more, like handling removing a ref from the array if it used to place object, so it is not selected again. FYI to keep the Blackjack 

I do not what overwhelm you, basically we going to handle everything, you sure you want this? When You have working code, it might not be much better in the end?

 

 

baby steps, some questions, how many forms are being checked for, I could see tree and flower in the form list, plus there is 

int MyType = akForm.GetType()

to debug it too, But I am just brainstorming, not saying it is going to work... but make our own array of Form Refs and handle everything, but is GetNumRefs this Form going to work for you?

step one is simply debug the forms in your list to see if you get a return that not...

f*#@ Stupid Wikki does not say, let's assume -1 or 0 ¯\_(ツ)_/¯ is a negative result.. 

Posted

Just for fun I prototype above and included the debug code for

int MyType = akForm.GetType()

in the OnInit Event, I personally would preferred to test that before I prototype anything, but is Saturday and I had nothing to do.. It compiled, but it is untested in every way

  Reveal hidden contents

 

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...