diff options
| author | Gene Pasquet <dev@etenil.net> | 2026-04-08 07:08:54 +0100 |
|---|---|---|
| committer | Gene Pasquet <dev@etenil.net> | 2026-04-08 07:08:54 +0100 |
| commit | afc30a12e25215ff5e9226c3b4f8fd127d9a4d68 (patch) | |
| tree | f736393fb8ebfd8982a4b79310a08c57ee430ff0 /docs/entities.org | |
| parent | 9e8b75f9949259ef01942cd3717b79b044efddf7 (diff) | |
Move the engine-update to the scene
Diffstat (limited to 'docs/entities.org')
| -rw-r--r-- | docs/entities.org | 59 |
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=. |
