Space Evolution is gamemode with procedural generation, space theme and start with nothing(Well, almost with nothing).
You have 2 humans at the start and you must find resources for feeding humans, crafting items and then flying away from earth and discovering other planets!
Steam page: https://steamcommunity.com/sharedfiles/filedetails/?id=2191619265
Humans is simple AI which have special tasks. Human with low IQ just wandering around, but humans with IQ 80+ can explore the planet. Or you can force them to explore planet by clicking on them
When human exploring the planet, he/she will search for useful resources, if he/she will find something, you'll see message in chat what was found
Amount of exists resources you can see in top-right corner on your screen, you need these resources for crafting, and some of them(Food) for humans. Each planet have different amount of resources
Planets generates absolutely randomly, using perlin's noise and simple random functions. You can find over 3,000 planets, while playing this gamemode, some planets can be dry or flooded.
You can modificate that gamemode as you want, you can change generation, behaivor of humans and so on
Everything is client side
NOTE: in some functions/hooks/globals can be used same things but with different names:
- Pixel/Block
- World/Planet
GM:SpaceEvo_GenerationFailed(PlanetName, Name, OnlyGenerate)
Calls only for earth when generation is failed(Not enough resources was generated)
- PlanetName(string): Name of folder of planet. Example: "earth"
- Name(string): Name of planet. Example: "Earth"
- OnlyGenerate(bool): Means that planet will be only generated, without visiting that planet
GM:SpaceEvo_PlanetStartLoading(PlanetName, Name, OnlyGenerate)
Calls when planet starts loading
- PlanetName(string): Name of folder of planet. Example: "earth"
- Name(string): Name of planet. Example: "Earth"
- OnlyGenerate(bool): Means that planet will be only generated, without visiting that planet
GM:SpaceEvo_NewPlanetGenerating(PlanetName, Name, OnlyGenerate)
Calls when new planet starting generation
- PlanetName(string): Name of folder of planet. Example: "earth"
- Name(string): Name of planet. Example: "Earth"
- OnlyGenerate(bool): Means that planet will be only generated, without visiting that planet
GM:SpaceEvo_CustomSeed(seed, resourceseed)
Calls when new planet going to generate seed. Return true in that hook to override default seed generation
- seed(table): Seed of planet(Surface)
- resourceseed(table): Seed of resources(Under ground)
Example:
-- Same as default seed generation
hook.Add("SpaceEvo_CustomSeed", "TestSeed", function(Seed, ResourceSeed)
for i=0, 255 do
local num = math.random(255)
while table.HasValue(Seed, num) do
num = math.random(255)
end
Seed[#Seed+1] = math.random(255)
end
for i=0, 255 do
local num = math.random(255)
while table.HasValue(ResourceSeed, num) do
num = math.random(255)
end
ResourceSeed[#ResourceSeed+1] = math.random(255)
end
return true
end)
GM:SpaceEvo_OnSeedGenerated(PlanetName, SeedTbl)
Called after seed generated and written in the planet's file
- PlanetName(string): Name of folder of planet. Example: "earth"
- SeedTbl(table): Table of 2 seeds, SeedTbl.WorldSeed - Seed of surface, SeedTbl.ResourceSeed - Seed of resources(under ground)
GM:SpaceEvo_PreLoadPlanetSeed(PlanetName, seed)
Calls before seed was loaded
- PlanetName(string): Name of folder of planet. Example: "earth"
- seed(table): Table of 2 seeds, SeedTbl.WorldSeed - Seed of surface, SeedTbl.ResourceSeed - Seed of resources(under ground) Return in that hook seed to override planet's seed. It wouldn't re-write file of planet's seed
GM:SpaceEvo_PostLoadPlanetSeed(PlanetName, seed)
Called after planet's seed was loaded
- PlanetName(string): Name of folder of planet. Example: "earth"
- SeedTbl(table): Table of 2 seeds, SeedTbl.WorldSeed - Seed of surface, SeedTbl.ResourceSeed - Seed of resources(under ground)
GM:SpaceEvo_OnPlanetGenerated(PlanetName, PlanetTable, seed)
Calls when new planet was generated. It will be called when earth first generated too
- PlanetName(string): Name of folder of planet. Example: "earth"
- PlanetTable(Planet): Table of new planet. You can find its structure in "Structures" section
- seed(table): Table of 2 seeds, SeedTbl.WorldSeed - Seed of surface, SeedTbl.ResourceSeed - Seed of resources(under ground)
GM:SpaceEvo_GenerateTerrain(BlockHeight, Neighbors, PlanetName)
That hook calls when terrain is generating. It calls each time you loading(visiting) planet With that hook you can override default terrain generation, for example making somewhere winter, stone, mud or whatever. See example
- BlockHeight(float): Height of current block/pixel. You can see height of blocks alredy in game, or google more about Perlin noise
- Neighbors(table): Neighbors of block. You can find its structure in "Structures" section"
- PlanetName(string): Name of folder of planet. Example: "earth"
Example:
-- in that hook you must return name of block and its color
hook.Add("SpaceEvo_GenerateTerrain", "CustomGeneration", function(height, neighbors)
if height >= 0.5 and height <= SpaceEvo.MountainHeight then
return "Stone", Color(255*height,255*height,255*height)
end
end)
GM:SpaceEvo_GenerateResources(BlockHeight, BlockSurface, Neighbors, PlanetName)
Same as hook above, but allows you to override default resource generation. You can add your own resources or just make default generation better. Return same values as in hook above to override generation. You can check your resource generation using sv_cheats 1
- BlockHeight(float): Height of current block/pixel. You can see height of blocks alredy in game, or google more about Perlin noise
- BlockSurface(Block): That table contains information of block on surface. You can find its structure in "Structures" section
- Neighbors(table): Neighbors of block. You can find its structure in "Structures" section"
- PlanetName(string): Name of folder of planet. Example: "earth"
GM:SpaceEvo_PlanetFinishedGeneration(PlanetName)
Calls after all hooks above and when planet was successfully generated(No errors)
- PlanetName(string): Name of folder of planet. Example: "earth"
SpaceEvo.Humans:AddMenuButton(funcAdd)
Allows you to add your custom button in popup menu, when you're clicking on human
- funcAdd(function): Function which called each time you're pressing on human. function(Menu, Human, HumanID)
- Menu(Panel): DermaMenu
- Human(Human): Table of human. You can find its structure in "Structures" section
- HumanID(int): ID of human in humans table
Example:
SpaceEvo.Humans:AddMenuButton(function(m, hum, humid)
m:AddOption( "Suicide", function()
SpaceEvo.Humans:Kill(humid, false, {color_white, " just suicided!"})
end)
end)
SpaceEvo.Humans:AddFirstName(gender, name)
Adds possible first names to table of first names. Same as table.insert(SpaceEvo.Humans.FirstName[gender], name)
- gender(string): For which gender will be used that name. You can type here "Female" or "Male".
- name(string): Name which you want to add
SpaceEvo.Humans:AddLastName(lastname)
Adds possible last names to table of first names. Same as table.insert(SpaceEvo.Humans.LastName, lastname)
- lastname(string): Last name which you want to add
SpaceEvo.Humans:Kill(humanID, isUniqueID, reason, planet)
Allows you to kill a human
- humanID(int): ID of human, it can be uniqueID of human(which can be get by Human.uniqueID, see structure of human's table) or human's ID from table of all humans
- isUniqueID(bool): If you used uniqueID of human, then place here true. Else false
- reason(table)[optional]: If you want to put message in chatbox, that this human was killed, add that table. Table values should be as arguments for chat.AddText - https://wiki.facepunch.com/gmod/chat.AddText
- planet(string)[optional]: If you want to kill human from another planet, use that argument. You must use human's uniqueID to kill him/her on another planet
SpaceEvo.Humans:Create(FirstName, LastName, Gender, planet, pos, parrents)
Allows you to create human on any planet That function returns created human
- FirstName(string)
- LastName(string)
- Gender(string): "Male" or "Female
- planet(string): On which planet create this human
- pos(table)[optional]: If you want to create human on special position, use that table. {x = whatever, y = whatever}
- parrents(table)[optional]: Allows to add parrents to that human. {Dad = uniqueID, Mom = uniqueID}
SpaceEvo.Humans:CanBeInLove(hum1, hum2)
Returns boolean, can hum1 be in love with hum2
- hum1(Human): First human
- hum2(Human): Second human
SpaceEvo.Humans:FindLove(human)
Finds and returns the partner for human
- human(Human): For who search the partner
SpaceEvo.Humans:FindInRadius(WorldPosition, Radius)
Returns table with humans which was found in that radius. Notice that here used world position, not screen position
- WorldPosition(Vector): Center of sphere where to search
- Radius(int): Radius to search. Must be squared. This function uses "DistToSqr"
SpaceEvo.Humans:GetScreenPos(human)
Returns screen position of human
- human(Human): Human whose position needed
SpaceEvo.Humans:GetPos(human)
Returns worls position of human
- human(Human): Human whose position needed
SpaceEvo.Humans:GetVelocity(human)
Returns velocity of human
- human(Human): Human whose velocity needed
SpaceEvo.Humans:FindByID(id, planet)
Returns human
- id(int): uniqueID of needed human. **That function searches
- PlanetName(string)[optional]: Name of folder of planet. Example: "earth"
GM:SpaceEvo_HumanThink(humID, hum, planet)
Calls each tick when human is thinking. Actually it is same as "hook.Add('Think', ..)" Return true to override human's behaivor
- humID(int): ID of human in their table (SpaceEvo.Planets[SpaceEvo.CurrentWorld].Humans)
- hum(Human)
- planet(string): Current planet
GM:SpaceEvo_HumanSearchingResource(hum, block)
That hook calls each time when human scans whole planet to find useful resource. This happens randomly and depends of human's IQ. Return true in that function to prevent human from finding that block If you want to remove that ability, then do also "hum.shouldFind = nil" in that hook, to prevent human's stuck
- hum(Human): Human who trying to find something useful
- block(Block): Block which he checking
GM:SpaceEvo_OnResourceFound(hum, block)
That hook calls once when human was found something usefult and going to build special object for that resource
- hum(Human): Human who found resource
- block(Block): Block which contains resource
GM:SpaceEvo_OnNewPlanetFound(hum, PlanetTable)
That hook calls when human found new planet using the telescope
- hum(Human): Human who found the planet
- PlanetTable(Planet): Planet which was found
GM:SpaceEvo_HumanLeftToAnotherPlanet(hum, newPlanet)
Calls when human flying away to the another planet, using the rocket
- hum(Human): Human who fly away
- newPlanet(Planet): The planet he went to
GM:SpaceEvo_CantBeInLove(hum1, hum2)
That hook allows you to skip human which could be a partner for hum1. You are cruel if you do that
- hum1(Human): Human who searching partner
- hum2(Human): Human who could be a partner
GM:SpaceEvo_FoundLove(hum1, hum2)
Calls after hum1 found his/her love
- hum1(Human): Human who was searching for love
- hum2(Human): Human who was found by hum1
GM:SpaceEvo_PreHumanCreate(FirstName, LastName, Gender, planet, pos, parrents)
That hook calls in function SpaceEvo.Humans:Create before all code and contains arguments which was used in that function
- FirstName(string)
- LastName(string)
- Gender(string)
- planet(string): On which planet human will be created These arguments can be nil
- pos(table): Position where to create human. {x = whatever, y = whatever}
- parrents(table): Parrents of that human. {Dad = uniqueID, Mom = uniqueID}
GM:SpaceEvo_PostHumanCreate(human)
Called after human was created
- human(Human): Human who was created
GM:SpaceEvo_OnHumanKilled(human, planet)
Called when human was killed by calling SpaceEvo.Humans:Kill function
- human(Human): Human who was killed
- planet(string): Planet on which human was killed
Next 2 functions need additional description. When new planet generating, it takes random name from 2 tables: SpaceEvo.RandomPlanets1 and SpaceEvo.RandomPlanets2. Basicly, it does that:
select(1, table.Random(SpaceEvo.RandomPlanets1))..select(1, table.Random(SpaceEvo.RandomPlanets2))
It allows to create more unique planets with unique names.
SpaceEvo.Planets:AddFirstName(name)
Allows you to add more possible names for planets. It will also increase amount of possible generated planets
- name(string): First part of planet's name
SpaceEvo.Planets:AddLastName(name)
Allows you to add more possible names for planets. It will also increase amount of possible generated planets
- name(string): Last(Second) part of planet's name
SpaceEvo.Planets:GenerateNewPlanet()
That function generates new random planet without loading(visiting) it. Game freezes when generating new planet Returns:
- PlanetTable(Planet): Table of new planet
SpaceEvo.Planets:SavePlanet(planet)
That function allows you to save any planet which is generated
- planet(string): PlanetName (must be lower case)
SpaceEvo:GenerateWorld(planet, name, dontopen)
That function allows you to generate planet with special name
- planet(string): PlanetName
- name(string): Planet's name (Usually it's same as planet, just starts with a capital letter)
- dontopen(bool)[optional]: If true then this planet will be only generated, without visiting it
GM:SpaceEvo_PreSavePlanet(planet)
Calls before saving the planet.
- planet(Planet): Table of planet to save
GM:SpaceEvo_PostSavePlanet(planet)
Calls after planet saved.
- planet(Planet): Table of planet which was saved
Objects are used for resource extraction or special actions (Like telescope, house or rocket)
SpaceEvo.Objects:AddNew(index, tbl)
That function allows you to add new object. If human will find resource which name == index, human will create that object on resource's position
- index(string): Index for object. Must be unique
- tbl(table): Table of new object. Find structure of objects in "Structures" section
SpaceEvo.Objects:GetPos(obj)
Returns world position of the object
- obj(Object): Needed object
SpaceEvo.Objects:GetScreenPos(obj)
Returns screen position of the object
- obj(Object): Needed object
SpaceEvo.Items:AddCraftableItem(itemTbl)
Adds item to the Craft menu
- itemTbl(table): Table of item.
{
Name = "Telescope", -- Should be save as index in "SpaceEvo.Objects:AddNew" function
Img = Material("space_evolution/telescope.png"), -- image which will be drawn
Desc = "Allows you to search planets", -- description
Need = { -- What player need to craft that item
Wood = 50,
Food = 0,
Iron = 25,
Oil = 0
}
},
GM:SpaceEvo_OnItemCrafted(item)
Calls when player crafts item in Craft menu
- item(Object's adding table): Item which was crafted
SpaceEvo.Objects:Create(objName, objBlockPos)
That function allows you to create any object which exists by default or was added by "SpaceEvo.Objects:AddNew" function
- objName(string): Object to create. Example: "Telescope"
- objBlockPos(table): Position of block where should be placed object
SpaceEvo.Objects:Get(id, planet)
Allows you to get object by using their ID, without using global table
- id(int): ID of object in global table
- planet(string)[optional]: Where to search
GM:SpaceEvo_OnObjectCreated(objID, objName, objBlockPos)
Called when object was created by function above
- objID(int): ID of object in their table (SpaceEvo.Planets[planet].Objects)
- objName(string): Name of object
- objBlockPos(table): Position of block where it was placed
GM:SpaceEvo_PreFramePaint(panel, width, height)
Calls before main frame was painted
GM:SpaceEvo_BlockPaint(index, block, mousex, mousey, freeSpace)
Calls when mouse over block and drawing block info
- index(int): Index of block in their global table
- block(Block): Block's table
- mousex(float): x position of mouse
- mousey(float): y position of mouse with offset
- freeSpace(float): Y Coordinate where you can place something yours
GM:SpaceEvo_PostFramePaint(panel, w, h, rightY, leftY)
Calls after main frame was painted
- panel(Panel): Main frame
- w(int): Width
- h(int): Height
- rightY(int): Y Coordinate where you have free space to place something yours under the "Resources:" text
- leftY(int): Same as above but at left, under "Planet:" text
GM:SpaceEvo_OnHumanSelected(human)
Calls when player click on human and then on ground
GM:SpaceEvo_PreSaveRemove()
Calls before all saves being removed
GM:SpaceEvo_PostSaveRemove()
Calls after all saves was removed
GM:SpaceEvo_OnMainFrameCreated(frame)
Calls after SpaceEvo.MainFrame was created and loaded
SpaceEvo.Circle(x, y, radius, segments, color)
Function for drawing filled circle
SpaceEvo:Frame(Parrent[optional])
Function for creating DFrame in gamemode's style
SpaceEvo:Button(text, parrent)
Function for creating DButton in gamemode's style
- text(string): Text which should be drawn on button NOTE: Button works a bit different than usual DButton:
local btn = SpaceEvo:Button("Sample text")
btn.Click = function(self)
btn.Text = "Instead of 'DoClick' you must use 'Click' funciton, and instead of 'SetText' - '.Text = '"
end
```lua
SpaceEvo:NearestPixel(pos)
That function used to get nearest block(Pixel) to position. You must use world coordinates in that function
- Pos(Vector)
SpaceEvo:ShadowText(text, font, x, y, color, alignx, aligny)
That function works same as draw.SimpleText but adds simple shadow
WIP
SpaceEvo.Particle(pData)
Creates 2D particles on the screen
Example:
-- that is how water particles was done
local velX, velY = SpaceEvo.Humans:GetVelocity(v)
SpaceEvo.Particle({
x = p.x,
y = p.y+10,
Spread = .1,
Dir = {x = velX, y = velY},//
Mat = nil,
Time = .25,
StartSize = 5,
EndSize = 3,
ColorStart = Color(100,155,255,100),
ColorEnd = Color(180,200,255,0),
Rotate = math.Rand(-.1, .1),
Amount = 1
})
SpaceEvo.Humans.MaxIQ = 200 -- Maximum IQ which human can reach
SpaceEvo.Humans.FirstName - Table of first names for humans
SpaceEvo.Humans.LastName - Table of last names for humans
SpaceEvo.Humans.ExtraButtons - Table which contains custom buttons, which was created with "SpaceEvo.Humans:AddMenuButton" function
SpaceEvo.Planets -- All generated planets
SpaceEvo.Planets[planet].Humans -- Table of all humans on the planet
SpaceEvo.Planets[planet].Objects -- Table of all object on the planet
SpaceEvo.CurrentWorld -- Current planet. DON'T CHANGE IT WITH CODE
SpaceEvo.Items.Storage -- Items which you can find in Craft menu. {[ItemName] = ItemAmount}
SpaceEvo.MainFrame -- Main DFrame of gamemode
SpaceEvo.CursorPos -- Position of cursor
SpaceEvo.Removing -- true if all saves removing right now
SpaceEvo.CamPos -- Position of camera
SpaceEvo.WorldPos -- Position of the world(planet)
SpaceEvo.GeneratedWorld -- Table of generated world(planet)
-- That table contains 5 keys:
SpaceEvo.GeneratedWorld.World -- The whole table of generated blocks, but I'm not recommend to use it
SpaceEvo.GeneratedWorld.WorldResources -- Same as above but for resources
SpaceEvo.GeneratedWorld.WorldMesh -- Use that, it's processed and simple table of world's (planet's) blocks
SpaceEvo.GeneratedWorld.WorldResourcesMesh -- Use that for resources, it's processed and simple table of world's (planet's) resources
SpaceEvo.GeneratedWorld.WorldName -- Same as SpaceEvo.CurrentWorld
Pos = Position of the block in the world coordinates
Col = Color of the block
Type = Type of the block(Hills, Sand, Water, ..)
Height = Height of the block
Resource = Table of not-processed resource, which located under that block (Resource from SpaceEvo.GeneratedWorld.WorldResources)
In block of resource only one different: Instead of "Resource" it has "World"*
Name = Name of the planet
Hills = Color of the hills
Water = Color of the water
Sand = Color of the sand
WaterAmount = Height of water. It's using in terrain generation: Height <=.1 and Height >= WaterAmount and "Sand" or "Water"
Humans = Table of all humans on that planet
Objects = Table of all objects on that planet
Seed_Random = Table of 2 values for generating seed of surface. {min = 0, max = 255}. It will do math.random(Seed_Random.min, Seed_Random.max)
SeedResource_Random = Table of 2 values for generating seed of resources. {min = 0, max = 255}. It will do math.random(SeedResource_Random.min, SeedResource_Random.max)
Resources = Table of resources on that planet:
Resources.Iron = Amount of iron
Resources.Oil = Amount of oil
Resources.Wood = Amount of wood
Resources.Food = Amount of food
FirstName = First name of human
LastName = Last name of human
Sex = Sex of human
Job = job of human(unused)
InLove = uniqueID of human he's in love
uniqueID = Unique ID of human
IQ = IQ
Pos = Position of human. Use SpaceEvo.Humans:GetPos(human) or SpaceEvo.Humans:GetScreenPos(human) to get calculated position
Parrents = Table of parrents with unique ids:
Dad = uniqueID
Mom = UniqueID
Model = Table of color for human's body
Body = Color of his skin
Shirt = Color of his shirt
Pants = Color of his pants
Hairs = Color of his hairs
x = x position of the block
y = y position of the block
color = color of the block
v = height of the block
slf = self-index of the block
typ = type of the block
neighbors = neighbors of the block
Simple table with simple values:
left = left block
right = right block
top = top block
bottom = bottom block
All these values ARE INTs, to get actual not-processed block use:
SpaceEvo.GeneratedWorld.World[Block.neighbors.top]
to get processed block use:
SpaceEvo.GeneratedWorld.WorldMesh[Block.neighbors.top]
Name = Name of the object
Paint = Paint function(x Position X, y Position Y, mx Mouse Position X, my Mouse Position Y) for the object
IsMouseOver = function(x Position X, y Position Y, mx Mouse Position X, my Mouse Position Y), return true if mouse is over
Think = function(self), Think function of object
Click = function(self), calls when the player just clicks on an object
Usable = bool, if usable, then when you're selecting human and then your object, you'll be able to press "Use Object" in popup menu
CanUse = function(self, human), Function which checks, can human use object
BuildValue = float/int, How much will be added to its BuildProgress each tick
BuildMaxValue = Max value to build it
NeededIQ = Unused
Name = Name of the object
Pos = position of the object. Use SpaceEvo.Objects:GetPos(obj) or SpaceEvo.Objects:GetScreenPos(obj) to get needed positions
BuildState = BuildState of object, not used much
CurrentTask = Unused
There is only one font: "SpaceEvo_Pixel", which size goes from 3 to 50 So, SpaceEvo_Pixel3, SpaceEvo_Pixel4, SpaceEvo_Pixel5, SpaceEvo_Pixel10, SpaceEvo_Pixel23, etc.