aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorGene Pasquet <dev@etenil.net>2026-04-08 00:30:11 +0100
committerGene Pasquet <dev@etenil.net>2026-04-08 00:30:11 +0100
commitf8cc4a748bb8b6431a1023a876745b1bb473eb19 (patch)
treeaf708ac1138ee17d35d9b1ba46ec8b56acaccedb /docs
parentcfddc2f180552afdb080968f847018c5a223b41a (diff)
Support entity groups
Diffstat (limited to 'docs')
-rw-r--r--docs/api.org18
-rw-r--r--docs/entities.org15
2 files changed, 32 insertions, 1 deletions
diff --git a/docs/api.org b/docs/api.org
index 1f15945..45593e4 100644
--- a/docs/api.org
+++ b/docs/api.org
@@ -237,6 +237,14 @@ Example:
; Each entity is passed through increment-x, then through apply-gravity
#+end_src
+** ~scene-sync-groups!~
+
+#+begin_src scheme
+(scene-sync-groups! scene)
+#+end_src
+
+For every entity with ~#:group-id~ that is not an origin (~#:group-origin?~ is false), sets ~#:x~ and ~#:y~ to the corresponding origin’s position plus that entity’s ~#:group-local-x~ and ~#:group-local-y~. Origins are read from ~scene-entities~, so after a tween or other motion that returns a *new* origin plist, replace that origin in the scene’s list (match on ~#:group-id~ / ~#:group-origin?~) before calling ~scene-sync-groups!~. Call after updating origin positions and before per-entity physics so platforms and collisions see a consistent pose. Returns the scene.
+
** ~scene-filter-entities~
#+begin_src scheme
@@ -1233,7 +1241,7 @@ Creates an SDL2 texture from the tileset image embedded in a tilemap struct. Use
(load-prefabs filename engine-mixin-table user-hooks)
#+end_src
-Loads a prefab definition file and returns a ~prefab-registry~ struct. The file must contain a Scheme expression with ~mixins~ and ~prefabs~ sections (see ~docs/entities.org~).
+Loads a prefab definition file and returns a ~prefab-registry~ struct. The file must contain a Scheme expression with ~mixins~ and ~prefabs~ sections; an optional ~group-prefabs~ section defines multi-entity assemblies (see ~docs/entities.org~).
| Parameter | Type | Description |
|-----------|------|-------------|
@@ -1263,6 +1271,14 @@ Reloads the prefab file that the registry was originally loaded from. Returns a
Looks up a prefab by type symbol in the registry and returns a fresh entity plist at the given position and size. Returns ~#f~ if the type is not registered. If the resulting entity has an ~#:on-instantiate~ hook, it is called with the entity before returning.
+** ~instantiate-group-prefab~
+
+#+begin_src scheme
+(instantiate-group-prefab registry type origin-x origin-y)
+#+end_src
+
+Looks up a *group prefab* by type symbol and returns a list ~(origin member ...)~: one origin entity plus one entity per part. Optional group-level flags ~#:pose-only-origin?~ and ~#:static-parts?~ select origin/part profiles (see ~docs/entities.org~); defaults are ~#f~ (physics-driving origin, non-static parts). Each instance receives a fresh gensym ~#:group-id~ shared by the origin and all members. Returns ~#f~ if the type is not in ~group-prefabs~. After moving origins (tween and/or physics), ensure updated origins are stored in the scene’s entity list, then call ~scene-sync-groups!~ so member ~#:x~ / ~#:y~ match ~origin + #:group-local-x/y~.
+
** ~tilemap-objects->entities~
#+begin_src scheme
diff --git a/docs/entities.org b/docs/entities.org
index a29ebf6..3cdae6e 100644
--- a/docs/entities.org
+++ b/docs/entities.org
@@ -123,6 +123,21 @@ The engine recognizes these standard keys. Use them to integrate with the physic
| ~#:anim-name~ | symbol | Currently active animation name, e.g., ~'walk~, ~'jump~. Set with ~set-animation~; reset by ~animate-entity~. |
| ~#:anim-frame~ | integer | Current frame index within the animation (0-indexed). Updated automatically by ~animate-entity~. |
| ~#:anim-tick~ | integer | Tick counter for frame timing (0 to ~#:duration - 1~). Incremented by ~animate-entity~; resets when frame advances. |
+| ~#:group-id~ | symbol | Shared id for one rigid assembly (from ~instantiate-group-prefab~). All parts and the origin share the same symbol. |
+| ~#:group-origin?~ | boolean | When ~#t~, this entity is the assembly’s pose origin; world ~#:x~ / ~#:y~ drive the group. Members should not set this. |
+| ~#:group-local-x~, ~#:group-local-y~ | number | Offset from the origin’s top-left corner; members’ world position is origin + local (updated by ~scene-sync-groups!~). |
+| ~#:skip-render~ | boolean | When ~#t~, ~render-scene!~ skips drawing this entity (used for invisible origins). |
+
+* Entity groups (prefab assemblies)
+
+A **group prefab** describes one *origin* entity plus several *parts* with local offsets. Data lives in the optional ~group-prefabs~ section of the prefab file (alongside ~mixins~ and ~prefabs~). Each group entry has the shape ~(name #:type-members SYMBOL #:parts (part ...) ...)~ with two optional flags:
+
+- ~#:pose-only-origin?~ — when ~#t~ (typical for tweened platforms), the origin is invisible, does not run physics pipelines, and is driven by tweens or scripts. When ~#f~ (default), the origin uses a small *physics-driving* profile (~#:gravity? #t~, no ~#:skip-pipelines~): integrate the origin like a mover, then call ~scene-sync-groups!~ so parts stay glued as a rigid body. For that case, set ~#:origin-width~ and ~#:origin-height~ to the full assembly size (same box as the combined parts); otherwise the origin stays 0×0 and tile collision only sees a point at the reference corner, which can leave the raft overlapping solid floor tiles.
+- ~#:static-parts?~ — when ~#t~, each part gets static rigid-body defaults (no gravity on parts; pose comes from the origin). When ~#f~ (default), parts only have what you put in each part plist.
+
+Each ~part~ is a plist using ~#:local-x~ / ~#:local-y~ (or ~#:group-local-x~ / ~#:group-local-y~) and the usual ~#:width~, ~#:height~, ~#:tile-id~, physics keys, etc.
+
+Use ~(instantiate-group-prefab registry 'name origin-x origin-y)~ from ~downstroke-prefabs~ to obtain ~(origin member ...)~. Append all of them to the scene. After moving origins (tweens and/or physics), ensure updated origins are in ~scene-entities~, then call ~(scene-sync-groups! scene)~ so every part’s ~#:x~ / ~#:y~ matches the origin plus local offsets (see ~docs/api.org~ for ordering).
* Entities in Scenes