Physics

From Everybody Edits Wiki
Revision as of 20:52, 1 November 2026 by PiotrGrochowski (talk | contribs) (Created page with "Everybody Edits includes a physics engine to manage the movement of its players and interactions with player inputs and world blocks. ==Source code files== Inside Everybody Edits Offline source: {| class="wikitable" |Config.as |constants used in the physics engine (such as drag values, jump height, gravity values, delayed block queue, etc.) |- |Me.as |touchBlock function (handles most non-solid collisions, such as interactions with coins, reset block, sound blocks...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Everybody Edits includes a physics engine to manage the movement of its players and interactions with player inputs and world blocks.

Source code files

Inside Everybody Edits Offline source:

Config.as constants used in the physics engine (such as drag values, jump height, gravity values, delayed block queue, etc.)
Me.as touchBlock function (handles most non-solid collisions, such as interactions with coins, reset block, sound blocks, crown, switches, invisible gravity, diamond/cake/hologram, checkpoint, win, god enable, minimap enable, keys, effects, lava)
Player.as tick function (handles most of the physics logic)
World.as overlaps function (handles collision with solid blocks, including doors/gates, half blocks, one-way, and secret blocks)

Timing

EE physics runs at 100tps (100 ticks per second), meaning that each physics tick takes 0.01 seconds.

Inputs

On each tick, the arrow/WASD keys and space keys are evaluated. The arrow/WASD inputs are converted into horizontal and vertical components of -1, 0, or 1, in which left+right and up+down inputs cancel out to 0. Space may be pressed independently of other keys.

Coordinates

Player's coordinates are represented in double precision floating point. The position [0, 0] corresponds to the top left block, and increases to the right and downwards in pixels (16 pixels per block on both axes). The bottom right position is [(width-1)*16, (height-1)*16].

Current and delayed blocks

The current block is determined by dividing player's position by 16 and rounding it (round to nearest, halfway values round up), except for down half or right half block, which decrement vertical or horizontal position of current block respectively.

The delayed block corresponds to current block from second previous tick (therefore delayed by 2 ticks from current block), unless the current block is a gravity dot or climbable/slow dot, in which case the current block is pushed to the queue a second time (effectively making delayed block only delayed by 1 tick), resulting in dots having a slightly faster reaction than other gravities.

Slippery field

First, the current_below block is determined (only used for computing slippery value). It follows the gravity direction inside the current block (following player's gravity if current is not a gravity arrow) and offsets by 1 from the current block to determine the current_below block. However, invisible right arrow (413), down arrow (1518, 1519), and invisible dot (414) are ignored, dot (4) is interpreted as a down offset, and neutral gravity (flipGravity==4) is interpreted as a right offset.

The slippery value is initialized to 0. It is set to 2 if current_below is an ice block and current is not a dot or climbable/slow dot. Otherwise, it is set to 0 if current_below is solid. Otherwise, it is set to 0.2 less than previous slippery value.

In case of slippery>0, jump height is multiplied by 0.88, it also affects drag computation.

Drag values

Drag values are used for multiplicative deceleration of player's speed.

name definition floating point result
physics_ms_per_tick 10 10
physics_base_drag Math.pow(.9981,physics_ms_per_tick) * 1.00016093 0.9813195279915707
physics_ice_no_mod_drag Math.pow(.9993,physics_ms_per_tick) * 1.00016093 0.9931818159222691
physics_ice_drag Math.pow(.9998,physics_ms_per_tick) * 1.00016093 0.9981624074698557
physics_no_modifier_drag Math.pow(.9900,physics_ms_per_tick) * 1.00016093 0.9045276172161356
physics_water_drag Math.pow(.9950,physics_ms_per_tick) * 1.00016093 0.9512631926190678
physics_mud_drag Math.pow(.9750,physics_ms_per_tick) * 1.00016093 0.7764545555823221
physics_lava_drag Math.pow(.9800,physics_ms_per_tick) * 1.00016093 0.8172042984143593
physics_toxic_drag Math.pow(.9900,physics_ms_per_tick) * 1.00016093 0.9045276172161356

The speed is added with the sum of lateral acceleration (performed with player's horizontal/vertical movements, ignoring movements along the axis of gravity), and gravitational acceleration (performed by current arrow or world gravity).

Then, using the drag constants, drag is applied on each axis as follows (first true condition applies):

case resulting speed
used if current block is climbable/slow dot (except god mode)
not used if slippery<=0 (unless in god mode)
used if lateral acceleration along the axis is 0 and gravity is on perpendicular axis
used if speed and lateral acceleration along the axis are non-zero and of opposite signs
speed*physics_base_drag*physics_no_modifier_drag
used if current block is water speed*physics_base_drag*physics_water_drag
used if current block is mud speed*physics_base_drag*physics_mud_drag
used if current block is lava speed*physics_base_drag*physics_lava_drag
used if current block is toxic speed*physics_base_drag*physics_toxic_drag
used if slippery>0 (except god mode), lateral acceleration along the axis is non-zero, and speed along the axis is zero or same sign as lateral movement speed*physics_base_drag
used if slippery>0 (except god mode), lateral acceleration along the axis is 0 speed*physics_ice_no_mod_drag
used if slippery>0 (except god mode), speed and lateral acceleration along the axis are non-zero and of opposite signs speed*physics_ice_no_mod_drag*physics_ice_drag
used if none of the above speed*physics_base_drag

After computing drag on each axis, the speed is capped to a minimum of -16 and maximum of 16.

Speeds less than 0.0001 and greater than -0.0001 are set to 0. That's when the player will start falling on hovers if not moving (prior to that, it can stay in hover if within 0.2 pixels of block due to auto-align), or will be able to jump on a Tight-fit (which is why it takes more time to perform an Ice Tight-fit due to the ice drag being closer to 1).

Boosts force the speed to be -16 or 16 on the axis they apply to, though the other axis still follows the usual computations.