Jump to content

Asteroid Spawn API?


Recommended Posts

Hi,

Does anybody know if it's possible to change the rules for asteroid spawning? I'm thinking of making a mod that puts the asteroids on more diverse orbits than just a narrow band near Kerbin's orbit (though free time might be a problem), and I was wondering if we even had the tools to do it.

Thanks!

Edited by Starstrider42
Link to comment
Share on other sites

Hi,

Does anybody know if it's possible to change the rules for asteroid spawning? I'm thinking of making a mod that puts the asteroids on more diverse orbits than just a narrow band near Kerbin's orbit (though free time might be a problem), and I was wondering if we even had the tools to do it.

Thanks!

Well, ScenarioDiscoverableObjects have some public fields related to spawn rate. You could probably mess with these to tweak spawn rate. You could also, assuming asteroids trigger it, use a GameEvents.OnVesselCreate callback to change the newly spawned asteroid's orbit as desired. That'd probably be simplest, although maybe a little hacky

Link to comment
Share on other sites

I tried this over the weekend but any asteroids I added to the game, whether discoverable or set as discovered, were immediately removed by the game. I'm not sure what's causing this but the likely culprit is the ScenarioDiscoverableObjects class. You can tweak that class' public variables and call for it to spawn an asteroid, but I'm pretty sure all the actually spawning mechanics are private.

Link to comment
Share on other sites

I gave it a shot and ended up with some results.

81LVP.jpg

There is more to be done but it shouldn't be too difficult to figure out exactly how to control when ScenarioDiscoverableObjects destroys asteroids. It has something to with the values in DiscoveryInfo and a signal strength. I just bypassed all that to see if I could create an asteroid with this:

        public void Start()
{
StartCoroutine(DelayedStart());

}

public System.Collections.IEnumerator DelayedStart()
{
while (!FlightGlobals.ready || HighLogic.CurrentGame.scenarios[0].moduleRef == null)
yield return 0;

ScenarioDiscoverableObjects discov = (ScenarioDiscoverableObjects)HighLogic.CurrentGame.scenarios.Find(scenario => scenario.moduleRef is ScenarioDiscoverableObjects).moduleRef;

if (discov == null)
Log.Error("Did not find ScenarioDiscoverableObjects!");

GameEvents.onVesselCreate.Add(CatchAsteroidSpawn);

for (int i = 0; i < 100; ++i)
discov.SpawnAsteroid();

GameEvents.onVesselCreate.Remove(CatchAsteroidSpawn);
}



public void CatchAsteroidSpawn(Vessel vessel)
{
vessel.DiscoveryInfo.SetLastObservedTime(Planetarium.GetUniversalTime());

// track it by default, else its orbit won't be visible in mapview
vessel.DiscoveryInfo.SetLevel(DiscoveryLevels.StateVectors | DiscoveryLevels.Name | DiscoveryLevels.Presence);

Orbit newOrbit = new Orbit((UnityEngine.Random.Range(0f, 360f)), 0f, 1060053.49854083, 217.714701468054, 126.848000556171, 0.52911447506945, Planetarium.GetUniversalTime(), FlightGlobals.Bodies.Find(body => body.name == "Eve"));
newOrbit.UpdateFromUT(Planetarium.GetUniversalTime());

vessel.orbitDriver.orbit = newOrbit;
}

Link to comment
Share on other sites

Thanks, xEvilReeperx! Maybe I will try the asteroid idea after all.

EDIT:

I tried this over the weekend but any asteroids I added to the game, whether discoverable or set as discovered, were immediately removed by the game. I'm not sure what's causing this but the likely culprit is the ScenarioDiscoverableObjects class. You can tweak that class' public variables and call for it to spawn an asteroid, but I'm pretty sure all the actually spawning mechanics are private.

I tried doing some basic tweaks to the code, completely removing the manual asteroid spawn and commenting out the code for forcing tracking. It appears that xEvilReeperx's approach doesn't run into the same problem regex found -- I can hijack auto-spawned asteroids, and they stay put long enough to be manually tracked from the station screen. I'll try heliocentric orbits this evening.

Edited by Starstrider42
Deleted out-of-date image
Link to comment
Share on other sites

Well, the dimensions may need some work, but that's definitely an asteroid belt. Thanks again to both of you for all your help, I think I can take it from here. :)

You beat me to it! :P I'm working on my own but trying to create separate tracks for inner (Eve and Moho, fairly rare), Kerbin (normal), belt (between Duna and Jool), outer (outside Jool orbit), and Jool trojan asteroids. I'm planning on intercepting every Space Object that gets created and, if it's not mine, removing it (turning the tables on YOU, SQUAD!). Anyway, good work!

Link to comment
Share on other sites

You beat me to it! :P I'm working on my own but trying to create separate tracks for inner (Eve and Moho, fairly rare), Kerbin (normal), belt (between Duna and Jool), outer (outside Jool orbit), and Jool trojan asteroids. I'm planning on intercepting every Space Object that gets created and, if it's not mine, removing it (turning the tables on YOU, SQUAD!). Anyway, good work!

I'm planning to create separate asteroid groups as well (though not in as much detail as you), it just requires some logic I haven't written yet.

Hey, if you're willing to share, mind if I use that in RSS? I didn't have a chance to change spawning logic in v6 and I'd rather not reinvent the wheel. :)

Once I get things working, yes (at the moment it's at very much a proof of concept stage, everything's hard-coded). The goal is to make it like Custom Biomes, in that everything's configurable, and then let players write files for RSS, PlanetFactory, etc. Once I have a presentable alpha I'll post it in the add-on development thread.

I'll try to have something official by the end of the weekend -- I think "how to edit asteroids" was the main hurdle -- but no promises, I've got RL stuff to juggle.

Edited by Starstrider42
Link to comment
Share on other sites

Inner populations:

gLwtG6G.png

Outer populations:

9NFwKxd.png

Basically just intercepting any asteroids the game makes and putting them into different orbits. I need to add code to generate the orbit for the Jool trojans.

Link to comment
Share on other sites

I have been working on a similar thing, but my idea was to define special areas in the solar system where asteroids could be detected, like main asteroid belt and Kuiper belt. One would have to send a spacecraft close to this area and to employ special modules like telescopes to detect asteroids. And of course some asteroids would just be detected near Kerbin similar to how it happens in stock now, assuming there are telescopes on Kerbin. Maybe there could be extra powerful telescopes higher up on the tech tree that would allow to detect asteroids very far away, but the main idea is to allow asteroid detection not only near Kerbin which does not make sense but anywhere where there could potentially be asteroids.

Seems like people in this thread making something similar, so I should probably stop.

Link to comment
Share on other sites

I have been working on a similar thing, but my idea was to define special areas in the solar system where asteroids could be detected, like main asteroid belt and Kuiper belt. One would have to send a spacecraft close to this area and to employ special modules like telescopes to detect asteroids. And of course some asteroids would just be detected near Kerbin similar to how it happens in stock now, assuming there are telescopes on Kerbin. Maybe there could be extra powerful telescopes higher up on the tech tree that would allow to detect asteroids very far away, but the main idea is to allow asteroid detection not only near Kerbin which does not make sense but anywhere where there could potentially be asteroids.

Seems like people in this thread making something similar, so I should probably stop.

Not at all. I, at least, am not touching the code for "discovering" asteroids, so if you could figure out how to control that it would be a big help to everyone.

Also, I move that the hypothetical belt of comets out beyond Jool be called the Kuper belt, in analogy to the Mun. :P

Link to comment
Share on other sites

Nice. But why's there an asteroid-free gap between Duna and Kerbin?

That would normally be handled by not altering an asteroid's orbit but I'm finding that onVesselCreated is called multiple times and the orbit is always changed. Might have something to do with altering the orbit firing that event. I'll be tracking that down in the next few days along with figuring out the lagrange orbits.

I'll post my code in a day or two; I have no interest in maintaining a mod right now, this is just for fun, but hopefully it'll have something useful for others.

Link to comment
Share on other sites

  • 4 weeks later...
Well, ScenarioDiscoverableObjects have some public fields related to spawn rate. You could probably mess with these to tweak spawn rate. You could also, assuming asteroids trigger it, use a GameEvents.OnVesselCreate callback to change the newly spawned asteroid's orbit as desired. That'd probably be simplest, although maybe a little hacky

Did some experimentation with ScenarioDiscoverableObjects. Part of the problem is that apparently, whenever there is a scene change, ScenarioDiscoverableObjects gets reloaded -- but only AFTER the call to <My MonoBehaviour>.Start(). Thought that wasn't supposed to happen.

Checking for and forcing settings changes on asteroid spawn is enough of a workaround to let me experiment with the features. Unfortunately, spawnInterval appears to be based on real time, not game time, so you can't use the existing framework to generate a fixed discovery rate. Maybe if I set spawnInterval and spawnOddsAgainst to highly unfavorable values, then called SpawnAsteroid() myself...

Link to comment
Share on other sites

Hi, guys, I need your help!

I am making a telescope mod and I need a (probably) very simple plugin with which more asteroids would appear when you activate the telescope. Is anyone willing to help me on this?

Link to comment
Share on other sites

  • 3 weeks later...

A request for those of you with some background in parts and modeling.

A ModuleAsteroid has three persistent fields: name, random seed, and a "prefab URL". Save file editing has confirmed that the seed and the prefab URL are the only pieces of information needed to specify an asteroid body -- change the URL, for example, and you can change the size of the asteroid model.

The problem is I don't actually know what prefabBaseURL means. I know it has one of the following five forms:

  • Procedural/PA_A
  • Procedural/PA_B
  • Procedural/PA_C
  • Procedural/PA_D
  • Procedural/PA_E

but I have no idea what kind of entity the URL points to, or even where the "Procedural" directory is supposed to live (apparently, not in the file system). In short, I need help.

Challenge:

  • Locate the resources linked by prefabBaseURL. They must exist somewhere in the KSP install.
  • Emulate the existing resource format to create a new size class and/or texture for an asteroid.
  • Show that prefabBaseURL can be told to point to the homemade resources.

Reward:

  • 5 rep
  • Credit in the first Custom Asteroids release to incorporate custom prefabs
  • My eternal gratitude

Link to comment
Share on other sites

Challenge:

  • Locate the resources linked by prefabBaseURL. They must exist somewhere in the KSP install.
  • Emulate the existing resource format to create a new size class and/or texture for an asteroid.
  • Show that prefabBaseURL can be told to point to the homemade resources.

Those urls lead to ProceduralAsteroid objects loaded with Resource.Load. Unfortunately, I couldn't find any way to edit asset bundles at runtime and couldn't get Resource.Load to load anything that didn't exist when the bundles were created so that's a bit of a dead end.

On the other hand, modifying the actual mesh and/or texture is fairly easy. Here's a dump of an asteroid vessel:

[LOG 02:15:26.881]  Transform: PotatoRoid (Ast. QFG-283)
[LOG 02:15:26.882] ---> Transform: model
[LOG 02:15:26.882] ------> Transform: Asteroid
[LOG 02:15:26.883] ---------> Transform: Visual
[LOG 02:15:26.883] ---------> Transform: Collider
[LOG 02:15:26.884] ---------> Transform: ColliderConvex

[LOG 02:15:26.885] PotatoRoid (Ast. QFG-283) has components:
[LOG 02:15:26.886] ...c: UnityEngine.Transform
[LOG 02:15:26.886] ...c: Vessel
[LOG 02:15:26.887] ...c: OrbitDriver
[LOG 02:15:26.887] ...c: OrbitRenderer
[LOG 02:15:26.888] ...c: FlightIntegrator
[LOG 02:15:26.888] ...c: Part
[LOG 02:15:26.889] ...c: ModuleAsteroid
[LOG 02:15:26.890] ...c: UnityEngine.AudioSource
[LOG 02:15:26.891] ...c: UnityEngine.Rigidbody
[LOG 02:15:26.891] ...c: CollisionEnhancer
[LOG 02:15:26.892] ...c: PartBuoyancy
[LOG 02:15:26.892] --->model has components:
[LOG 02:15:26.893] ......c: UnityEngine.Transform
[LOG 02:15:26.893] ------>Asteroid has components:
[LOG 02:15:26.894] .........c: UnityEngine.Transform
[LOG 02:15:26.895] .........c: PAsteroid
[LOG 02:15:26.895] --------->Visual has components:
[LOG 02:15:26.896] ............c: UnityEngine.Transform
[LOG 02:15:26.896] ............c: UnityEngine.MeshFilter
[LOG 02:15:26.897] ............c: UnityEngine.MeshRenderer
[LOG 02:15:26.898] --------->Collider has components:
[LOG 02:15:26.898] ............c: UnityEngine.Transform
[LOG 02:15:26.899] ............c: UnityEngine.MeshCollider
[LOG 02:15:26.900] --------->ColliderConvex has components:
[LOG 02:15:26.901] ............c: UnityEngine.Transform

91Nas.jpg


{
for (int i = 0; i < FlightGlobals.Vessels.Count; ++i)
{
Vessel target = FlightGlobals.Vessels[i];

if (target.packed || target.rootPart.FindModulesImplementing<ModuleAsteroid>().Count == 0)
continue;

Log.Write("Working with {0}", target.name);

Part root = target.rootPart;

//root.transform.PrintHierarchy();
//root.gameObject.PrintComponents();

var newTex = new Texture2D(32, 32);
var pixels = newTex.GetPixels32();

for (int p = 0; p < pixels.Length; ++p)
pixels[p] = new Color32((byte)UnityEngine.Random.Range(0, 255), (byte)UnityEngine.Random.Range(0, 255), (byte)UnityEngine.Random.Range(0, 255), 255);

newTex.SetPixels32(pixels, 0);
newTex.Apply();

Transform visual = root.gameObject.transform.Find("model/Asteroid/Visual");
Transform collider = root.gameObject.transform.Find("model/Asteroid/Collider");

// change mesh
var cubeGo = GameObject.CreatePrimitive(PrimitiveType.Cube);
MeshFilter asteroidMf = visual.gameObject.GetComponent<MeshFilter>();
if (asteroidMf == null) Log.Error("null asteroid meshfilter");

asteroidMf.sharedMesh = cubeGo.GetComponent<MeshFilter>().sharedMesh;
asteroidMf.gameObject.transform.localScale = Vector3.one * 10f; // default is a little low

GameObject.DestroyImmediate(cubeGo);

// change texture
var mat = new Material(Shader.Find("KSP/Emissive/Diffuse"));
mat.SetColor("_EmissiveColor", Color.blue);
mat.mainTexture = newTex;


visual.renderer.material = mat;
visual.renderer.castShadows = true;
visual.renderer.receiveShadows = true;

// modify collider
MeshCollider coll = collider.gameObject.collider as MeshCollider;
coll.sharedMesh = asteroidMf.sharedMesh; // be mindful of 255 tri limit
collider.localScale = visual.localScale;
}
}
}
            if (GUI.Button(new Rect(100, 400, 128, 32f), "Test asteroid"))

As for size class ... That looks hardcoded I'm afraid :( You'd probably have to replace the scenario and ModuleAsteroid entirely

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...