Eufloria > Eufloria Classic Mods

Annikk's Mechanics

(1/18) > >>

annikk.exe:


A series of guides intended to help you install all the different engines into your level.

Free to use, copy and modify.



~


Contents


* Read this first
* Infected AI
* Gravity/Collisions
* Parallax Scrolling
Thanks to CybeRogue for the banner.

annikk.exe:
Read this first.

Hello.



I wrote all of the engines in this thread.  This series of guides assumes some very basic knowledge of map-making - I expect for example that you are aware how to make a While GameRunning() do loop, that you are comfortable with creating your own Asteroids in LevelSetup(), etc.  If you are a newcomer to level design please read the Beginner's Guide first and try all the examples there.  That combined with a couple hours of experimentation will bring you up to speed sufficiently to have a go at using some engines.

Attached to each guide you will find three files:

* The first file is not a level - it's actually just the complete code for the engine, which you just copy and paste to the bottom of your level file, below absolutely everything else.
* The second file is a simple playable map, the way I imagine your maps might look before you have any engines in them.  Think of it as a "before"...
* The third file is the "after" version.  This is the exact same map but with the engine in question added.  This is so that you can compare the two to see the differences.
I have furnished each template with some default values, so installing the engine in your level is little more than a simple copy and paste affair, and the level will then load fine and you'll be able to see it doing something, at least.

However, only the Infected AI is intended to be used "as is".  The other engines all have variables that can and should be tweaked in order to get the particular functionality you are looking for.
It would be disappointing and extremely cheesy to see finished maps being released with these default values, especially when I have taken the trouble to explain the comparitively simple ins and outs of modifying them to your own design.
Therefore, if you use any of my engines other than the Infected AI, please ensure you alter the variables in such a way that it looks sufficiently different from the defaults.

I can't force you to do this.  The code is up here, freely available for all, and ultimately you can do what you want with it and there's nothing I or anyone can do to stop you.  However I wanted to make my personal wishes clear in the hope that they will be respected because - from my own experimentation - I know how much is actually possible with the code contained herein, and it would be a tragic waste if that potential was not exploited by the map-making community.

Furthermore, to my mind, tweaking variables is what is so much fun about these engines.  I encourage you to let your imagination go wild, and if you have any questions regarding any aspect of the engines or a query on how to implement a particular behaviour, please ask about it in this thread and I will do my best to respond.

Happy coding. :>


-Annikk.

annikk.exe:


Difficulty: Easy
CPU Cost: Medium; intermittent bursts.


1.  Description


* The Infected AI Engine is a scripted alternative to the normal, ingame AI.  It is designed as an "aggressive expansionist" and will use its seedlings very efficiently.
It is designed to:
i) target poorly defended asteroids when attacking
ii) use large swarms effectively by splitting its attacks across multiple different points
iii) not become traumatised by extensive damage to its empire
iv) cope with having its empire split up into parts that cannot reach one another.

If the AI's empire is reduced to a single asteroid, it will still (if subsequently left unchecked) come back to ultimately take over the entire galaxy and win.


* The Infected AI engine is the easiest of all the engines to implement, because it doesn't require you to change any variables.  It will just automatically learn about your level and take control of the seedlings/trees/etc that you've added for Empires 2 and up.


* The AI is equally at home on a static map as it is on a map with moving asteroids or maps where the numbers of asteroids in play changes over time.


* It will automatically take control of any seedlings or asteroids that you assign to Empires 2 and up, and will cause them to efficiently colonise the galaxy around them, defending themselves if attacked, before ultimately aggressively attacking the player and each other.


* You only need one copy of the engine to run as many different AI empires as you like.


* The AI will not control Greys (Empire 0).  So you can still use greys as a passive buffer force to guard valuable asteroids.  The AI will generally avoid trying to colonise these asteroids unless it has a sufficient force to kill them all.


* The AI knows how to use flowers to get Super Seedlings, but it doesn't know how to plant them on Defence Trees to make laser mines.  Perhaps a future update will introduce this functionality.  However, the AI does respond vigourously if the player attacks with a laser mine,  so feel free to allow the player to build mines in your level, should you deem it appropriate.


* Finally, for the avoidance of any doubt, commands like "GetAI(2).Cowardice = 0.05" and "GetAI(2).MinExpansionForce = 10" do not affect the Infected AI in any way - so remove them if you don't want the extra clutter.  Those commands are for the default in-game AI, which the Infected AI automatically switches off for you when the engine initialises.


2.  Implementation


* 1.  Download the file attached to this post called "Infected AI Engine.lua".
* 2.  Open the file in notepad or whatever text editor you use.
* 3.  Select all of the code and copy it to your clipboard.
* 4.  Open your own level and scroll down to the very bottom, and paste the code in.  It is imperative that it appears below everything else - including the "end" from your function LevelLogic().  The code you are pasting is two entirely seperate functions so if you inadvertantly put it inside function LevelLogic() then the map won't work.
* 5.  At the bottom of your function LevelSetup(), insert this command: AIinit()
* 6.  In your function LevelLogic(), ensure you have a While GameRunning() do loop (or create one if you don't), then insert the following command anywhere in the loop: InfectedAIEngine()
Now the engine is implemented.  Save your level and try to play it.


That's all that is required to implement Infected AI.
The process for the other engines is exactly the same - the only thing that differs is the name of the functions.



3.  Variables

There are no variables to change in Infected AI.  Once you have completed the above steps, the AI will be in the level.  It will take control of any asteroids and seedlings that you create for Empires 2 and up.

annikk.exe:


Difficulty: Medium
CPU Cost: Low/medium - dependent on number of asteroids


1.  Description


* The Gravity/Collision Engine allows you to designate certain asteroids (or all asteroids) as having gravitational properties.  It gives asteroids the ability to move around, bump into each other, and orbit each other in a realistic way.  The fact that it is based on real life physics (loosely - antigravity doesn't really exist as far as I know) makes it all the more interesting to play around with - and some surprising behaviours fall out of the equations naturally...


* You can use this engine to make asteroids orbit each other in complex patterns.  You can make asteroids incredibly bouncy, or so non-bouncy that they stick together the moment they collide.  You can make asteroids that behave like balloons.  You can create asteroids that have antigravity.  There is a LOT you can do with this - it's extremely fun to sit around tweaking the settings to produce unlikely looking trajectories, and experiment with strange anomalies such as black holes.


* The engine is quite forgiving for mistakes.  If you forget to specify variables for some of your asteroids, the level will still load - but those asteroids will not move or have any gravity.  Other asteroids will still be able to bounce off them, however.


2.  Implementation


* 1.  Download the file attached to this post called "Gravity Engine.lua".
* 2.  Open the file in notepad or whatever text editor you use.
* 3.  Select all of the code and copy it to your clipboard.
* 4.  Open your own level and scroll down to the very bottom, and paste the code in.  It is imperative that it appears below everything else - including the "end" from your function LevelLogic().  The code you are pasting is two entirely seperate functions so if you inadvertantly put it inside function LevelLogic() then the map won't work.
* 5.  At the bottom of your function LevelSetup(), insert this command: GravityInit()
* 6.  In your function LevelLogic(), ensure you have a While GameRunning() do loop (or create one if you don't), then insert the following command anywhere in the loop: GravityEngine()
Now the engine is implemented, but you will need to set some variables before it will do what you want it to do.



3.  Variables

In this engine there are several "global" variables which you only need to set once for the whole engine, and a handful of variables that you need to specify on a per-asteroid basis.
You can find the variables inside the "function GravityInit()" section in the code that you pasted in.  The variables are all initialised here, so this is where you change all the settings.


Global Variables


* G - the overall force of gravity.  I'd suggest setting this to 1 to begin with.
* bounce - how bouncy are asteroids?  A perfectly elastic collision (ie the most bouncy any real life object could possibly be) is 1.  I'd suggest trying 1.1 or 1.2 personally.  :>  It stops asteroids from clumping up together.
* EmergencyBrakeThreshold, MidBrakeThreshold, LowBrakeThreshold - These are for slowing down asteroids that are moving too fast.  Set it to the speed an asteroid must be travelling to incur a slowing-down effect.
* EmergencyBrakeFactor, MidBrakeFactor, LowBrakeFactor - When one of the above thresholds is reached, this is the value that the speed is multiplied by.  Setting a value of less than about 0.98 causes the asteroid to slow down like a balloon does in air.
The brakes aren't exactly very true to astrophysics, but it lets you simulate (somewhat crudely) things like the response to an atmosphere such as if you try to throw a balloon.  The balloon slows down very rapidly and doesn't go very far.

Brakes are necessary if you use a bounce factor greater than 1, because that will mean each collision adds energy to the system.  Without brakes, the asteroids will collide and collide, picking up more and more speed, until eventually they fly all over the screen at lightning speed colliding with each other dozens of times a second, and vanish.
This is certainly interesting but hardly makes for a productive level-making environment.  Hence, the brakes.


Per-Asteroid Variables

Just copy and paste these ready-made template examples for each asteroid you need to declare for.


--- Code: --- -- Asteroid 1
-- This asteroid has gravity and moves around.  It is drifting northwest at game start.
roid = 1
hasgravity[roid] = true
canmove[roid] = true
MomentumX[roid] = -13.1
MomentumY[roid] = -9
density[roid] = 0.3
--- End code ---


If you forget to set these attributes for one of your asteroids, some default settings will be used for it instead (the asteroid won't move and won't have gravity).



* roid - Enter the ID of the asteroid you are setting properties for.
* hasgravity - True or False.  If you set to true, the asteroid will contribute forces to the gravitational field around it.  If you set false, it won't produce any gravity or feel any gravity from others.
* canmove - True or False.  Can the asteroid be moved (by gravity and from being struck by other asteroids), or is it static and unmoving?  Using different combinations of "hasgravity" and "canmove" is the one of the main methods of producing different asteroid behaviours.
* density - how dense is the asteroid?  Asteroids with greater density have more gravity.  An asteroid made of metal (which has very high density, eg 10) would produce more gravity, and also take more force to get it moving, than an asteroid made of gas (which would have a density of about 0.1).
* MomentumX and MometumY - This is the starting speed/direction for this asteroid.  For example, if you set the X to -3 and the Y to 0, the asteroid will start the game drifting gently west.

You can also change the properties of individual asteroids ingame whilst the simulation is in progress.  To do this, simply open the console and declare a new value for the variable in question.
For example, if I wanted to set the density of Asteroid 1 to 500 instead of 0.3, this is the command I would type into the console:


--- Code: ---density[1] = 500
--- End code ---

Asteroid 1 would then instantly have a gravitational field more than 1500 times stronger than before, and the asteroids would all behave differently as a result of the change.
This looks hilarious, by the way.  It's like someone just pulled a giant plug in space, and everything starts rushing towards it...

annikk.exe:


Difficulty: Advanced
CPU Cost: High - dependent on number of asteroids and stars


1.  Description


* The Parallax Scrolling Engine lets you create stars that float behind the asteroids in your level, giving a faux-3D effect.


* This engine is the most difficult to understand and configure.  However, in its default form it is cut back a great deal.  You should be able to massively increase the number of stars that are displayed with some tweaking, especially if this is the only engine you are using in your level.


* This version is designed to display stars, but you can also use it to display other things.  Lots of different visual effects are possible.  The engine is set up to use Sprite Index 0 which in my view is the most star-like, however you can also set it to display other sprite indexes.  Possibly with some interesting results.


2.  Implementation


* 1.  Download the file attached to this post called "Parallax Engine.lua".
* 2.  Open the file in notepad or whatever text editor you use.
* 3.  Select all of the code and copy it to your clipboard.
* 4.  Open your own level and scroll down to the very bottom, and paste the code in.  It is imperative that it appears below everything else - including the "end" from your function LevelLogic().  The code you are pasting is two entirely seperate functions so if you inadvertantly put it inside function LevelLogic() then the map won't work.
* 5.  At the bottom of your function LevelSetup(), insert this command: ParallaxInit()
* 6.  Insert a LevelDraw function in between your LevelSetup() and your LevelLogic() using this command: function LevelDraw()
* 7.  Ensure that you place an "end" after it, to indicate where the code in that function stops.
* 8.  Inside your LevelDraw, insert this command: ParallaxEngine()
Now the engine is implemented, and will work immedietely.  However, be sure to change the variables to your own design before releasing it.



3.  Variables

The Parallax Engine has a large number of variables.  Some of the variables are arrays, so you will need to set values for all of the arrays too.  Because some of the arrays can span hundreds of slots, you may wish to combine formulas and For loops in order to set all the values efficiently, without having to manually specify each one.

This engine is not nice and friendly like gravity.  If you forget to set one of the values, the level will probably not load.

The settings for the Parallax Engine all appear in the ParallaxInit() function that you pasted in.
The section marked "User-Changeable Variables" roughly marks out the bounds of which variables are designed to be modified easily.


Single Variables


These are just single values that you can specify to govern global properties of the engine.


* numberofstars - The total number of stars in your level.  Be careful with setting this too high - stars require a lot of processing power, especially if you have a lot of asteroids in your level.
* numberoflayers - How many Parallax layers are there?  The stars will be split equally among the layers, so if you have 50 stars and 10 layers, there will be 5 stars in each layer.  You can set some attributes per-star, and other attributes per-layer.
* widthofstarfield, heightofstarfield - How large an area shall the starfield occupy?  Change this to be optimum for your size of map.  The engine always centres the starfield at coordinates 0,0.
* starsize - How big should each star be?  200 is good for average sized stars.  Setting this value very high creates some interesting effects, but the higher the value, the greater the CPU cost.
* stoprenderingbelow - When you zoom out, the engine will start to reduce the alpha of certain layers (exactly which layers is definable in the arrays section below).  When the alpha falls below a certain point, the engine will just stop rendering them completely, saving CPU.  Set that threshold here.  Allowed values 0-1.

Setup Arrays

This is where you specify the attributes for individual stars and layers.
All these arrays are required by the engine and their values must be specified by you.

Red, Green, Blue - How much of each colour in the star?  0,0,0 is black.  1,1,1 is white.

For example, if you have 3 stars:


--- Code: --- red[0] = 1
green[0] = 0.2
blue[0] = 0.2

red[1] = 0.2
green[1] = 0.2
blue[1] = 1

red[2] = 1
green[2] = 1
blue[2] = 1
--- End code ---
   
This code would make the first star red, the second star blue, and the third star white.
The number in square brackets refers to the individual star we are colouring.

If you have hundreds or thousands of stars, this method is not a good approach.  Instead, set the values with a formula.  For example, this formula would colour the stars different shades of grey:


--- Code: ---for setcol = 0,numberofstars do
red[setcol] = math.sqrt(1 / numberofstars)
green[setcol] = math.sqrt(1 / numberofstars)
blue[setcol] = math.sqrt(1 / numberofstars)
end
--- End code ---
   
How to make the right formula?
Well, first think of what sort of values you are going to need.  I know that for grey stars I need the values for red, green and blue to be the same for each star.  So the formula should be the same for each of them (which isn't always the case - it depends entirely on the effect you're trying to achieve).
Next, I know that the values should vary between 0 and 1.  I also know that the one thing that I can rely on changing between one star and another, is its ID number.  So we can use that as the seed of difference for our formula.
"setcol" is going to vary between 1 and however many stars we have.  Say it was 50.  What could we do with the number 50 to get a value between 0 and 1?
One answer is to divide 1 by that 50, and use the result.  But that's only 0.02 - if we have 100 stars then it means most of them will basically be black.
We need to find a way to increase the result we get, without making it stray above 1.
An ideal way to do this is to take the square root.  The square root of 0.02 for the 50th star would be around 0.14, so its r, g and b values would be at 14%.  That's a dark grey, but not black.  The 10th star would be the square root of 0.1, which is about 32% - a gunmetal grey.  So it looks like this formula would work well for creating stars with different shades of grey.

It's up to you to develop your own methods for setting the colours of these arrays.  Lets move onto the next array.



threshold - How zoomed out do we have to be before each layer starts to fade out/disappear?

This is useful for keeping lots of detail when zoomed in, but only displaying a certain amount of stars when zoomed out so that the FPS doesn't suffer.
You need to specify a value for each layer.  Unlike stars, the numbering of layers always starts on 1, NOT 0.

You can specify values manually:


--- Code: ---threshold[1] = 0.3
threshold[2] = 0.2
threshold[3] = 0.1
threshold[4] = 0.07
threshold[5] = 0.04
--- End code ---

Or you can do it with some formula that you invent:


--- Code: ---for setthresh = 1, numberoflayers do
threshold[setthresh] = 1 / setthresh
end
--- End code ---



zdepth - How far away does this layer look?

This should normally be a value greater than 1.  The higher the value, the closer the stars look.
If the value is equal to 1, the stars will look like they are so far away that they don't move with the camera at all.
If the value is less than 1, the stars will move backwards!
If the value is 0, the stars will not be rendered.
If the value is less than 0, the stars will seem to be in the foreground - in front of the asteroids (but they will still disappear when they actually move in front of one)

In the template, the line looks like this:


--- Code: ---zdepth[numberoflayers - lnumber + 1] = 1 + (5 * (1 / lnumber))
--- End code ---

You can replace the bit after the = and write your own formula, or you can replace that line entirely and specify the z-depths for all the layers manually:


--- Code: ---zdepth[1] = 1.1
zdepth[2] = 1.4
zdepth[3] = 1.8
zdepth[4] = 2.5
--- End code ---

...or with any other method of your choosing.




Additional Arrays

As well as the arrays that are required for startup, there are also two others that you may be interested in using.

They are SetStarX and SetStarY.  These are the "given" positions of stars.  The engine generates these automatically at the start of the level but there is no reason why you couldn't refer to it and change it during play using some code in your function LevelLogic().
For example, if I want to make a star (lets say star number 50) move from side to side, I can do it with this:



--- Code: ---function LevelLogic()
While GameRunning() do
SetStarX[50] = 1000 * math.sin(GetGameTime())

coroutine.yield()
end
end
--- End code ---

That would cause star number 50 to drift left and right.
Using this, it's possible to make some - or all - of the stars move.  You could move lots of them at once by employing a for loop.




You can do a similar thing with the other variables and arrays.  You could have stars that flash/twinkle, or pulsate, or anything you like.  You can even have stars that come closer or move further away!  (by changing the zdepth of their layer..)

Navigation

[0] Message Index

[#] Next page

Go to full version