FSM: Difference between revisions

From Unofficial EFPSE wiki Extended
Jump to navigation Jump to search
(Added the note about the way random number generation actually works.)
m (→‎Examples: Just fix the formatting with one of the headers so that they align with the other headers and produce a table of contents Correctly)
 
(33 intermediate revisions by 3 users not shown)
Line 4: Line 4:


===== Best practices =====
===== Best practices =====
Never have a space or tab Infront of any string. (White space is also counted when the engine reads the FSM/Script or script and unexpected spaces will break the FSM/Script)
Never have a space or tab in front of any string. (White space is also counted when the engine reads the FSM/Script or script and unexpected spaces will break the FSM/Script


===== '''Basic FSM for a weapon:''' =====
0.0167 - is exactly how long a single frame lasts for 60fps games. Numbers too small put too much pressure on the engine and it simply starts skipping frames altogether so a FSM should read like 
<blockquote>image Weapon 0 7


sound WeaponFire
frame 1 0.01 0 0 0 NONE anything lower then 0.01 will cause the engine to miss those frames 


sound WeaponReload
'''IMPORTANT'''


state IDLE NONE 0
The first line of any given state should always be NONE as this line is simply ignored due to am ongoing bug. By using NONE on the first line you cab circumvent this bug allowing the rest of your states to function as expected.


frame 1 0.25 0 0 0 NONE
'''image Decoration 0 3''' - loads sprites and adds them to a list. They are numbered from 0. In this case this command will load every sprite from "Decoration0" to "Decoration3". Sprites must be placed in Data/Sprites/ with appropriate entity folder (Decorations or [[Enemies]]) or weapons(Weapons). e.g. "Data/Sprites/Decorations". Weapon sprites MUST have frame 0 which is used for sprites on the floor.


frame 1 0.25 0 0 0 READY
'''image Decoration''' - will load only one sprite (in this case named "Decoration") and add it to a list.


state ATTACK IDLE 0
'''sound WeaponFire''' - will load a sound and add it to a list. They are numbered from 0. Sounds must be placed in Data/Sounds.


frame 2 1 0 0 0 NONE
'''state IDLE NONE 0''' - creates a new state, where IDLE is a name, NONE - name of the next state to jump to after this one is done (if it's NONE, current state will be looped), 0 (или 1) - sets if you want this state to interpolate model frames or not (if you use 3D models).


frame 3 1 0 0 0 SOUNDANDATTACK 0
'''frame 0 0.25 0 0 0 NONE''' - adds a frame to the latest created state. Here 0 - number of a sprite that was loaded (see earlier), 0.25 - time this frame will be staying on screen, 0 0 0 - offset coordinates (only for weapons), NONE - action (see further down).


frame 4 1 0 0 0 MUZZLEFLASH
States shown in examples are MANDATORY to create. There might be many other states, however enemies will only move while in CHASE state. Enemy will spawn blood when in state HURT.


frame 5 1 0 0 0 READY
There's also an additional state for weapons called ALTATTACK and can be used to use your weapon with right mouse button.


frame 6 1 0 0 0 NONE
Weapons can also have optional DRAW and HOLSTER states, which will be used when you switch to/from the weapon respectively. If specified, these will replace the weapon-switching animations.


frame 7 1 0 0 0 NONE
All key words are '''CASE SENSITIVE!''' Also be wary of whitespaces, they are important for engine to correctly parse parameters. Only latin characters are allowed.


frame 1 0.25 0 0 0 NONE


frame 1 0.25 0 0 0 NONE
'''Frame delays are the amount of time it takes for the frame to be displayed. It affects how long the *previous* frame is on the screen, not the *current* frame.'''


state RELOAD IDLE 0
=== States ===
Each of the state machines in EFPSE have built in states that the engine requires these entities to have. As stated before you can define others yourself but these are the built-in states that each of the entities expect to be defined.


frame 1 0 0 0 0 NONE
==== Decorations ====
'''IDLE:''' This is the first state the '''Decoration''' state machine will enter.


frame 1 0.1 0 0 0 NONE
'''DEATH:''' If at any point the '''Decoration''' HP is less than or zero the decoration will move to this state.


frame 1 0.1 0 200 0 NONE
'''DEAD:''' The dead state is where the '''Decoration''' state machine halts. Every entity in the engine has access to this state and is used in conjunction with the setting remove after break. Which will remove a decoration after it has zero hp.


frame 1 0.1 0 200 0 RELOAD
==== Weapons ====
'''IDLE:''' This is the first state the '''Weapon''' state machine will enter, ''if there is no draw state defined.''


frame 1 0.1 0 0 0 SOUND 1</blockquote>'''Basic FSM for alt attack:'''<blockquote>state ALTATTACK IDLE 0
'''DRAW:''' '''Weapon''' state machine will enter this state upon switching to the '''Weapon''' in game.


frame 1 0 0 0 NONE
'''HOLSTER''': '''Weapon''' state machine will enter this state upon switching from this '''Weapon''' in game.


frame 2 0 0 0 SOUNDATTACK 0     (plays the attack sound)
'''ATTACK:''' As long as ready has been called, '''Weapon''' state machine will enter this state once the left mouse button has been clicked


frame 3 0 0 0 MUZZLEFLASH         (Sets the muzzel flash)
'''ALTATTACK:''' As long as ready has been called, '''Weapon''' state machine will enter this state once the right mouse button has been clicked.


frameset 4 28 0 0 0 NONE               (This plays frames 4 through to 28 so that you don't have to write out each line)
'''RELOAD: Weapon''' state machine enters this state when player hits the reload key (r).


frame 29 0 0 0 ATTACK                   (sets the attack)
==== Enemies ====
'''IDLE:''' This is the first state the '''Enemy''' state machine will enter.


frame 30 0 0 0 READY </blockquote>
'''SEE:''' The '''Enemy''' state machine will enter the state upon seeing the player.


===== '''Basic FSM for enemies:''' =====
'''CHASE:''' When the '''Enemy''' state machine is in this state, the '''Enemy''' state machine will chase the player.
<blockquote>image Enemy 0 12


state IDLE NONE 0
'''ATTACK:''' When the '''Enemy''' state machine is in this state, the '''Enemy''' state machine will attack the player. However this attack must be explicitly defined; see [[weapon and enemy actions]].


frame 0 0.125 0 0 0 NONE
'''FLEE:''' When the '''Enemy''' state machine is in this state, the '''Enemy''' state machine will flee from the player.


frame 0 0.125 0 0 0 READY
'''HURT:''' When the '''Enemy''' is hurt they will go into this state and they will also spawn blood specified by the '''Enemy''' 's Blood image in the '''Enemies''' setting window.


state SEE CHASE 0
'''DEATH:''' If at any point if the HP of the '''Enemy''' drops to zero or below, the '''Enemy''' state machine will enter this state.


frame 0 0.125 0 0 0 NONE
'''DEAD:''' When the '''Enemy''' is in this state, the '''Enemy''' state machine will terminate and will be removed if the ''delete after death optio''n is selected and the '''Enemy''' settings window.


frame 0 0.125 0 0 0 READY
=== Actions: ===


state CHASE NONE 0
===== '''<u>Weapons Decorations and Enemies</u>''' =====


frame 1 1 0 0 0 NONE
====== Math ======
'''INCREMENT name [$value: 1]''' - increments the value of a variable, i.e. increases


frame 2 1 0 0 0 NONE
'''DECREMENT name [$value: 1]''' - decrements the value of a variable, i.e. decreases


frame 3 1 0 0 0 NONE
'''MULTIPLY name $value''' - multiplies the value of a variable


frame 4 1 0 0 0 READY
'''DIVIDE name $value''' - divides the value of a variable


state ATTACK CHASE 0
'''MODULO name $value''' - performs modulo operation on the value of a variable


frame 5 0.25 0 0 0 NONE
'''CLAMP name $min $max''' - confines the value of a variable between min and max


frame 5 0.25 0 0 0 NONE
====== Jumps ======
'''JUMPIFEQUALS variable $value state''' - moves to another state if variable value equal to the one we want. You can also use global. and map. prefixes.


frame 6 0.0625 0 0 0 NONE
'''JUMPIFNEQUALS variable $value state''' - moves to another state if variable value is not equal to the one we want. You can also use global. and map. prefixes.


frame 6 0.0625 0 0 0 ATTACK
'''JUMPIFGEQUALS variable $value state''' - moves to another state if variable value equal or greater to the one we want. You can also use global. and map. prefixes.


frame 5 0.25 0 0 0 NONE
'''JUMPIFLEQUALS variable $value state''' - moves to another state if variable value equal or less to the one we want. You can also use global. and map. prefixes.


frame 5 0.25 0 0 0 READY
'''JUMPIFGREATER variable $value state''' - moves to another state if variable value greater to the one we want. You can also use global. and map. prefixes.


state HURT CHASE 0
'''JUMPIFLESS variable $value state''' - moves to another state if variable value less to the one we want. You can also use global. and map. prefixes.


frame 7 0.125 0 0 0 NONE
'''JUMPIFHPLESS $value state''' - moves to another state if hp is lower than specified value (0 = no health, 1 = 100% health)


frame 8 0.125 0 0 0 NONE
===== <u>Other</u> =====
'''NONE''' - empty. Does nothing.


state DEATH DEAD 0
'''READY''' - sets if entity is ready to attack. Mandatory after enemy or weapon attack.


frame 9 0.166 0 0 0 NONE
'''SOUND $value''' - plays a sound, value - number of a loaded sound (see earlier).


frame 10 0.166 0 0 0 NONE
'''SOUNDANDATTACK $value''' - does attack and plays sound in one action.


frame 11 0.166 0 0 0 NONE
'''PLAYERSPEED $value''' - controls player's movement speed. 1 = normal, 0.5 = half, 2 = double, etc..


state DEAD NONE 0
'''PARTICLES imageindex i,l,x,y,z dx,dy,dz''' - creates particles. imageindex - number of sprite loaded, i - number of particles, l - particle lifetime, x,y,z - coordinates. Coordinates are local to enemy or player, meaning that 0,0,1 will always be in front of enemy or player. x - side offset, y - vertical offset, z - forward offset. dx,dy,dz - particle velocity. Also local to entity.


frame 12 0.125 0 0 0 NONE
'''CUSTOMPARTICLE $id $lifetime $x,$y,$z $dx,$dy,$dz $scale $gravity''' - creates one custom particle. id - which particle image to use (shared between all entities, loaded from "Particles\CustomX.png", X is the particleID), lifetime and xyz are the same as in PARTICLES. dx,dy,dz are always exact values, and will not be randomised. scale affects the particle size. gravity is the fall strength.<blockquote>Please note If you want to use CUSTOMPARTICLE command in FSM, you must be aware of the fact, that the first custom particle must be always named as "Custom0". Not "Custom1" or any other number. Counting starts from 0.


frame 12 0.125 0 0 0 NONE</blockquote>
To add to that, if you want to use particle that is named "Custom4" - this means that you must have all previous particles to exist and named in order: "Custom0", "Custom1","Custom2" and "Custom3". If you named your particle as "Custom20" - you must have 20 particles named appropriately before it, no gaps in counting, otherwise it wont load. </blockquote>'''SETVAR name $value''' - sets variable to a certain value. You can use RANDOM(0,100) instead of value. The value will be randomized from 0 to 100. You can also use global. and map. prefixes to set global or map variables (see [[Scripting]]). value can be set to LASTDAMAGE, HP or MAXHP to retrieve the last amount of damage the entity received, its current hp, or its max hp.


===== '''Basic FSM for decorations:''' =====
'''MODELTEXTURE path [name]''' - if a 3d model is used, sets the texture. Path is a texture path relative to your project directory (Textures/wallTexture.png). If a variable name is specified after the path, any $ symbols in the path will be replaced with that variable's value. Textures are cached when they are first used, allowing you to preload them for performance if required.
<blockquote>image Decoration 0 3


state IDLE NONE 0
'''SPAWN name x,y,z f,v''' - creates an entity with a name (enemies and decoration) or a keyword (Key1, Key2, Key3, Hp1, Hp2, Hp3, Hp4, Armour1, Armour2, Armour3, Armour4). x,y,z - just like with particles, f - front velocity when spawned, v - vertical velocity when spawning.


frame 0 0.25 0 0 0 NONE
'''HUDIMG $imageName $x $y $scale $path $layer''' - Exactly the same the "hud image" command. Creates or updates a hud image. Using the same imageName will replace the previous hud image with that name. Using 'HUDIMG imageName' without any other parameters will remove the specified hud image.


frame 0 0.25 0 0 0 READY
'''CAMSPEED $speedMultiplier''' - Sets a multiplier value to use for the player's camera rotation speed. 1 = normal, 0 = frozen, 2 = double, etc...


state DEATH DEAD 0
===== '''<u>Weapons and Enemies</u>''' =====
'''ATTACK''' - weapon or enemy attack


frame 1 0.166 0 0 0 NONE
===== '''<u>Enemies and Decorations</u>''' =====
'''EXPLOSION name radius''' - creates an explosion with a name and radius where name is name of explosion sprites. Sprites must be place in Data/Sprites/Effects.


frame 2 0.166 0 0 0 NONE
'''SPAWN name x,y,z f,v''' - creates an entity with a name (enemies and decoration) or a keyword (Key1, Key2, Key3, Hp1, Hp2, Hp3, Hp4). x,y,z - just like with particles, f - front velocity when spawned, v - vertical velocity when spawning. (enemies and decorations only).


frame 3 0.166 0 0 0 NONE
====== '''Enemies only''' ======
'''PROJECTILE [$angle: 0] [absolute? 0] [$height: 0] [$spread: 0]''' - shoots a projectile in the specified direction. angle is in degrees. If absolute is 0, angle will be relative to the player's direction (0 = directly at player, 180 = directly away from player). If absolute is 1, angle will be an exact direction in the world. 0=North, 90 = East, etc.. Height is a relative height offset to shoot the projectile (negative = lower, positive = higher). Spread adjusts how much random jitter to apply to the projectile's direction.


state DEAD NONE 0
====== '''Weapons only''' ======
'''JUMPIFLESSAMMO state''' - moves to another value if ammo in magazine is lower than maximum.


frame 3 0.25 0 0 0 NONE
'''JUMPIFNOAMMO state''' - moves to another state if magazine is empty.


frame 3 0.25 0 0 0 NONE</blockquote>'''Let's take a look:'''
'''GIVEAMMO [$value: 1] [fromTotal?: 0]''' - adds ammo to the weapon. If fromTotal is set to 1, ammo is taken from the total count, otherwise it's taken from the magazine.


'''image Decoration 0 3''' - loads sprites and adds them to a list. They are numbered from 0. In this case this command will load every sprite from "Decoration0" to "Decoration3". Sprites must be placed in Data/Sprites/ with apropriate entity folder (Decorations or [[Enemies]]) or weapons(Weapons). e.g. "Data/Sprites/Decorations". Weapon sprites MUST have frame 0 which is used for sprites on the floor.
'''TAKEAMMO [$value: 1] [fromTotal?: 0]''' - takes ammo from the weapon.


'''image Decoration''' - will load only one sprite (in this case named "Decoration") and add it to a list.
'''SETAMMO $value [fromTotal?: 0]''' - directly sets the weapon's ammo.


'''sound WeaponFire''' - will load a sound and add it to a list. They are numbered from 0. Sounds must be placed in Data/Sounds.
'''RELOAD''' - reloads magazine.


'''state IDLE NONE 0''' - creates a new state, where IDLE is a name, NONE - name of the next state to jump to after this one is done (if it's NONE, current state will be looped), 0 (или 1) - sets if you want this state to interpolate model frames or not (if you use 3D models).
'''MUZZLEFLASH''' - shows muzzle flash.


'''frame 0 0.25 0 0 0 NONE''' - adds a frame to the latest created state. Here 0 - number of a sprite that was loaded (see earlier), 0.25 - time this frame will be staying on screen, 0 0 0 - offset coordinates (only for weapons), NONE - action (see further down).
'''SETSTAT stat $value''' - sets one of the weapon's stats to specified value. Same available stats as the weapon command


States shown in examples are MANDATORY to create. There might be many other states, however enemies will only move while in CHASE state. Enemy will spawn blood when in state HURT.
'''ZOOM $value''' - sets the current camera zoom (-100 to 100). Negative values will zoom out. 0 = no zoom.


There's also an additional state for weapons called ALTATTACK and can be used to use your weapon with right mouse button.
=== Examples ===


===== Actions: =====
===== '''Basic FSM for a weapon:''' =====
* '''NONE''' - empty. Does nothing.
image Weapon 0 7
* '''ATTACK''' - weapon or enemy attack
* '''READY''' - sets if entity is ready to attack. Mandatory after enemy or weapon attack.
sound WeaponFire
* '''SOUND 0''' - plays a sound, 0 - number of a loaded sound (see earlier).
sound WeaponReload
* '''SOUNDANDATTACK 0''' - does attack and plays sound in one action.
* '''SETVAR name value''' - sets variable to a certain value. You can use RANDOM(0,100) instead of value. The value will be randomized from 0 to 100. You can also use global. and map. prefixes to set global or map variables (see [[Scripting]]). ''Actually - the generated random number will always be lower than the top value by one. This means that RANDOM(0,100) will generate any number in numeric segment from 0 to 99. It will never generate value equal to 100.'' ''If you would, for example, simulate a coin flip with each side having 50% chance, with zero means heads and one means tails - you must use RANDOM(0,2) action, because it will generate only zero's or one's. RANDOM(0,1) will always output only zero's. This is true for the latest - Dec 28, 2022 - 12th version of EFPSE currently available on Itch.io.''
state IDLE NONE 0
* '''INCREMENT name value''' - increments the value of a variable, i.e. increases by 1.
frame 1 0.25 0 0 0 NONE
* '''DECREMENT name value''' - decrements the value of a variable, i.e. decreases by 1.
frame 1 0.25 0 0 0 READY
* '''JUMPIFEQUALS variable value state''' - moves to another state if variable value equal to the one we want. You can also use global. and map. prefixes.
* '''JUMPIFNEQUALS variable value state''' - moves to another state if variable value is not equal to the one we want. You can also use global. and map. prefixes.
  state ATTACK IDLE 0
* '''JUMPIFGEQUALS variable value state''' - moves to another state if variable value equal or greater to the one we want. You can also use global. and map. prefixes.
frame 2 1 0 0 0 NONE
* '''JUMPIFLEQUALS variable value state''' - moves to another state if variable value equal or less to the one we want. You can also use global. and map. prefixes.
frame 3 1 0 0 0 SOUNDANDATTACK 0
* '''JUMPIFGREATER variable value state''' - moves to another state if variable value greater to the one we want. You can also use global. and map. prefixes.
frame 4 1 0 0 0 MUZZLEFLASH
* '''JUMPIFLESS variable value state''' - moves to another state if variable value less to the one we want. You can also use global. and map. prefixes.
frame 5 1 0 0 0 READY
* '''JUMPIFLESSAMMO state''' - moves to another value if ammo in magazine is lower than maximum (weapons only).
frame 6 1 0 0 0 NONE
* '''JUMPIFNOAMMO state''' - moves to another state if magazine is empty (weapons only).
frame 7 1 0 0 0 NONE
* '''GIVEAMMO''' - gives 1 ammo to a magazine. (weapons only).
frame 1 0.25 0 0 0 NONE
* '''TAKEAMMO''' - takes one ammo from magazine (weapons only).
frame 1 0.25 0 0 0 NONE
* '''RELOAD''' - reloads magazine (weapons only).
* '''MUZZLEFLASH''' - shows muzzle flash (weapons only).
state RELOAD IDLE 0
* '''PARTICLES imageindex i,l,x,y,z dx,dy,dz''' - creates particles. imageindex - number of sprite loaded, i - number of particles, l - particle lifetime, x,y,z - coordinates. Coordinates are local to enemy or player, meaning that 0,0,1 will always be in front of enemy or player. x - side offset, y - vertical offset, z - forward offset. dx,dy,dz - particle velocity. Also local to entity.
frame 1 0 0 0 0 NONE
* '''EXPLOSION name radius''' - creates an explosion with a name and radius where name is name of explosion sprites. Sprites must be place in Data/Sprites/Effects (enemies only).
frame 1 0.1 0 0 0 NONE
* '''SPAWN name x,y,z f,v''' - creates an entity with a name (enemies and decoration) or a keyword (Key1, Key2, Key3, Hp1, Hp2, Hp3, Hp4). x,y,z - just like with particles, f - front velocity when spawned, v - vertical velocity when spawning. (enemies and decorations only).
frame 1 0.1 0 200 0 NONE
* '''PLAYERSPEED''' - controls player's movement. You can only entirely freeze the movement (if set to 0) and enable it back (if set to 1), or double it (if set to 2).
frame 1 0.1 0 200 0 RELOAD
frame 1 0.1 0 0 0 SOUND 1


All key words are '''CASE SENSITIVE Also be wary of whitespaces, they are important for engine to correctly parse parameters. Only latin characters are allowed.'''
===== '''Basic FSM for enemies:''' =====
image Enemy 0 12
state IDLE NONE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY
state SEE CHASE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY
state CHASE NONE 0
frame 1 1 0 0 0 NONE
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 NONE
frame 4 1 0 0 0 READY
state ATTACK CHASE 0
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 NONE
frame 6 0.0625 0 0 0 NONE
frame 6 0.0625 0 0 0 ATTACK
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 READY
state HURT CHASE 0
frame 7 0.125 0 0 0 NONE
frame 8 0.125 0 0 0 NONE
state DEATH DEAD 0
frame 9 0.166 0 0 0 NONE
frame 10 0.166 0 0 0 NONE
frame 11 0.166 0 0 0 NONE
state DEAD NONE 0
frame 12 0.125 0 0 0 NONE
frame 12 0.125 0 0 0 NONE


===== '''Intermediate FSM for enemies:''' =====
image BORIS 0 455
sound AK
state IDLE NONE 0
frameset 2 254 0.025 0 0 0 NONE
frame 255 0.025 0 0 0 NONE
frame 256 0.025 0 0 0 READY
state SEE CHASE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY
state CHASE SEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY
state ATTACK CHASE 0
frame 463 0.025 0 0 0 NONE
frame 464 0.025 0 0 0 SOUNDANDATTACK 0
frameset 465 496 0.025 0 0 0 NONE
frame 497 0.025 0 0 0 READY
state HURT FLEE 0
frameset 286 340 0.025 0 0 0 NONE
frame 341 0.025 0 0 0 NONE
frame 342 0.025 0 0 0 READY
state FLEE SEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY
state SEE FLEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY
state FLEE CHASE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY
state DEATH DEAD 0
frameset 357 453 0.025 0 0 0 NONE
frame 454 0.025 0 0 0 NONE
frame 455 0.025 0 0 0 NONE
state DEAD NONE 0
frame 455 0.025 0 0 0 NONE


'''An Example of a working FSM for a weapon with a Alt fire which fires 3 shots in quick succession.'''<blockquote>image ColtNavy 0 12
===== '''Basic FSM for decorations:''' =====
 
image Decoration 0 3
sound ColtNavyFire
 
state IDLE NONE 0
sound ColtNavyReload
frame 0 0.25 0 0 0 NONE
 
frame 0 0.25 0 0 0 READY
state IDLE NONE 0
 
state DEATH DEAD 0
frame 1 0.1 0 0 0 NONE
frame 1 0.166 0 0 0 NONE
 
frame 2 0.166 0 0 0 NONE
frame 1 0.1 0 0 0 READY
frame 3 0.166 0 0 0 NONE
 
state ATTACK IDLE 0
state DEAD NONE 0
 
frame 3 0.25 0 0 0 NONE
frame 2 0.10 0 0 0 NONE
frame 3 0.25 0 0 0 NONE
 
<div id="progs">
frame 3 0.10 0 0 0 NONE
===== Environment Particles =====
 
Environmental particles can now be created using the FSM command for CUSTOMPARTICLES, it works by randomizing the location the particles spawn on the x,y,z coordinates and adjusting the gravity. In this example the particle uses custom particle number 21 so the image file in the particles folder is called Custom21. Typically this folder can be found at EasyFPSEditor\Projects\YourProject\Sprites\Particles
frame 4 0.10 0 0 0 SOUNDANDATTACK 0
{{#ev:youtube|5vtxVH-X6ko}}
 
</div>
frame 5 0.10 0 0 0 MUZZLEFLASH
image particles 0 1
 
frame 6 0.10 0 0 0 NONE
state IDLE NONE 0
 
frame 0 0.025 0 0 0 NONE
frame 7 0.10 0 0 0 READY
frame 0 0.025 0 0 0 SETVAR p1 RANDOM(1,100)
 
frame 0 0.025 0 0 0 SETVAR p2 RANDOM(1,50)
state ALTATTACK IDLE 0
frame 0 0.025 0 0 0 SETVAR p3 RANDOM(1,100)
 
frame 0 0.1 0 0 0 CUSTOMPARTICLE 21 3000 $p1,$p2,$p3 0.005,0.003,0.001 0.08 -0.001
frame 8 0.04 0 0 0 NONE
frame 0 0.025 0 0 0 SETVAR p4 RANDOM(1,100)
 
frame 0 0.025 0 0 0 SETVAR p5 RANDOM(1,50)
frame 8 0.04 0 0 0 JUMPIFNOAMMO IDLE
frame 0 0.025 0 0 0 SETVAR p6 RANDOM(1,100)
 
frame 0 0.1 0 0 0 CUSTOMPARTICLE 21 3000 $p4,$p5,$p6 0.001,0.003,0.005 0.06 0.001
frame 8 0.04 0 0 0 READY
frame 0 0.025 0 0 0 READY
 
frame 9 0.04 0 0 0 SOUNDANDATTACK 0
 
frame 10 0.04 0 0 0 MUZZLEFLASH
 
frame 10 0.04 0 0 0 JUMPIFNOAMMO IDLE
 
frame 11 0.04 0 0 0 READY
 
frame 9 0.04 0 0 0 SOUNDANDATTACK 0
 
frame 10 0.04 0 0 0 MUZZLEFLASH
 
frame 10 0.04 0 0 0 JUMPIFNOAMMO IDLE
 
frame 11 0.04 0 0 0 READY
 
frame 11 0.04 0 0 0 SOUNDANDATTACK 0
 
frame 10 0.04 0 0 0 MUZZLEFLASH
 
frame 9 0.04 0 0 0 NONE
 
frame 8 0.04 0 0 0 READY
 
state RELOAD IDLE 0
 
frame 1 0 0 0 0 NONE
 
frame 1 0.1 0 0 0 SOUND 1
 
frame 1 0.1 0 200 0 NONE


frame 1 0.1 0 200 0 RELOAD</blockquote>
===== Click to Fire - =====
A setup for one shot per click so you cannot just hold down the trigger and spam bullets
image WeaponName 0 17
state IDLE NONE 0
frame 1 0.01 0 0 0 NONE
frame 1 0.1 0 0 0 SETVAR global.WEAP 2
frame 1 0.01 0 0 0 SETVAR canShoot 1
frame 1 0.1 0 0 0 READY
state ATTACK IDLE 0
frame 1 0.01 0 0 0 NONE
frame 1 0.01 0 0 0 JUMPIFEQUALS canShoot 0 IDLE
frame 1 0.01 0 0 0 SETVAR canShoot 0
frame 2 0.03 0 0 0 MUZZLEFLASH
frame 4 0.03 0 0 0 SOUNDANDATTACK 0
frame 5 0.03 0 0 0 NONE
frame 6 0.03 0 0 0 NONE
frame 7 0.03 0 0 0 READY
state RELOAD IDLE 0
frame 8 0.07 0 0 0 NONE
frame 9 0.07 0 0 0 SOUND 1
frame 10 0.07 0 0 0 NONE
frame 11 0.07 0 0 0 NONE
frame 12 0.07 0 0 0 NONE
frame 13 0.07 0 0 0 NONE
frame 14 0.07 0 0 0 NONE
frame 15 0.07 0 0 0 NONE
frame 16 0.07 0 0 0 NONE
frame 17 0.07 0 0 0 RELOAD

Latest revision as of 13:28, 1 June 2024

FSM or Finite State Machine allows you to extend sprites animation and entities behavior on general. It is a set of lines that describe what sprites enemy or decorations will have and what will they do. In short, you can change how many sprites an entity has and how fast frames will switch one another.

To add a state machine, you need to create a file with the .states extension and the name of the weapon, enemy, or decoration in the ProjectName/States folder. When adding a state machine, the attack and reload speed will no longer depend on the setting in the editor - everything will be controlled only by the duration of the frames specified in the file. In addition, all sprites and (for weapons) some of the sounds will need to be loaded manually using the image and sound commands.

Best practices

Never have a space or tab in front of any string. (White space is also counted when the engine reads the FSM/Script or script and unexpected spaces will break the FSM/Script

0.0167 - is exactly how long a single frame lasts for 60fps games. Numbers too small put too much pressure on the engine and it simply starts skipping frames altogether so a FSM should read like

frame 1 0.01 0 0 0 NONE anything lower then 0.01 will cause the engine to miss those frames

IMPORTANT

The first line of any given state should always be NONE as this line is simply ignored due to am ongoing bug. By using NONE on the first line you cab circumvent this bug allowing the rest of your states to function as expected.

image Decoration 0 3 - loads sprites and adds them to a list. They are numbered from 0. In this case this command will load every sprite from "Decoration0" to "Decoration3". Sprites must be placed in Data/Sprites/ with appropriate entity folder (Decorations or Enemies) or weapons(Weapons). e.g. "Data/Sprites/Decorations". Weapon sprites MUST have frame 0 which is used for sprites on the floor.

image Decoration - will load only one sprite (in this case named "Decoration") and add it to a list.

sound WeaponFire - will load a sound and add it to a list. They are numbered from 0. Sounds must be placed in Data/Sounds.

state IDLE NONE 0 - creates a new state, where IDLE is a name, NONE - name of the next state to jump to after this one is done (if it's NONE, current state will be looped), 0 (или 1) - sets if you want this state to interpolate model frames or not (if you use 3D models).

frame 0 0.25 0 0 0 NONE - adds a frame to the latest created state. Here 0 - number of a sprite that was loaded (see earlier), 0.25 - time this frame will be staying on screen, 0 0 0 - offset coordinates (only for weapons), NONE - action (see further down).

States shown in examples are MANDATORY to create. There might be many other states, however enemies will only move while in CHASE state. Enemy will spawn blood when in state HURT.

There's also an additional state for weapons called ALTATTACK and can be used to use your weapon with right mouse button.

Weapons can also have optional DRAW and HOLSTER states, which will be used when you switch to/from the weapon respectively. If specified, these will replace the weapon-switching animations.

All key words are CASE SENSITIVE! Also be wary of whitespaces, they are important for engine to correctly parse parameters. Only latin characters are allowed.


Frame delays are the amount of time it takes for the frame to be displayed. It affects how long the *previous* frame is on the screen, not the *current* frame.

States

Each of the state machines in EFPSE have built in states that the engine requires these entities to have. As stated before you can define others yourself but these are the built-in states that each of the entities expect to be defined.

Decorations

IDLE: This is the first state the Decoration state machine will enter.

DEATH: If at any point the Decoration HP is less than or zero the decoration will move to this state.

DEAD: The dead state is where the Decoration state machine halts. Every entity in the engine has access to this state and is used in conjunction with the setting remove after break. Which will remove a decoration after it has zero hp.

Weapons

IDLE: This is the first state the Weapon state machine will enter, if there is no draw state defined.

DRAW: Weapon state machine will enter this state upon switching to the Weapon in game.

HOLSTER: Weapon state machine will enter this state upon switching from this Weapon in game.

ATTACK: As long as ready has been called, Weapon state machine will enter this state once the left mouse button has been clicked

ALTATTACK: As long as ready has been called, Weapon state machine will enter this state once the right mouse button has been clicked.

RELOAD: Weapon state machine enters this state when player hits the reload key (r).

Enemies

IDLE: This is the first state the Enemy state machine will enter.

SEE: The Enemy state machine will enter the state upon seeing the player.

CHASE: When the Enemy state machine is in this state, the Enemy state machine will chase the player.

ATTACK: When the Enemy state machine is in this state, the Enemy state machine will attack the player. However this attack must be explicitly defined; see weapon and enemy actions.

FLEE: When the Enemy state machine is in this state, the Enemy state machine will flee from the player.

HURT: When the Enemy is hurt they will go into this state and they will also spawn blood specified by the Enemy 's Blood image in the Enemies setting window.

DEATH: If at any point if the HP of the Enemy drops to zero or below, the Enemy state machine will enter this state.

DEAD: When the Enemy is in this state, the Enemy state machine will terminate and will be removed if the delete after death option is selected and the Enemy settings window.

Actions:

Weapons Decorations and Enemies
Math

INCREMENT name [$value: 1] - increments the value of a variable, i.e. increases

DECREMENT name [$value: 1] - decrements the value of a variable, i.e. decreases

MULTIPLY name $value - multiplies the value of a variable

DIVIDE name $value - divides the value of a variable

MODULO name $value - performs modulo operation on the value of a variable

CLAMP name $min $max - confines the value of a variable between min and max

Jumps

JUMPIFEQUALS variable $value state - moves to another state if variable value equal to the one we want. You can also use global. and map. prefixes.

JUMPIFNEQUALS variable $value state - moves to another state if variable value is not equal to the one we want. You can also use global. and map. prefixes.

JUMPIFGEQUALS variable $value state - moves to another state if variable value equal or greater to the one we want. You can also use global. and map. prefixes.

JUMPIFLEQUALS variable $value state - moves to another state if variable value equal or less to the one we want. You can also use global. and map. prefixes.

JUMPIFGREATER variable $value state - moves to another state if variable value greater to the one we want. You can also use global. and map. prefixes.

JUMPIFLESS variable $value state - moves to another state if variable value less to the one we want. You can also use global. and map. prefixes.

JUMPIFHPLESS $value state - moves to another state if hp is lower than specified value (0 = no health, 1 = 100% health)

Other

NONE - empty. Does nothing.

READY - sets if entity is ready to attack. Mandatory after enemy or weapon attack.

SOUND $value - plays a sound, value - number of a loaded sound (see earlier).

SOUNDANDATTACK $value - does attack and plays sound in one action.

PLAYERSPEED $value - controls player's movement speed. 1 = normal, 0.5 = half, 2 = double, etc..

PARTICLES imageindex i,l,x,y,z dx,dy,dz - creates particles. imageindex - number of sprite loaded, i - number of particles, l - particle lifetime, x,y,z - coordinates. Coordinates are local to enemy or player, meaning that 0,0,1 will always be in front of enemy or player. x - side offset, y - vertical offset, z - forward offset. dx,dy,dz - particle velocity. Also local to entity.

CUSTOMPARTICLE $id $lifetime $x,$y,$z $dx,$dy,$dz $scale $gravity - creates one custom particle. id - which particle image to use (shared between all entities, loaded from "Particles\CustomX.png", X is the particleID), lifetime and xyz are the same as in PARTICLES. dx,dy,dz are always exact values, and will not be randomised. scale affects the particle size. gravity is the fall strength.

Please note If you want to use CUSTOMPARTICLE command in FSM, you must be aware of the fact, that the first custom particle must be always named as "Custom0". Not "Custom1" or any other number. Counting starts from 0. To add to that, if you want to use particle that is named "Custom4" - this means that you must have all previous particles to exist and named in order: "Custom0", "Custom1","Custom2" and "Custom3". If you named your particle as "Custom20" - you must have 20 particles named appropriately before it, no gaps in counting, otherwise it wont load.

SETVAR name $value - sets variable to a certain value. You can use RANDOM(0,100) instead of value. The value will be randomized from 0 to 100. You can also use global. and map. prefixes to set global or map variables (see Scripting). value can be set to LASTDAMAGE, HP or MAXHP to retrieve the last amount of damage the entity received, its current hp, or its max hp.

MODELTEXTURE path [name] - if a 3d model is used, sets the texture. Path is a texture path relative to your project directory (Textures/wallTexture.png). If a variable name is specified after the path, any $ symbols in the path will be replaced with that variable's value. Textures are cached when they are first used, allowing you to preload them for performance if required.

SPAWN name x,y,z f,v - creates an entity with a name (enemies and decoration) or a keyword (Key1, Key2, Key3, Hp1, Hp2, Hp3, Hp4, Armour1, Armour2, Armour3, Armour4). x,y,z - just like with particles, f - front velocity when spawned, v - vertical velocity when spawning.

HUDIMG $imageName $x $y $scale $path $layer - Exactly the same the "hud image" command. Creates or updates a hud image. Using the same imageName will replace the previous hud image with that name. Using 'HUDIMG imageName' without any other parameters will remove the specified hud image.

CAMSPEED $speedMultiplier - Sets a multiplier value to use for the player's camera rotation speed. 1 = normal, 0 = frozen, 2 = double, etc...

Weapons and Enemies

ATTACK - weapon or enemy attack

Enemies and Decorations

EXPLOSION name radius - creates an explosion with a name and radius where name is name of explosion sprites. Sprites must be place in Data/Sprites/Effects.

SPAWN name x,y,z f,v - creates an entity with a name (enemies and decoration) or a keyword (Key1, Key2, Key3, Hp1, Hp2, Hp3, Hp4). x,y,z - just like with particles, f - front velocity when spawned, v - vertical velocity when spawning. (enemies and decorations only).

Enemies only

PROJECTILE [$angle: 0] [absolute? 0] [$height: 0] [$spread: 0] - shoots a projectile in the specified direction. angle is in degrees. If absolute is 0, angle will be relative to the player's direction (0 = directly at player, 180 = directly away from player). If absolute is 1, angle will be an exact direction in the world. 0=North, 90 = East, etc.. Height is a relative height offset to shoot the projectile (negative = lower, positive = higher). Spread adjusts how much random jitter to apply to the projectile's direction.

Weapons only

JUMPIFLESSAMMO state - moves to another value if ammo in magazine is lower than maximum.

JUMPIFNOAMMO state - moves to another state if magazine is empty.

GIVEAMMO [$value: 1] [fromTotal?: 0] - adds ammo to the weapon. If fromTotal is set to 1, ammo is taken from the total count, otherwise it's taken from the magazine.

TAKEAMMO [$value: 1] [fromTotal?: 0] - takes ammo from the weapon.

SETAMMO $value [fromTotal?: 0] - directly sets the weapon's ammo.

RELOAD - reloads magazine.

MUZZLEFLASH - shows muzzle flash.

SETSTAT stat $value - sets one of the weapon's stats to specified value. Same available stats as the weapon command

ZOOM $value - sets the current camera zoom (-100 to 100). Negative values will zoom out. 0 = no zoom.

Examples

Basic FSM for a weapon:
image Weapon 0 7

sound WeaponFire
sound WeaponReload

state IDLE NONE 0
frame 1 0.25 0 0 0 NONE
frame 1 0.25 0 0 0 READY

state ATTACK IDLE 0
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 SOUNDANDATTACK 0
frame 4 1 0 0 0 MUZZLEFLASH
frame 5 1 0 0 0 READY
frame 6 1 0 0 0 NONE
frame 7 1 0 0 0 NONE
frame 1 0.25 0 0 0 NONE
frame 1 0.25 0 0 0 NONE

state RELOAD IDLE 0
frame 1 0 0 0 0 NONE
frame 1 0.1 0 0 0 NONE
frame 1 0.1 0 200 0 NONE
frame 1 0.1 0 200 0 RELOAD
frame 1 0.1 0 0 0 SOUND 1
Basic FSM for enemies:
image Enemy 0 12

state IDLE NONE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY

state SEE CHASE 0
frame 0 0.125 0 0 0 NONE
frame 0 0.125 0 0 0 READY

state CHASE NONE 0
frame 1 1 0 0 0 NONE
frame 2 1 0 0 0 NONE
frame 3 1 0 0 0 NONE
frame 4 1 0 0 0 READY

state ATTACK CHASE 0
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 NONE
frame 6 0.0625 0 0 0 NONE
frame 6 0.0625 0 0 0 ATTACK
frame 5 0.25 0 0 0 NONE
frame 5 0.25 0 0 0 READY

state HURT CHASE 0
frame 7 0.125 0 0 0 NONE
frame 8 0.125 0 0 0 NONE

state DEATH DEAD 0
frame 9 0.166 0 0 0 NONE
frame 10 0.166 0 0 0 NONE
frame 11 0.166 0 0 0 NONE

state DEAD NONE 0
frame 12 0.125 0 0 0 NONE
frame 12 0.125 0 0 0 NONE
Intermediate FSM for enemies:
image BORIS 0 455

sound AK

state IDLE NONE 0

frameset 2 254 0.025 0 0 0 NONE
frame 255 0.025 0 0 0 NONE
frame 256 0.025 0 0 0 READY

state SEE CHASE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY

state CHASE SEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY

state ATTACK CHASE 0
frame 463 0.025 0 0 0 NONE
frame 464 0.025 0 0 0 SOUNDANDATTACK 0
frameset 465 496 0.025 0 0 0 NONE
frame 497 0.025 0 0 0 READY

state HURT FLEE 0
frameset 286 340 0.025 0 0 0 NONE
frame 341 0.025 0 0 0 NONE
frame 342 0.025 0 0 0 READY

state FLEE SEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY

state SEE FLEE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY

state FLEE CHASE 0
frameset 262 281 0.025 0 0 0 NONE
frame 282 0.025 0 0 0 NONE
frame 283 0.025 0 0 0 READY

state DEATH DEAD 0
frameset 357 453 0.025 0 0 0 NONE
frame 454 0.025 0 0 0 NONE
frame 455 0.025 0 0 0 NONE

state DEAD NONE 0
frame 455 0.025 0 0 0 NONE
Basic FSM for decorations:
image Decoration 0 3

state IDLE NONE 0
frame 0 0.25 0 0 0 NONE
frame 0 0.25 0 0 0 READY

state DEATH DEAD 0
frame 1 0.166 0 0 0 NONE
frame 2 0.166 0 0 0 NONE
frame 3 0.166 0 0 0 NONE

state DEAD NONE 0
frame 3 0.25 0 0 0 NONE
frame 3 0.25 0 0 0 NONE
Environment Particles

Environmental particles can now be created using the FSM command for CUSTOMPARTICLES, it works by randomizing the location the particles spawn on the x,y,z coordinates and adjusting the gravity. In this example the particle uses custom particle number 21 so the image file in the particles folder is called Custom21. Typically this folder can be found at EasyFPSEditor\Projects\YourProject\Sprites\Particles

image particles 0 1

state IDLE NONE 0
frame 0 0.025 0 0 0 NONE
frame 0 0.025 0 0 0 SETVAR p1 RANDOM(1,100)
frame 0 0.025 0 0 0 SETVAR p2 RANDOM(1,50)
frame 0 0.025 0 0 0 SETVAR p3 RANDOM(1,100)
frame 0 0.1 0 0 0 CUSTOMPARTICLE 21 3000 $p1,$p2,$p3 0.005,0.003,0.001 0.08 -0.001
frame 0 0.025 0 0 0 SETVAR p4 RANDOM(1,100)
frame 0 0.025 0 0 0 SETVAR p5 RANDOM(1,50)
frame 0 0.025 0 0 0 SETVAR p6 RANDOM(1,100)
frame 0 0.1 0 0 0 CUSTOMPARTICLE 21 3000 $p4,$p5,$p6 0.001,0.003,0.005 0.06 0.001
frame 0 0.025 0 0 0 READY
Click to Fire -

A setup for one shot per click so you cannot just hold down the trigger and spam bullets

image WeaponName 0 17

state IDLE NONE 0
frame 1 0.01 0 0 0 NONE
frame 1 0.1 0 0 0 SETVAR global.WEAP 2
frame 1 0.01 0 0 0 SETVAR canShoot 1
frame 1 0.1 0 0 0 READY

state ATTACK IDLE 0
frame 1 0.01 0 0 0 NONE
frame 1 0.01 0 0 0 JUMPIFEQUALS canShoot 0 IDLE
frame 1 0.01 0 0 0 SETVAR canShoot 0
frame 2 0.03 0 0 0 MUZZLEFLASH
frame 4 0.03 0 0 0 SOUNDANDATTACK 0
frame 5 0.03 0 0 0 NONE
frame 6 0.03 0 0 0 NONE
frame 7 0.03 0 0 0 READY

state RELOAD IDLE 0
frame 8 0.07 0 0 0 NONE
frame 9 0.07 0 0 0 SOUND 1
frame 10 0.07 0 0 0 NONE
frame 11 0.07 0 0 0 NONE
frame 12 0.07 0 0 0 NONE
frame 13 0.07 0 0 0 NONE
frame 14 0.07 0 0 0 NONE
frame 15 0.07 0 0 0 NONE
frame 16 0.07 0 0 0 NONE
frame 17 0.07 0 0 0 RELOAD