Nimbin[12]?Games / Entropie / commits / 742aa43

Entropie git · main

Entropie festival game; first steps

sdl c game entropie cmake · first commit 2026-10-10 · last commit 2026-11-02 (17 hours ago) · synced 8 hours ago

C 88.5% Markdown 9.1% GLSL 2.3%
git clone https://git.christianimmanuel.de/games/Entropie.gitwget https://git.christianimmanuel.de/games/Entropie/archive/Entropie.tar.gz

entropie 2.27.0: a hand on the bank

Christian Immanuel · 2026-10-21 07:18 · 742aa433e306b967244ddf6faa8b898b0e40bc71

- Walking up a steep bank you bend forward and put a hand down on the
  slope ahead (everybody with a hand free)
- An NPC told to get out of the way while climbing no longer gets stuck
  half way up
 commit_message.txt          | 10 +++++-----
 entropie/Makefile           |  2 +-
 entropie/STATE.md           |  9 ++++++++-
 entropie/commit_message.txt | 10 +++++-----
 entropie/src/people/ai.c    |  2 +-
 entropie/src/world/object.h |  2 ++
 entropie/src/world/world.c  | 28 ++++++++++++++++++++++++++++
 7 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/commit_message.txt b/commit_message.txt
index a49827c..e90f32f 100644
--- a/commit_message.txt
+++ b/commit_message.txt
@@ -1,6 +1,6 @@
-entropie 2.26.0: cleanup
+entropie 2.27.0: a hand on the bank
 
-- README cut down to a short overview; the full description of the game
-  moved to STATE.md ("Playing it")
-- STATE.md: the notes per version in their own section
-- Removed four functions nothing used
+- Walking up a steep bank you bend forward and put a hand down on the
+  slope ahead (everybody with a hand free)
+- An NPC told to get out of the way while climbing no longer gets stuck
+  half way up
diff --git a/entropie/Makefile b/entropie/Makefile
index 8c84107..05394ed 100644
--- a/entropie/Makefile
+++ b/entropie/Makefile
@@ -1,5 +1,5 @@
 APP       := entropie
-VERSION   := 2.26.0
+VERSION   := 2.27.0
 
 PREFIX    ?= /usr
 BINDIR    ?= $(PREFIX)/bin
diff --git a/entropie/STATE.md b/entropie/STATE.md
index 4596c89..32d9a67 100644
--- a/entropie/STATE.md
+++ b/entropie/STATE.md
@@ -621,6 +621,8 @@ and satellite pictures (about 340 x 340 m).
 - People walk round obstacles in smooth curves, no zigzag
 - Arms move around the body, never through it; carried things stay off the body
 - Steps get shorter uphill and longer downhill
+- Walking up a steep bank (the one behind the garages) you bend forward and
+  put a hand down on the slope ahead, again and again (anybody with a hand free)
 - Falls differ: straight over, knees first, twisting, or reeling back a few
   steps first; a stumble takes you over the foot that caught
 - A fall lands where there's room: a little to the side, or shorter at the
@@ -1123,6 +1125,11 @@ Round 2.26 (cleanup):
 - README cut down to a short overview (120 lines, was 800); the detailed description of everything moved here ("Playing it"). The round notes moved into this section (they were in the middle of "Behaviours"). RULES: details go into STATE.md.
 - Dead code out: `Wetness_soil`, `Wetness_water`, `Site_court`, `Shapes_wallColor` (never called).
 
+Round 2.27:
+- Up a steep bank (`world.c` scrambleHand, before Hands_update): anybody walking on bare ground where it rises SCRAMBLE_GRADE 0.8 m per m ahead, a hand free: bent forward (Hands_touch: lean, crouch to it), a hand put down SCRAMBLE_AHEAD 0.6 m (scaled) ahead on the slope (`Object.scramble_hand`, `scrambling`), left there till the body is past it, then down again further up. Checked: Toni up the bank behind the garages.
+- NPCs: a climb going on is played before anything else in their update (a warned-off climber stalled half way up: Climb_update wasn't reached).
+- Tried and dropped: NPCs taking a straight way up a bank instead of the way round - the walking map already goes straight up it where it matters.
+
 ## Open tasks
 
 Most important first.
@@ -1157,4 +1164,4 @@ Most important first.
 - Drawing many figures on a real graphics card: not measured (software GL: 300 people cost 3x the rest of the scene)
 
 ---
-State of `entropie 2.26.0 (build 183cb96)`
+State of `entropie 2.27.0 (build a2db897)`
diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt
index a49827c..e90f32f 100644
--- a/entropie/commit_message.txt
+++ b/entropie/commit_message.txt
@@ -1,6 +1,6 @@
-entropie 2.26.0: cleanup
+entropie 2.27.0: a hand on the bank
 
-- README cut down to a short overview; the full description of the game
-  moved to STATE.md ("Playing it")
-- STATE.md: the notes per version in their own section
-- Removed four functions nothing used
+- Walking up a steep bank you bend forward and put a hand down on the
+  slope ahead (everybody with a hand free)
+- An NPC told to get out of the way while climbing no longer gets stuck
+  half way up
diff --git a/entropie/src/people/ai.c b/entropie/src/people/ai.c
index 1b229a4..efff106 100644
--- a/entropie/src/people/ai.c
+++ b/entropie/src/people/ai.c
@@ -2232,6 +2232,7 @@ void Ai_update(Object *self, Object *const *objects, int count, float dt) {
         self->sitting = false;
         return;
     }
+    if (ai_climbing(self, dt)) return; /* (up or down a ladder, over an edge: that first - whatever it was for) */
     if (ai->dodge_t > 0.0f && !self->body.asleep && !self->in_tent && self->indoors <= 0.0f) { /* warned off: out of the way first */
         ai->dodge_t -= dt;
         self->sitting = false;
@@ -2255,7 +2256,6 @@ void Ai_update(Object *self, Object *const *objects, int count, float dt) {
     if (takeBack(self)) return;
     lighterManners(self, objects, count, dt);
     smokeBreak(self, objects, count, dt);
-    if (ai_climbing(self, dt)) return; /* (up or down a ladder, over an edge: that first) */
     if (stepAside(self, dt)) return;   /* (a pushed load coming at us) */
     if (ai->mode != AI_IDLE && ai->mode != AI_TABLE && !(ai->mode == AI_WORK && ai->order == ORDER_FIRE)) self->sitting = false; /* up again to do anything */
     smell(self, objects, count, dt);
diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h
index 37cd252..ef97c8f 100644
--- a/entropie/src/world/object.h
+++ b/entropie/src/world/object.h
@@ -220,6 +220,8 @@ typedef struct Object {
     float      impact;        /* speed lost in collisions during the last step */
     struct Object *touched;   /* the last thing it ran into during the last step (NULL: none, or the ground) */
     struct Object *standing_on; /* characters: what they stood on in the last step (NULL: the ground) */
+    Vec3       scramble_hand; /* characters: up a steep bank, a hand put down on it here (world.c scrambleHand) ... */
+    bool       scrambling;    /* ... doing that now */
     float      veer_side;     /* the player: drifting sideways past something lying there (share of the speed, eased) */
     bool       broken;        /* shattered bottle: only shards are left */
     int        variant;       /* trees: 1 = fruit tree; trash: what it is (the palette) */
diff --git a/entropie/src/world/world.c b/entropie/src/world/world.c
index 29d4284..281bef5 100644
--- a/entropie/src/world/world.c
+++ b/entropie/src/world/world.c
@@ -865,8 +865,36 @@ static void landFromHigh(World *world, Object *o) {
     (void)world;
 }
 
+/* Up a steep bank (walking straight up it): bent forward, a free hand put down
+   on the slope ahead, left there as the body passes, then put down again
+   further up. */
+#define SCRAMBLE_GRADE 0.8f  /* rise per m ahead from which a hand goes down */
+#define SCRAMBLE_AHEAD 0.6f  /* m (scaled) ahead it goes down ... */
+#define SCRAMBLE_LEAVE 0.15f /* ... and is taken up once the shoulders are this far past it */
+static void scrambleHand(World *world, Object *o) {
+    bool was = o->scrambling;
+    o->scrambling = false;
+    if (!o->is_character || !o->is_grounded || o->climbing || o->on_ladder || o->sitting || Body_isBusy(&o->body) ||
+        Hands_freeHand(o) < 0 || hypotf(o->body.velocity.x, o->body.velocity.z) < 0.3f) return; /* (walking up it: the body moving) */
+    const float s = o->look.height / 1.75f;
+    Vec3 f = Object_facing(o);
+    const Terrain *t = &world->terrain;
+    float here = Terrain_height(t, o->position.x, o->position.z);
+    if (fabsf(World_groundHeight(world, o->position.x, o->position.z, o->position.y + 0.3f) - here) > 0.1f) return; /* (on the bare ground) */
+    float grade = (Terrain_height(t, o->position.x + f.x * 0.5f * s, o->position.z + f.z * 0.5f * s) - here) / (0.5f * s);
+    if (grade < SCRAMBLE_GRADE) return;
+    Vec3 rel = vec3_sub(o->scramble_hand, o->position);
+    if (!was || vec3_dot(vec3(rel.x, 0.0f, rel.z), f) < SCRAMBLE_LEAVE * s) { /* (down again further up) */
+        Vec3 at = vec3_add(o->position, vec3_scale(f, SCRAMBLE_AHEAD * s));
+        o->scramble_hand = vec3(at.x, Terrain_height(t, at.x, at.z) + 0.03f, at.z);
+    }
+    o->scrambling = true;
+    Hands_touch(o, o->scramble_hand);
+}
+
 /* Hands, feet and skeleton, then carried items follow the hands. */
 static void animateCharacter(World *world, Object *o, float dt) {
+    scrambleHand(world, o);
     if (o->climbing || o->on_ladder || o->is_held) o->air_fall = 0.0f;
     else if (!o->is_grounded) o->air_fall = fmaxf(o->air_fall, -o->velocity.y);
     else if (o->air_fall > 0.0f) landFromHigh(world, o);