Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    7
  • comments
    12
  • views
    1369

About this blog

This blog will contain new infos on Lyfe, the game that sets out to become a spiritual successor to Spore.

Entries in this blog

 

Reworking the Compound Clouds (Tutorial)

Hello once again to this entry to our devblog.
This one will show the basics how we reworked the compound clouds to look - let's be honest - a lot better than they did before.
The last version consisted of one class CompoundCloud which was represented by a procedural mesh component. That one started out as a simple cube and then offset the positions of the vertices by a randomly chosen amount between two previously chosen values. That looked... functional at best. And interaction with the player was pretty much not practical and computationally expensive.
So the next idea we came up with was to make a cloud of sphere meshes and just have the player collect every one of those. This resulted in a new hierarchy. At the top there's still the CompoundCloud but it now has an array of Compound_ParticleComponents for its representation. Each one of those has a sphere mesh  to handle collision and a particle system to look pretty. A short demo of the new system can be found here.
We should probably start with the particle system. Not many steps requiered here. 1. Create a new particle system
  2. Click on "Required" and in the first section ("Emitter") set a material (will be shown later) and the Screen Alignment to "PSA Rectangle" (this might not make a difference to the standard but it's set to that for our system). Then scroll down and set a cutout testure in the section "Particle Cutout". We used our heart icon you might have seen in one of our update videos. (we also changed the background color to something light so you can actually see what is happening) 3. Click an Spawn.
There's a little more to do here. First of all set the rate in the "Spawn" section to "Distribution Float Uniform". Same for the rate scale. Play around with the values a bit or just take what we got there.
Next set the particle burst method to interplated. The burst scale distribution should be "Distribution Float Particle Parameter". Once again play around with the values until you have something you like. 4. Go into "Lifetime" and set Min to 2 and Max to 1.1 (Again, once you're done with this tutorial just play around with this values) 5. Go to "Initial Velocity" and reduce the Min and Max values. We recommend between 2 for all Max and -2 for all Min. This will keep your particles closer together and not have them shoot in one direction. 6. Next up add a seeded initial location and set its bounds to something you like. 7. And the final step is to add a seeded sphere. You should now have something roughly looking like this. The Material: (absolutly nothing special)   Now for the interesing part: The code. This is perfectly doable in blueprints, too but since we're mostly working in C++ I'll show how we solved it in code. I'm also only gonna show the constructors of the CompoundCloud class and the Compound_ParticleComponent class since this tutorial mostly deals with the look of the clouds. If you're interested in how any other part works just let me know and maybe I'll make a short explanation for that in the future.   The code then: uint8 particleCount = StaticMaths::RR(CLOUD_PARTICLE_MIN, CLOUD_PARTICLE_MAX); We get a random value for the number particle systems we want to use. In our case this is our own function that simply determines a number between two other numbers. std::string center = "CenterSystem"; UCompound_ParticleComponent_Cell* temp = CreateDefaultSubobject<UCompound_ParticleComponent_Cell>(FName(center.c_str())); particles.Add(temp); RootComponent = temp; Then we set up the center component. All the other systems will circle around this one. This also functions as the rootComponent for the actor. The UCompound_ParticleComponent_Cell is the second class and we will deal with it later. for (uint8 i = 0; i < 100; i++) { for (int j = 0; j < pow(i, 2); j++) { //define the name for the current particle system //ParticleSystem_<circleNum>_<Num>_<randomSeed> std::string name = "ParticleSystem_"; name.append({ static_cast<char>((i + 1)) }); name.append({ "_" }); name.append({ static_cast<char>(j + 1) }); name.append({ "_" }); name.append({ static_cast<char>(j + i) }); //create the particle system with the newly defined name UCompound_ParticleComponent_Cell* temp = CreateDefaultSubobject<UCompound_ParticleComponent_Cell>(name.c_str()); particles.Add(temp); temp->SetupAttachment(RootComponent); //set up random location within a circle double a = (((double)rand() / (RAND_MAX)) + 1) * 2 * PI; double r = (CLOUD_RADIUS_STEPS * (i + 1)) * sqrt(((double)rand() / (RAND_MAX)) + 1); double x = r * cos(a); double y = r * sin(a); FVector location = FVector(x, y, 0); temp->SetRelativeLocation(location); //finally: check if number of elements in array is particle count //if so, stop this loop if (particleCount - 1 == particles.Num()) { break; i = 100; j = pow(i, 2); } } if (particleCount - 1 == particles.Num()) { break; i = 100; } } This part is where the magic happens. Basically we want to have somewhat circular shapes around the center system. So the outer for-loop with i counts the circles. The 100 is a dummy value since there will never be that many circles and it would be a waste of resources to actually calculate the true number of circles. We only need to know the number of particleComponents which is our particleCount. The inner loop with j counts from 0 to i to the power of 2. So on every circle there are i*i particleComponents. Next up is a bit of naming. Not really relevant.
Then we create another particleComponent and add it to the actor and the array.
What comes next might be interesting for some: this formular basically determines a random position on a circle. So we take (i + 1) times our pre-defined cloud radius steps to get the radius of our current circle and we have all the data we need. Everything else can be determined from that and a random number.
Whe then set that location for the particleComponent. At the end of the inner loop we check if we already have all the particles we need. If so set i and j to their max values so the loops stop. This is why we didn't need to calculate how many circles there will be when we start the loops.   Don't worry, the particleComponent involves less maths. //instantiate mesh component and particle system component particleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleSystem")); mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh")); particleSystem->SetupAttachment(this); mesh->SetupAttachment(this); //Collision binding mesh->bGenerateOverlapEvents = true; mesh->OnComponentBeginOverlap.AddDynamic(this, &UCompound_ParticleComponent_Cell::BeginOverlap); mesh->OnComponentEndOverlap.AddDynamic(this, &UCompound_ParticleComponent_Cell::EndOverlap); We create default subobject for the mesh and the particles system and then bind the collision functions. Easy as that. //get the mesh and set it auto meshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Game/Meshes/ball.ball'")); if (meshAsset.Object != nullptr) { mesh->SetStaticMesh(meshAsset.Object); mesh->SetVisibility(false); mesh->RelativeScale3D = FVector(5.f); } else { Logging::Log("Could not find Asset 'ball' at path in Compound_ParticleComponent_Cell"); } Then we load the mesh and set it. We also scales up the sphere mesh since it turned out to be way too small and the player would miss it a lot of the time. (That Logging::Log there doesn't really concern you. It's a function we wrote that simple writes a message into a file and onto the screen. Helpful for debugging. I left it in there for this tutorial because I think you should always have something in your code tell you when something goes wrong.) //get the needed particle system and set it in the component try { //static ConstructorHelpers::FObjectFinder<UParticleSystem> psAsset(TEXT("ParticleSystem'/Game/ParticleSystems/PS_CompoundCloud_SingleCelled.PS_CompoundCloud_SingleCelled'")); auto psAsset = ConstructorHelpers::FObjectFinderOptional<UParticleSystem>(TEXT("ParticleSystem'/Game/ParticleSystems/PS_CompoundCloud.PS_CompoundCloud'")); if (psAsset.Succeeded()) { particleSystemType = psAsset.Get(); particleSystem->SetTemplate(particleSystemType); } else { Logging::Log("Could not find Asset 'PS_CompoundCloud_SingleCelled' at path in Compound_ParticleComponent_Cell"); } //particleSystem->Template = particleSystemType; } catch (int e) { Logging::Log("Could not find Asset 'PS_CompoundCloud_SingleCelled' at path in Compound_ParticleComponent_Cell\nCause: FObjectFinder Access Violation"); Logging::Log(e); } We had some trouble loading particleSystems this way so I left in both ways to do it and the try-catch block in case one of you might have a similar problem.

So that's basically it. Bye and keep on evolving.

Lyfe

Lyfe

 

Feature #1 - Cell Editor Base Sculpting

And so we meet once again to discuss what's new in the development of Lyfe. But as we promised on our Twitter this is something big. I don't have to tell you what we're discussing, you probably already read the title of this entry. I have to thank Jake Best who took the time draw the concept we developed for how the player will create the basic shapes for his cells. So let me explain what is going on here. You start off with just one central orb. This is your base node and your cell starts to 'grow' from it. There are arrows on four sides of this base node. If you pull on them new nodes will be created in that direction. This will create a kind of 'spine' for your cell. As shown in fig. 3 and 4 not only is the default setting when creating new nodes to the left or the right to make your cell symmetrical but you can also move your nodes/ bend the spines and the shape will be translated to the other side as well. You can also scale single nodes (fig. 5/6). This expands the cytoplasm around this node. The next thing is something we decided we needed but are not sure how to implement: a weight/thickness slider. This includes the overall amount of cytoplasm with a slight bias for filling up space between spines. Next step: placing organelles. Most organelles like Mitochondria or a Golgi Apparatus can only be placed on the inside of your cells but all organelles that are used for interaction with the outside world like Flagella or Pseudopodia have to be placed on the membrane. Organelles will have options to deform them, like elongating. Rotating them around the anchor point on the cell is also an option. Asymmetry is an option that not only affects the placement of the organelles but also the sculpting of your cell. In fig. 11 the right half of the cell is deleted resulting in this more potato shaped creation. Below are some possible results you might achieve with this toolset. For the two on the right, the dashed line represents their shape if the weight-slider was put to maximum and the one on the far left is a more experimental idea with actually two split nodes. If this will be possible in future is not sure yet, but we will see. That's it for this entry. Feel free to comment all your questions and suggestions. Keep on evolving! cellcreator.pdf

Lyfe

Lyfe

 

Update #1 - Compound Clouds and Shells

Once again we have a new entry to this devblog. First of all some logistics: We will post new updates every other week from now on because we just don't make enough breakthroughs to justify wasting your time every week. And we decided to categorize these entries. So far we got "Update" and "Feature". Updates will deal with the current state of the game while Features are more theoretical and will explain certain features we are planning on implementing or are currently implementing. So let's jump right in, shall we? The cell stage is coming along nicely. You can see the current state in this video on our ... Could that be? On our brand new YouTube channel! There are still two minor bugs with the compound clouds: #1 Vertices only move until they are in the center then stop there; Solution: Move the cloud end reorient the vertices as soon as one hits the center #2 You can basically swim through the cloud and as long as you don't get too close to any vertex it won't deform; Solution: If you are between a vertex and the center move that verteg towards the center of the mesh One feature we wan't to add that isn't in the code yet: Calculate the value of the clouds (the amound of the compound you can extract from it) based on the mesh's volume. So far it's a static value and the mesh simply disappears once it's zero. Also you don't gain any compounds from consuming the clouds yet. But that will change within the next week. During that time we will also implement the different types of clouds. So far there is no solution in sight on how we will generate the cloud representation so we can finally make the mesh invisible. This is our main hurdle at the moment.   There is now a Logging function that writes important messages into a log file, e.g. if the connection to the database failed. That's right: We now got a database connected to Lyfe. There will be a separate DevBlog on its structure once it's fully planned out. We decided on SQLite. Mostly because it does everything we need and is easy to use.   Another thing that's currently being discussed is how we should save your creations. The first idea was to use XML: <Creature name="" stage="creature"> <Backbone count="6"> <!-- starting at 0 then move in one direction and note all vertebrae then the other direction alignment in the degree varying from horizontal --> <vertebra id="0" parent="" alignment=""/> <vertebra id="1" parent="0" alignment=""/> <vertebra id="2" parent="1" alignment=""/> <vertebra id="3" parent="0" alignment=""/> <vertebra id="4" parent="3" alignment=""/> <vertebra id="5" parent="4" alignment=""/> </Backbone> <Limbs count="2"> <!-- type are the prefabs you pull into the creator x and y position on parent body mesh or something Limb set as tail/one central leg etc are symmetrical but not split --> <limb id="0" parenttype="body" type="" positionX="" positionY="" symmetry="y" split="y"/> <limb id="1" parenttype="body" type="" positionX="" positionY="" symmetry="y" split="n"/> </Limbs> <Extremities count="2"> <!-- Extremities can also be put onto the last vertebra--> <extremity id="0" parenttype="limb" parent="0" type="" scale=""/> <extremity id="1" parenttype="limb" parent="1" type="" scale=""/> <extremity id="2" parenttype="vert" parent="5" type="" scale=""/> </Extremities> <!-- ... ... ... ... ... --> </Creature> But one of the problems was finding a proper way to parse it while directly constructing your creation after each parsed node. Also XML files are gerenally constructed in scripts like C# or JS (from my experience; correct me if I'm wrong). This would create some additional steps while storing your creation so we decided against it. The next thing is a quite simple text file that looks pretty much like a config file and our programmer came up with: #CREATURE creature #BACKBONE 6 #VERTEBRA 0 -1 0 #VERTEBRA 1 0 0 #VERTEBRA 2 1 0 #VERTEBRA 3 0 0 #VERTEBRA 4 3 0 #VERTEBRA 5 4 0 #LIMBS 2 #LIMB 0 body -1 -1 -1 y y #LIMB 1 body -1 -1 -1 y n #EXTREMITIES 2 #EXTREMITY 0 limb 0 -1 1 #EXTREMITY 1 limb 1 -1 1 #EXTREMITY 2 vert 5 -1 1 As you can see the structure is preserved so all parent objects are listed before their children so the creature can be built line by line. All the stats are missing a defining name now and this is the only let down with kind of structure: it's not that easy on the eye and probably hard to understand. But it's easy to write, easy to parse and a lot smaller. The second one only is a third the size of the first one (after you remove the comments).   I guess that's it for this week. And as always we would appreciate if you shared your thoughts with us. Keep on evolving!

Lyfe

Lyfe

 

Concept Functionality - Cell Stage

We're back with another update. First a little recap of what happened this week: We got our own banner and logo. Thanks go out logomakr.com where we made it. Our website is now in develpoment. I got no idea when it will be online but we're working on it. We started using Taiga.io to manage the development. It was frustraing to just have a good a idea or realised something that needed fixing/reworking in the concept and just forget about it or have it in an unorganised text file. We got a new team member: Helices, who will function as a Biology Advisor to this project. On that note: We are reworking the cell stage to be more realistic (as far as it doesn't sabotage fun gameplay in any way). We will do another entry on that once we deem it presentable. On the actual development front: The procedural meshes now work mostly as intended. They are being generated randomly from a basic cube shape with 26 vertices. For now that should work and adding more is basically just busywork if we really need more than that. When the player collides with this mesh all vertices with a distance to the player that's within a certain threshold will  move away from the player based on a vector from the player center to the vertex. This functionality is planned out so far but not implemented. Slicing the mesh will be the next, more complicated step. Next thing I will be working on besides the website: The procedural environment. Since it would be pretty silly to just but up barriers around the map it should be infinite. To make this feasible all content has to be procedurally generated around the player. Logically it will be deleted again as soon as the player has a certain distance to it. This is true for all passive, floating objects, compound clouds and other cells. The distance should be high enough to feel natural for there to be change but also not so high that it affects the framerate. The rework on the cell stage results in there being five new compounds replacing the previous ones: CO2, Oxygen, Amino Acids, Glucose and Lipids. The will definitely be differentiated by their color and maybe by the shape of the clouds if it is deemed useful for the player and doable for a programmer. Interaction with other cells will be an interesting part. I don't want to unveil anything that will be part of the cell stage rework but I'll tell you everything we have for certain: To absorb other cells you simply have to move over them. If you have 30% more mass than they do - which is calculated via your organelles and your cytoplasm - you will absorb them and vice versa.   One thing we want to get sort of experimental with is sound. Despite the background music there will be no ingame sound effects. And even the background music will mostly consist of some atmospheric sounds. So far there was no time to prototype this but we will try to get to it soon but for now planning and coding has a higher priority.   That's it for this week's update. I'll leave you with a little insight into our code with which we generate the compound cloud mesh. void ACompoundCloud_Cell::CreateCloudMesh() { //vertex buffer //TArray<FVector> vertices; //Front vertices.Add(FVector(50.f, -50.f, -50.f));//0 vertices.Add(FVector(50.f, 0.f, -50.f)); vertices.Add(FVector(50.f, 50.f, -50.f)); vertices.Add(FVector(StaticMaths::RR(50.f, 150.f), StaticMaths::RR(-150.f,-50.f), 0.f)); vertices.Add(FVector(StaticMaths::RR(100.f, 200.f), 0.f, 0.f)); vertices.Add(FVector(StaticMaths::RR(50.f, 150.f), StaticMaths::RR(50.f, 150.f), 0.f));//5 vertices.Add(FVector(50.f, -50.f, 50.f)); vertices.Add(FVector(50.f, 0.f, 50.f)); vertices.Add(FVector(50.f, 50.f, 50.f)); //Left //2 vertices.Add(FVector(0.f, 50.f, -50.f)); vertices.Add(FVector(-50.f, 50.f, -50.f)); //10 //5 vertices.Add(FVector(0.f, StaticMaths::RR(100.f, 200.f), 0.f)); vertices.Add(FVector(StaticMaths::RR(-150.f, -50.f), StaticMaths::RR(50.f, 150.f), 0.f)); //8 vertices.Add(FVector(0.f, 50.f, 50.f)); vertices.Add(FVector(-50.f, 50.f, 50.f)); //Back //10 vertices.Add(FVector(-50.f, 0.f, -50.f)); //15 vertices.Add(FVector(-50.f, -50.f, -50.f)); //12 vertices.Add(FVector(StaticMaths::RR(-200.f, -100.f), 0.f, 0.f)); vertices.Add(FVector(StaticMaths::RR(-150.f, -50.f), StaticMaths::RR(-150.f, -50.f), 0.f)); //14 vertices.Add(FVector(-50.f, 0.f, 50.f)); vertices.Add(FVector(-50.f, -50.f, 50.f));//20 //Left //16 vertices.Add(FVector(0.f, -50.f, -50.f)); //0 //18 vertices.Add(FVector(0.f, StaticMaths::RR(-200.f, -100.f), 0.f)); //3 //20 vertices.Add(FVector(0.f, -50.f, 50.f)); //6 //Bottom //16 //15 //10 //21 vertices.Add(FVector(0.f, 0.f, -50.f)); //9 //0 //1 //2 //Top //6 //7 //8 //23 vertices.Add(FVector(0.f, 0.f, 50.f)); //25 //13 //20 //19 //14 //index buffer //+++++ Front //Lower Left indices.Add(3); indices.Add(1); indices.Add(0); indices.Add(1); indices.Add(3); indices.Add(4); //Lower Right indices.Add(4); indices.Add(2); indices.Add(1); indices.Add(2); indices.Add(4); indices.Add(5); //Upper Left indices.Add(6); indices.Add(4); indices.Add(3); indices.Add(4); indices.Add(6); indices.Add(7); //Upper Right indices.Add(7); indices.Add(5); indices.Add(4); indices.Add(5); indices.Add(7); indices.Add(8); //+++++ Right //Lower Left indices.Add(5); indices.Add(9); indices.Add(2); indices.Add(9); indices.Add(5); indices.Add(11); //Lower Right indices.Add(11); indices.Add(10); indices.Add(9); indices.Add(10); indices.Add(11); indices.Add(12); //Upper Left indices.Add(8); indices.Add(11); indices.Add(5); indices.Add(11); indices.Add(8); indices.Add(13); //Upper Right indices.Add(13); indices.Add(12); indices.Add(11); indices.Add(12); indices.Add(13); indices.Add(14); //+++++ Back //Lower Left indices.Add(12); indices.Add(15); indices.Add(10); indices.Add(15); indices.Add(12); indices.Add(17); //LowerRight indices.Add(17); indices.Add(16); indices.Add(15); indices.Add(16); indices.Add(17); indices.Add(18); //Upper Left indices.Add(14); indices.Add(17); indices.Add(12); indices.Add(17); indices.Add(14); indices.Add(19); //Upper Right indices.Add(19); indices.Add(18); indices.Add(17); indices.Add(18); indices.Add(19); indices.Add(20); //+++++ Left //Lower Left indices.Add(18); indices.Add(21); indices.Add(16); indices.Add(21); indices.Add(18); indices.Add(22); //Lower Right indices.Add(22); indices.Add(0); indices.Add(21); indices.Add(0); indices.Add(22); indices.Add(3); //Upper Left indices.Add(20); indices.Add(22); indices.Add(18); indices.Add(22); indices.Add(20); indices.Add(23); //Upper Right indices.Add(23); indices.Add(3); indices.Add(22); indices.Add(3); indices.Add(23); indices.Add(6); //+++++ Bottom //Lower Left indices.Add(21); indices.Add(15); indices.Add(16); indices.Add(15); indices.Add(21); indices.Add(24); //Lower Right indices.Add(24); indices.Add(10); indices.Add(15); indices.Add(10); indices.Add(24); indices.Add(9); //Upper Left indices.Add(0); indices.Add(24); indices.Add(21); indices.Add(24); indices.Add(0); indices.Add(1); //Upper Right indices.Add(1); indices.Add(9); indices.Add(24); indices.Add(9); indices.Add(1); indices.Add(2); //+++++ Top //Lower Left indices.Add(23); indices.Add(7); indices.Add(6); indices.Add(7); indices.Add(23); indices.Add(25); //Lower Right indices.Add(25); indices.Add(8); indices.Add(7); indices.Add(8); indices.Add(25); indices.Add(13); //Upper Left indices.Add(20); indices.Add(25); indices.Add(23); indices.Add(25); indices.Add(20); indices.Add(19); //Upper Right indices.Add(19); indices.Add(13); indices.Add(25); indices.Add(13); indices.Add(19); indices.Add(14); TArray<FVector> normals; for (int i = 0; i < vertices.Num(); i++) { normals.Add(vertices[i] / vertices[i].Size()); } TArray<FVector2D> uv0; TArray<FProcMeshTangent> tangents; ////The colors applied to every vertex and blended on the surfaces TArray<FLinearColor> vertexColors; mesh->CreateMeshSection_LinearColor(0, vertices, indices, normals, uv0, vertexColors, tangents, true); //Enable collision data mesh->ContainsPhysicsTriMeshData(true); mesh->bUseComplexAsSimpleCollision = false; mesh->SetSimulatePhysics(true); }   If you made it to this part you probably read the code and in that case: We are still looking for anyone who wants to contribute to this journy into the unknown. And please don't look at me like that, the code is functional if not beautiful. Thanks, bye.

Lyfe

Lyfe

 

Tech-Info: Procedural Mesh

This week I want to give you some technical insight into our project. I want to start with recapping what happened over the last week: The player movement for the cell stage is implemented and the GUI is wired up, too. There is now a health-bar, DNA-bar and you can see your current compounds as well as your compound balance. Currently I'm working with or rather exoerimenting with Unreal's UProceduralMeshComponent. My main goal is to create a mesh I can manipulate on runtime. The first thing I want to use it for are the compound clouds. When the player swims into them they should bend around him as if they were being absorbed while simoultaniously decreasing their value until it reaches 0 and the dissovle completly.   Once I'm familiar with how this class works I will use it for the creature editor. So far it's the best thing I know of for creating meshes that can be generated on runtime.  Currently I'm struggeling with writing an algorithm that creates a mesh that roughly outlines the shape for the compound cloud and mostly acts as a trigger and the bounds for the simulated clouds. On that point I discovered somethin you might be interested in this topic:  So far I haven't tried it but it looks exactly like the thing I need for this.   And something special: Version 1 of the Lyfe Main Theme is done. (Lyfe_Main.mp3)   That's it for this week. I want to focus on the cell stage for this devblog as long as I'm working on it. This might result in shorter entries but we want to keep you up to date.   We're also still looking for people to join the team if you're interested.   UPDATE: I managed to create an actual cube with a procedural mesh   UPDATE 2: We go some actual random shapes that will later function as the outline for the clouds.

Lyfe

Lyfe

 

The Cell Stage - Gameplay

For this weeks update I wanted to talk about something I'm currently working on (conceptually and actually in code): The Cell Stage and how its gameplay works.   Disclaimer: I'm not promising anything I'm just explaining the plan we have for Lyfe and we will work hard to get as close as we can to that vision. Secondly Some of the info you read here might not yet be in the DesignDocument but it will be updated after this post.   You start out as just a membrane with some DNA in it. Floating around one of the possible bioms. Different bioms have different spawn rates for different chemicals. We haven't yet fully worked out what chemicals will be there in detail but the basics are: Oxygon, Carbon (mostly as CO2 or simple Sugars), Hydrogen (since you are under water there is quite a lot of that so it might not necessary be a ressource), Nitrogen (as Ammonium), Phosphorus (organic Phosphorus), Sulfur. Since these are the building blocks for life. Since at the beginning you are not really a living organism yet you don't need any of it. You don't have any real means of propulsion at this point, too. You can simply wiggle around a bit and move forward this way or get carried around my the currents of whatever body of water you are currently in. At this point the game is like a low key cutscene. This changes when you meet your first other cell. It will weither be a "Proto-Mitochondrium" or Cyanobacterium. The biom you are in has influence on this. If you are somewhere deep in the ocean cyanobacteria might be more scarce since... you know... it's dark down there and photosynthesis doesn't work so well without light. As you might have guessed this unlocks the Mitochondrium or Chloroplast. (The other one can be unlocked later one as you move to other bioms over time.) Both of them can produce ATP which basically is the value of how much energy you have. The Mitochondrium uses sugar and oxygon to produce ATP while the Chloroplast uses CO2 (since Hydrogen might not be a ressource). To balance this the Chloroplast produces less ATP. As long as you have those chemicals left energy will be produced. Other organelles you unlock on your microscobic journy will consume it to give you an advantage in surviving. For example if you got a flagellum or cilia on your cell and move forward ATP will be consumed over time. The more organelles are on your cell the more is consumed. This will force you, the player, to think about what you really need to survive.   Some organelles you might unlock include: Mitochondrium -> Produces ATP Chloroplast -> Produces ATP (but less) Vacuole -> Store more compounds Cell Core -> better defense agains viruses  Cell Wall -> More health but slower Endoplasmic Reticulum -> Repairs Cell Golgi Body -> Produces Vesicel => Reduced cost for ATP production since compounds get transported faster Flagellum -> Movement Ribosome -> Produces protein => your acquire DNA faster Poison Vacuole -> Damages cells attacking you <Poison Excretion> -> Lets you excret poison to damage enemy cells Sensory Input -> Allows you to "see" Cilia -> Movement   You might now have some questions like "what's it with allowing me to see?" So basically at the beginning - and I can't stress enough how much this is just the plan we're TRYING to follow - you don't really see what's around you. You can make out your surroundings as basic shapes.  This part is basically some artsy-o vision through you see the game world. The simple reason we decided to add this is that having no eyes has a penalty in the creature stage and a consistant ruleset is an important factor in this, so it feels like one game. But we also didn't just want to make a black screen because that isn't fun. (Also we're up for suggestions on how we could solve this better.)   Then: DNA. You acquire it through absorbing other cells. The same way you can unlock new organelles. The criterium that decides if you absorb the cell or it absorbs you is how much mass you have. One simple rule that works like one browsergame proofed.   And apart from other cells viruses might also be a factor in gameplay. This is also more of a experimental-feature on which I'd like to hear your opinions. If you spot a virus you can swim away from it absorb it. If you pick the latter one of two things can happen: You gain a bonus or a malus for this "life". They are gone as soon as you die. Splitting your cell doesn't remove it. This neatly brings us to the next point: Splitting your cell and the editor. All I want to say about it in the cell gameplay is that you need a certain amount of DNA to split and open the editor. We want it to be something the player has to work for. After all Lyfe is supposed to be a game.   Now we come to the control settings which aren't that essential to this entry but I'm currently working on them so I just want to throw this in here: The player can chose from one of three settings: Follow Mouse Move To Click WASD   I think I mentioned all I need to make clear how this part of the game works except for one thing and we're still struggling with that: How will you, the player, progress through this stage. Of collect all the organelles but those just give you options to adapt to your environment but what is the overall goal you are working towards? For the other stages this was easy to decide because there are other games to look for examples. But for this part? Not even our big inspiration Spore really had something interesting in this place. It was basically pacman but with a full 360° range of motion. We want to improve on that. But as I said we don't have a 100% bullet proof idea, yet. As always we're open for suggestions.   That's it for this week from the Lyfe team and me. Thanks for reading.

Lyfe

Lyfe

 

Introduction - Organ Tree

For our first dev blog entry we decided to introduce you to the organ-tree which we already described in our design document. If you haven't read you can find it in the description of our project here.   So about that organ-tree: This is it: The tool you use during the creature stage to unlock or as it will be called ingame "evolve" your organs/skin types/body parts. Now, this is still a very rough outline but I think the intention is clear. One important design decision we made is to split it into three categories: Aquatic, Terrestrial and Both, with you starting off mostly in the aquatic branch, since your life (or lyfe if you will) as a complex creature will start off in the beautiful and mysterious depths of the ocean.   Parts from the aquatic part of the tree might be useless on land or even harm you and vice versa. For example you don't want to leave the water with gills on your creature because you will run out of oxygen very quickly. This doesn't apply to all parts, though. For aquatic hands for example it is more of a design choice (We might add gameplay functionalities later like aquatic hands help with swimming but aren't good for attacking while with some hands developed from the terrestrial branch you can claw at your rivals or prey).   You might have noticed that every set of organs has one base set and four versions deriving from it with numbers at the end. Each new version will be a new model/have a new design and slightly different stats. We are not 100% sure if we can keep the 4 stages of each organ but we will try. Because you know what they say: "Shoot for the moon. Even if you miss you will end in the vacuum of space and die alone."   What's next? The skin types. This is something where we really want to make use of the advanced technology we have compared to that from Spore almost ten years ago. Skin might not have an effect on the gameplay (yet, we're planning something for our nice-to-haves) but will make your creature look fantastic. The plan was keep it a small number of types but make them well differentiated.   Eyes: Withou eyes you won't be able to see anything, pretty straight forward, BUT: How good your eyes are determines how well you see objects at a distance/how far you can see. As a little bonus we also added a branch that grants you nightvision if you plan on making a nocturnal creature.   Finally: The brain. This is an indicator for your prograss in the creature stage. You start off with the first and most basic brain. You have to unlock all three upgrades to be able to enter the next stage which we will undoubtedly discuss at some point in this blog.

Lyfe

Lyfe

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!