Comments (17)
Notes on a possible implementation:
Define a large, rectangular area around the player that should always be populated with interesting things. Outside of this "area of interest" (AOI), no entities should exists. When the player moves, figure out the newly covered area, which should be devoid of any entities. Fill this area with random new entities until the object density is satisfactory.
To keep things interesting, the spawning system should provide some variety. That could be achieved with a "spawn table" that lists each object type and a measure of probability for spawning it.
Despawning simply involves finding all entities outside the AOI and destroying them.
from thrive.
I would like to be assigned to this, as I have ideas on how to implement it. They are shown below.
First of all, I will probably do this in Lua.
The SpawningSystem will handle all the data related to the spawning of entities, and it will need to be updated when new things to spawn are added. It will probably hold some sort of spawn table, but since different objects have different properties such as size, and different microbes vary greatly, the SpawningSystem needs to randomize said properties.
A SpawnComponent will hold data such as spawn radius, which determines how far away a component spawns, despawn radius, which determines how close an entity can be to the player while still having a chance to despawn, and a persistant attribute (boolean) which determines whether the entity is supposed to despawn. There may be other attributes to add, but I think these will be enough for a simple spawning system.
Microbe entities, agent emitter entities, and all other entities that will be spawned into the map need this SpawnComponent.
If these ideas are good, I will go ahead and implement them. Let me know if I need to rename anything.
Also, I would like to know if there is a way to include spawning information (such as how to randomize size) of specific entities outside the file defining SpawningSystem.
from thrive.
I'm not sure I understand how you will go from a SpawnComponent to spawning new entities. In particular, how will the SpawnComponent determine what components are added to the new entity?
Also, I would like to know if there is a way to include spawning information (such as how to randomize size) of specific entities outside the file defining SpawningSystem.
You can add multiple script files to the manifest. As long as file A comes before file B, you can use A's global variables in B's global scope. So if you offer some kind of API for your SpawningSystem with which others can register their "blueprints" for entities, you can put your script file containing the SpawningSystem relatively high in the manifest, so that later files can use that API.
from thrive.
I'll add, creating a randomness-toolbox-class to issues, so things like seeds and an interface to the new c++11 random utilities are concentrated.
from thrive.
@nimbal I see your confusion, and I am not entirely sure. I'm still getting used to the Entity, Component, System framework.
From what I can tell, to spawn an entity manually (in code), you give it an ID/name, give it a set of components, and change the data stored in each component if necessary. Sometimes, a wrapper class will perform these operations more conveniently.
I may have been mistaken about the SpawnComponent. Instead, it seems to me like the SpawningSystem will have to do absolutely everything pertaining to spawning. Please tell me if there are better alternatives.
The problem I see is that different entity types spawn in different ways. My idea about SpawnComponent was that there could be some template entities that include the SpawnComponent, which would also hold data such as which components should spawn with the entity. What I would really like, though, is if the SpawnComponent could somehow be given a function as data that actually spawns the entity, but as far as I know, that does not fit within the framework.
A possible solution would be to create a mini system for each type of entity to spawn. The system that spawns decoration would handle randomizing the size and type, while systems that spawn microbes would handle giving the microbes all its organelles. Each type of object to spawn is different enough that different functions are needed to spawn them.
Please tell me if I am missing something. Should the "systems" I mentioned just be functions for the SpawningSystem defined in other files?
from thrive.
SpawnComponent could somehow be given a function as data that actually spawns the entity
I like that idea. The template entities isn't a very clean solution, but i can't think of a better alternative. Nimbal will have to chime in!
a mini system for each type of entity to spawn
I think thats a bit overkill, especially if you have the SpawnComponent know how to create the entity
from thrive.
How about this: the SpawnSystem maintains a list of "factory functions". Each of those functions takes an EntityId and can then attach whatever components it wants to it, with whatever property values are fitting. The SpawnSystem provides functions to register (and unregister) such factory functions.
If nobody pokes unpatchable holes in the above idea, there's another problem left to tackle. How will the SpawnSystem decide the when to spawn new entities, where to spawn them and most importantly, which type of entity to spawn?
from thrive.
Excuse my ignorance, but if we go down the path of having SpawnComponent store functions defining how an Entity is spawned, how do we do so?
As far as I know, for Lua, we would just hold the function as a variable because that works. However, for C++, would function pointers be the way to go, or is there a better way? I'm more familiar with C than C++ because of the classes I am currently taking.
Also, how would we link functions used as data for components between C++ and Lua? I can only assume we will have to, but I am not quite familiar with how scripting is implemented in Thrive
I started writing this post before Nimbal commented, so this post is somewhat outdated.
from thrive.
Ah, sorry. I should have mentioned that there would be no need for a SpawnComponent. Also, generally, it's a bad idea to put Lua functions into components, because these functions can't be easily serialized, so saving the component in a savegame is almost impossible.
If we ever decide to move the SpawnSystem from Lua to C++, we could use C++11 lambdas, which pretty much work like Lua functions in that they can be passed around and it just works. However, it is very likely that we'd still need to register factory functions from Lua. In that case, we can use luabind::object
that comes with the luabind library. This object represents a Lua value, in our case a function, and provides an overloaded call operator.
from thrive.
Responding to your first paragraph, I realized that SpawnComponent was unnecessary because of the suggestion you gave in your previous post. In my previously held view of SpawnComponent, each entity that contains that component would be created at the start of the game to act as a template, but I admit that is clunky.
I like the idea of "factory functions." They seem pretty robust to me. However, for the sake of diversity, some areas of the world may act differently from others, so if there is an area that generally has smaller bubbles, SpawnSystem may need more control than just calling a factory function with no arguments.
In other words, to prevent a need of refactoring later on, SpawnSystem will generally need to manually call the factory functions in its own way rather than something simpler such as having a list of functions and probabilities and choosing which function to call that way. In this case, Lambdas will probably be unnecessary.
By the way, I do have ideas on how to figure out a spawning system because I have previously made a game that spawned enemies in an open world environment and was able to get a good distribution no matter how the player moved. Please tell me if you want me to explain the algorithm I have in mind.
from thrive.
SpawnSystem may need more control than just calling a factory function with no arguments.
Nothing stops us from passing more arguments into the functions. It just has to be well defined what the arguments are. Concerning future extension of that argument list, Lua has a... "quirk" in that it's not an error to call a function with fewer arguments than it is defined for. The missing arguments will just be nil
inside the function:
local function f(x, y, z)
if z == nil then
print "z is nil!"
end
end
f(1, 2) -- Prints "z is nil"
from thrive.
I understand, but I'm not sure whether that clears up the issue.
There are other complexities to consider. Maybe the system will spawn a cluster of bubbles at one location and a lone microbe somewhere else. Maybe it will spawn a cluster of agent emitters of different types. While we won't necessarily implement bubbles, other things that should spawn may have similar complexity.
Of course, the initial dynamic spawning system will probably only spawn one entity at a time and keep the distribution constant, but to allow the flexibility I mentioned, the SpawnSystem will likely need to handle each entity type separately.
The only downside I see is that it will make the code defining the spawn cycle longer, but with few entity types (microbe, decoration, emitter, compounds), I doubt this is an issue.
I doubt that factory functions were initially designed to be the way I am describing them, but I think that the way I am describing them would work.
from thrive.
Do I understand you right, you want the SpawnSystem to explicitly know about what entities it needs to spawn (as opposed to hiding it behind an opaque factory function)? I'm not so sure that's a good idea, as it greatly increases the coupling between the system and anything that is supposed to randomly spawn.
To handle more complex spawning behaviour like clusters, we can always register a separate factory function for them. So we have one function spawnMicrobe
for spawning a single microbe, and another function spawnMicrobeColony
for spawning a whole bunch of them in close proximity (probably reusing spawnMicrobe
in the process).
I know it can be tempting to try and foresee all eventualities, but usually, YAGNI applies. So don't worry too much about what weird ideas the designers / users might come up with.
from thrive.
You almost understand me right, I didn't want the SpawnSystem to explicitly know about what entities it needs to spawn. I only thought that it would be a necessary evil.
After sleeping on it, I better understand your point, and I totally agree with you.
I propose creating a function in SpawnSystem that takes, as parameters, a factory function and spawn frequency. SpawnSystem can then use the data gained to properly handle spawning.
from thrive.
Sound like you both agree then! Time to make it happen!
from thrive.
Will do. I plan on working on it today, as soon as I can. I can always make a modification if it turns out that the function in SpawnSystem I proposed is not a good idea.
from thrive.
I added a basic SpawnSystem for review and possible future modification.
from thrive.
Related Issues (20)
- Clouds have slightly artifacty / glitchy looking edges when overlapping near the edge of the screen
- Improve the licenses menu loading speed with Godot 4
- Investigate potentially glitchy audio when many microbe sounds playing at once (audio latency) HOT 2
- Reduce JSON read memory allocations
- Find out why CI import of assets doesn't result in same file hashes
- Save reading can randomly start failing after playing some time HOT 9
- The “You're thriving” text goes beyond screen borders
- The game still randomly locks up in the C# code HOT 2
- Removed multicellular cell can incorrectly keep digesting things
- Editor screen fails to load anything randomly HOT 4
- Check useTopDownOrientation in SoundListenerSystem really was meant to use FromEuler HOT 5
- Unable to manually select the screen resolution HOT 1
- Zooming back in on the evolutionary tree doesn't work (zooming out works but can zoom out too far) HOT 1
- Game locks up randomly with message Error: Attempt to disconnect a non existent connection from 'root,Window#32044483792>' HOT 3
- Attempt to disconnect a nonexistent connection from `'root:<Window#32010929360>'. Signal: 'focus_entered', callable: ''.` HOT 1
- Make CompoundProgressBar into a tool script once possible
- Make CustomRichTextLabel a Tool script if at all possible to make editor edited GUIs show up better
- Going to the editor causes 160 new orphaned Nodes each time
- Add interface to TaskExecutor to allow non-allocating tasks to be used
- Floating chunks can spawn inside the player cell colony (which should be prevented)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from thrive.