aboutsummaryrefslogtreecommitdiff
path: root/docs/entities.org
diff options
context:
space:
mode:
authorGene Pasquet <dev@etenil.net>2026-04-08 07:08:54 +0100
committerGene Pasquet <dev@etenil.net>2026-04-08 07:08:54 +0100
commitafc30a12e25215ff5e9226c3b4f8fd127d9a4d68 (patch)
treef736393fb8ebfd8982a4b79310a08c57ee430ff0 /docs/entities.org
parent9e8b75f9949259ef01942cd3717b79b044efddf7 (diff)
Move the engine-update to the scene
Diffstat (limited to 'docs/entities.org')
-rw-r--r--docs/entities.org59
1 files changed, 21 insertions, 38 deletions
diff --git a/docs/entities.org b/docs/entities.org
index 9f8e9ee..06b1831 100644
--- a/docs/entities.org
+++ b/docs/entities.org
@@ -91,13 +91,13 @@ Since each update returns a new entity, chain updates with ~let*~:
#+begin_src scheme
(let* ((player (entity-set player #:vx 3))
- (player (apply-velocity-x player))
- (player (resolve-tile-collisions-x player tilemap)))
+ (player (apply-velocity-x player scene dt))
+ (player (resolve-tile-collisions-x player scene dt)))
;; now use the updated player
player)
#+end_src
-This is how the platformer demo applies physics in order: each step reads the input, computes the next state, and passes it to the next step.
+With the default =engine-update=, you normally set =#:vx= / =#:ay= in =update:= and do not chain physics steps yourself. This =let*= shape is for custom =engine-update= hooks or tests; per-entity steps take =(entity scene dt)=.
* Plist Key Reference
@@ -111,7 +111,7 @@ The engine recognizes these standard keys. Use them to integrate with the physic
| ~#:vx~, ~#:vy~ | number | Velocity in pixels per frame. ~#:vx~ is updated by ~apply-velocity-x~; ~#:vy~ is updated by ~apply-velocity-y~. Both consumed by collision resolvers. |
| ~#:ay~ | number | Y acceleration (e.g., from jumping or knockback). Consumed by ~apply-acceleration~, which adds it to ~#:vy~. Optional; default is 0. |
| ~#:gravity?~ | boolean | Whether gravity applies to this entity. Set to ~#t~ for platformers (gravity pulls down), ~#f~ for top-down or flying entities. Used by ~apply-gravity~. |
-| ~#:on-ground?~ | boolean | Whether the entity is supported from below (set by ~detect-on-solid~): solid tile under the feet and/or standing on another solid entity when you pass the scene entity list. Use this to gate jump input. |
+| ~#:on-ground?~ | boolean | Whether the entity is supported from below (set by ~detect-on-solid~ in the default pipeline): solid tile under the feet and/or standing on another solid entity from ~(scene-entities scene)~. Use this in ~update:~ to gate jump input (~#:ay~). |
| ~#:solid?~ | boolean | Whether this entity participates in entity-entity collision. If ~#t~, ~resolve-entity-collisions~ will check it against other solid entities. |
| ~#:immovable?~ | boolean | If ~#t~ with ~#:solid? #t~, entity–entity resolution only moves the *other* entity (static platforms). Two overlapping immovable solids are not separated. |
| ~#:skip-pipelines~ | list of symbols | Optional. Each symbol names a pipeline step to skip (e.g. ~gravity~, ~velocity-x~, ~tweens~). See ~docs/physics.org~ and ~docs/tweens.org~. |
@@ -173,21 +173,16 @@ Returns a new scene with the entity appended to the entity list.
Maps each procedure over the scene's entities, applying them in sequence. Each proc must be a function of one entity, returning a new entity.
#+begin_src scheme
-;; Apply physics pipeline to all entities:
+;; Example: map per-entity physics steps (need scene + dt in scope):
(scene-map-entities scene
- apply-gravity
- apply-velocity-x
- apply-velocity-y)
+ (lambda (e) (apply-gravity e scene dt))
+ (lambda (e) (apply-velocity-x e scene dt))
+ (lambda (e) (apply-velocity-y e scene dt)))
#+end_src
-The result is equivalent to:
+The result is equivalent to chaining three =scene-map-entities= passes, one per step.
-#+begin_src scheme
-(chain scene
- (scene-map-entities _ apply-gravity)
- (scene-map-entities _ apply-velocity-x)
- (scene-map-entities _ apply-velocity-y))
-#+end_src
+With default =engine-update=, the engine applies the full pipeline for you; use this pattern inside a custom =engine-update= or tools.
** ~scene-filter-entities scene pred~
@@ -328,7 +323,7 @@ While tags are free-form, consider using these conventions in your game:
* Example: Complete Entity Setup
-Here is a full example showing entity creation, initialization in the scene, and update logic:
+Here is a full example showing entity creation, initialization in the scene, and update logic (assumes =downstroke-physics= is imported for =*jump-force*=):
#+begin_src scheme
(define (create-player-entity)
@@ -358,40 +353,28 @@ Here is a full example showing entity creation, initialization in the scene, and
(define (update-hook game dt)
(let* ((input (game-input game))
(scene (game-scene game))
- (player (scene-find-tagged scene 'player))
- (tm (scene-tilemap scene)))
- ;; Update input-driven velocity
+ (player (scene-find-tagged scene 'player)))
+ ;; Intent + presentation — default engine-update already ran physics this frame
(let* ((player (entity-set player #:vx
(cond
((input-held? input 'left) -3)
((input-held? input 'right) 3)
(else 0))))
- ;; Handle jump
(player (if (and (input-pressed? input 'a)
(entity-ref player #:on-ground? #f))
- (entity-set player #:ay -5)
+ (entity-set player #:ay (- *jump-force*))
player))
- ;; Apply physics
- (player (apply-acceleration player))
- (player (apply-gravity player))
- (player (apply-velocity-x player))
- (player (resolve-tile-collisions-x player tm))
- (player (apply-velocity-y player))
- (player (resolve-tile-collisions-y player tm))
- (player (detect-on-solid player tm))
- ;; Update animation
(player (set-animation player
(cond
((not (entity-ref player #:on-ground? #f)) 'jump)
((not (zero? (entity-ref player #:vx 0))) 'walk)
(else 'idle))))
- (player (animate-entity player player-animations)))
- ;; Update facing direction
- (let ((player (if (< (entity-ref player #:vx 0) 0)
- (entity-set player #:facing -1)
- (entity-set player #:facing 1))))
- (game-scene-set! game
- (update-scene scene entities: (list player)))))))
+ (player (animate-entity player player-animations))
+ (player (if (< (entity-ref player #:vx 0) 0)
+ (entity-set player #:facing -1)
+ (entity-set player #:facing 1))))
+ (game-scene-set! game
+ (update-scene scene entities: (list player))))))
#+end_src
-Note the let*-chaining pattern: each update builds on the previous result, keeping the data flow clear and each step testable. The single ~game-scene-set!~ at the boundary stores the final scene back on the game struct.
+Import =*jump-force*= from =downstroke-physics= (or use a literal jump impulse for =#:ay=). The single ~game-scene-set!~ stores the scene after game logic; motion and =#:on-ground?= come from =default-engine-update=.