Entropie git · main
Entropie festival game; first steps
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.gzentropie 1.64.0: smooth ladder and climbs (no jumping feet)
- Getting on a ladder: the body eases over onto it, hands and feet go onto the rungs from where they were (feet jumped 20 cm) - Over the edge at the top of a ladder: a proper pull-up, the feet from the rungs onto the roof without snapping - Every climb starts from where the feet are; the foot height on top follows a sloping roof; the knee room blends out instead of snapping - Audit: ladder joint jumps 163 -> 65, climb test 458 -> 180; the easy 1 m climb no longer drops you off again Includes 1.63.0 (if not committed separately): - The hose melts in the fire (leaks, burns through); duct tape and the shears mend it Includes 1.62.0 (if not committed separately): - Smooth pull-ups: no hop at the end, feet and knees ease over the edge, elbows and hands taking hold blend in (audit walk: joint jumps 161 -> 58) Includes 1.61.0 (if not committed separately): - A step ladder in the tool room: stands on its own, at a wall with its back to it; climb onto the wall from its top Includes 1.60.0 (if not committed separately): - A folding ladder (two 2.5 m halves on a hinge, 5 m open) beside the telescopic one; one click at a wall unfolds it and leans it there Includes 1.59.0 (if not committed separately): - Stepping up onto blocks above knee high; set moves and jumps only for things standing on the ground in front of you Includes 1.58.0 (if not committed separately): - Walking over knee-high things is one smooth set move that always finishes; at a run: jump up onto blocks, catch climbable edges
entropie/Makefile | 2 +- entropie/STATE.md | 6 +++--- entropie/commit_message.txt | 21 +++++++++++++-------- entropie/src/game/game.h | 1 + entropie/src/game/game_actions.c | 38 +++++++++++++++++++++++++++++--------- entropie/src/world/ladder.c | 24 ++++++++++++++++++++++-- entropie/src/world/object.h | 1 + 7 files changed, 70 insertions(+), 23 deletions(-) diff --git a/entropie/Makefile b/entropie/Makefile index a9d96b6..7ef31b1 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 1.63.0 +VERSION := 1.64.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/STATE.md b/entropie/STATE.md index 1c378a3..daa8fb8 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -84,7 +84,7 @@ Talk topics: offer, ask, suggest, where (new woodpile spot), ask for a hand, ask - **Bushes**: trying to get over one ends in it, twigs snap - **Half way over something**: from when a foot is well into a step over something (lifted 12 cm+, 15 % into the step) until the body is over there (6 cm behind where that foot came down, at most 20 cm past it), you're crossing (`body.c` crossOver): stopping (or slower than 0.3 m/s) the body carries on over it at 0.6 m/s (`physics.c` carryOver); the foot over there stays down, the other comes after. Walking back takes you back. Standing still half over costs energy (2.5 %/s, a leg held up 6 %/s; less sporty, more); worn out, held longer than 1-6 s (fitness, energy) or legs over 0.95 m apart: you're made to go over; still stuck 1.5 s later: you fall (`world.c` halfOver) - **Sure-footedness**: one factor (`world.c`, unsure: ~0.2 sporty and careful .. ~1 average .. ~2.7 clumsy and unfit) scales every trip, slip, scrape and run-into, and how bad it gets; clumsy and unfit, you also stumble over your own feet jogging or running -- **Climbing**: hand on it (up to 1.35 m), hang and pull up (higher, both hands free), jump for the edge; ladder up and down, over the edge at the top. Walking up to something 0.7–2 m high, the hands go onto its edge first; pulling up, the feet push against the face below the edge, then the right knee and foot come over onto it, then the left (scripted in `game_actions.c`, climbFeet); knees bend up. A foot below the edge goes back until its (forward bent) knee is 8 cm clear of the face (`game_actions.c`, kneeClear); onto something low (under 1 m) the body rises quickly first, so the knee comes up above the edge. Walking up to anything higher than 0.5 m, the feet stay 0.35 m back from it (room for the knee; `body.c`, footSpot). Climb test: 0.8-1.5 m, walking or jumping, legs at most 5 cm into it (was 19 cm at 0.8 m). High pull-ups: pulled up till the arms press down (hips near the edge), then the knee comes up and you rise; the hands go on ahead onto the top and stay there, the back bends over the edge as far as it takes to keep them on it (body_pose.c, reach_bend). Jumping: holding Space (or W) grabs an edge the hands reach (about 2.4 m); up to 0.35 m higher, the fingertips touch it ("Just out of reach"); hands go up wide, then onto the edge. Smooth pull-ups (audit walk: joint jumps 161 -> 58, the worst 22 -> 10 cm): the climb ends at the highest point under the body's footprint (where the physics stands you: no hop), each foot lands on what's under it, no replanting at the end (the feet are there already; body velocity zeroed: no stride ahead); feet over the edge over longer windows (lead 0.56-0.86, trail 0.74-1.0 of a high climb); kneeClear eases the foot back in 1 cm steps and lets go gradually as the knee comes over the top; the knee pole for pulling up eases in and out (`pull_knees`); an elbow swinging up over an edge blends between the two solves (no flip at half way); a hand taking hold eases out of the arm's "move out" (`arm_hold`) +- **Climbing**: hand on it (up to 1.35 m), hang and pull up (higher, both hands free), jump for the edge; ladder up and down, over the edge at the top. Walking up to something 0.7–2 m high, the hands go onto its edge first; pulling up, the feet push against the face below the edge, then the right knee and foot come over onto it, then the left (scripted in `game_actions.c`, climbFeet); knees bend up. A foot below the edge goes back until its (forward bent) knee is 8 cm clear of the face (`game_actions.c`, kneeClear); onto something low (under 1 m) the body rises quickly first, so the knee comes up above the edge. Walking up to anything higher than 0.5 m, the feet stay 0.35 m back from it (room for the knee; `body.c`, footSpot). Climb test: 0.8-1.5 m, walking or jumping, legs at most 5 cm into it (was 19 cm at 0.8 m). High pull-ups: pulled up till the arms press down (hips near the edge), then the knee comes up and you rise; the hands go on ahead onto the top and stay there, the back bends over the edge as far as it takes to keep them on it (body_pose.c, reach_bend). Jumping: holding Space (or W) grabs an edge the hands reach (about 2.4 m); up to 0.35 m higher, the fingertips touch it ("Just out of reach"); hands go up wide, then onto the edge. Smooth pull-ups (audit walk: joint jumps 161 -> 58, the worst 22 -> 10 cm): the climb ends at the highest point under the body's footprint (where the physics stands you: no hop), each foot lands on what's under it, no replanting at the end (the feet are there already; body velocity zeroed: no stride ahead); feet over the edge over longer windows (lead 0.56-0.86, trail 0.74-1.0 of a high climb); kneeClear eases the foot back in 1 cm steps and lets go gradually as the knee comes over the top; the knee pole for pulling up eases in and out (`pull_knees`); an elbow swinging up over an edge blends between the two solves (no flip at half way); a hand taking hold eases out of the arm's "move out" (`arm_hold`). Every climb starts from where the feet are (`noteFeet`, eased in over the first 15 %); each foot's height on top is taken under where it ends up (clamped to 0.3 under / 0.15 over the top: roofs slope); below the edge the knee room (kneeClear) blends out as the foot gets over the face or above the top. Ladder: getting on, the body eases over onto it (`ladder_shift`, 1.6 m/s) and hands and feet go onto the rungs from where they are; over the edge at the top is a pull-up (1.6 s, `climb_face` where the top rests). Audit ladder: joint jumps 163 -> 65; climb test 458 -> 180 (the easy 1 m climb no longer drops you off again) - **Drink and the rest**: sips, burps, sways, veers, sick, passes out, sleeps it off; pees (stream lands on the real ground, soaks in or puddles) - **Throwing**: underhand lob, overhand when wound up long enough - **Carrying one-handed**: hangs at the side by its top (a bag by its neck), wide things with the arm a little out; only long things (ladder, logs, axe) stop you at walls, bags and bottles squeeze by @@ -137,7 +137,7 @@ A cell grid of the site (2 m cells, `src/world/grid.c`, built once a frame) answ Most important first. **Bugs** -- Joint jumps left in the audit: jog+stop 191, sprint 373 (worst 28 cm), ladder 163 (27 cm) - running into things and the ladder climb; walk is down to 58 (10 cm) +- Joint jumps left in the audit: jog+stop 191, sprint 358 (worst 28 cm) - running into things; ladder 65: stepping off at the bottom (feet replanted, 18 cm), taking it down (the hand flies up to the grip), toes after getting up on the roof **Body and moving** - Obstacle approach, still to do: prefer a step in between on top of something stable (or unstable, if clumsy) over a long stride; NPCs: pull up or jump onto things on their own (the player does when running at them) @@ -162,4 +162,4 @@ Most important first. - The walking map rebuild takes ~9 ms when fixed things change (a felled tree) --- -State of `entropie 1.63.0 (build 1f95dd5)` +State of `entropie 1.64.0 (build 55638db)` diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt index 2eb3320..b6d185d 100644 --- a/entropie/commit_message.txt +++ b/entropie/commit_message.txt @@ -1,12 +1,17 @@ -entropie 1.63.0: the hose melts in the fire; duct tape and shears mend it +entropie 1.64.0: smooth ladder and climbs (no jumping feet) -- Lying in or by a burning fire the hose gets hot (glows), melts and - leaks (less water, a shorter arc; it squirts onto the ground there), - then burns through (nothing at the nozzle, the loose end can be taken - anywhere) -- Duct tape (new, on the workbench) clicked at a melted bit tapes it up -- Shears clicked at a burnt-through bit cut it out and join the ends: - the hose gets shorter (and reaches less far) +- Getting on a ladder: the body eases over onto it, hands and feet go + onto the rungs from where they were (feet jumped 20 cm) +- Over the edge at the top of a ladder: a proper pull-up, the feet from + the rungs onto the roof without snapping +- Every climb starts from where the feet are; the foot height on top + follows a sloping roof; the knee room blends out instead of snapping +- Audit: ladder joint jumps 163 -> 65, climb test 458 -> 180; the easy + 1 m climb no longer drops you off again + +Includes 1.63.0 (if not committed separately): +- The hose melts in the fire (leaks, burns through); duct tape and the + shears mend it Includes 1.62.0 (if not committed separately): - Smooth pull-ups: no hop at the end, feet and knees ease over the edge, diff --git a/entropie/src/game/game.h b/entropie/src/game/game.h index fae2f7c..c1f18e2 100644 --- a/entropie/src/game/game.h +++ b/entropie/src/game/game.h @@ -53,6 +53,7 @@ typedef struct { float brace_hold; /* hands on an edge you walked up to: kept there this much longer ... */ Vec3 brace_grip; /* ... here */ float climb_face; /* how far ahead of where you started the face of it is (m) */ + Vec3 climb_ankle0[2], climb_toe0[2]; /* where the feet were when the climb started (eased from there) */ Object *putting_up; /* the ladder you are putting up (hands on it, standing still) */ } Game; diff --git a/entropie/src/game/game_actions.c b/entropie/src/game/game_actions.c index a04fb38..3180c32 100644 --- a/entropie/src/game/game_actions.c +++ b/entropie/src/game/game_actions.c @@ -61,6 +61,14 @@ static void reachForIt(Game *game, Object *p, float s) { } } +/* Where the feet are as a climb starts: they go from there (no jump onto the climb's own path). */ +static void noteFeet(Game *game, const Object *p) { + for (int i = 0; i < 2; i++) { + game->climb_ankle0[i] = p->body.feet[i].ankle; + game->climb_toe0[i] = p->body.feet[i].toe; + } +} + /* Hands on the edge: climb up. Easy ledges with a hand on them; higher up (as far as the hands reach, standing or jumping) hanging on and pulling up. */ static bool startClimb(Game *game, float top, Vec3 probe) { @@ -116,6 +124,7 @@ static bool startClimb(Game *game, float top, Vec3 probe) { game->climb_time = (hard ? 1.3f + 0.7f * fmaxf(rise / s - CLIMB_EASY, 0.0f) : 0.6f + rise * 0.6f) / fmaxf(vigor, 0.4f); game->climb_t = 0.0f; game->climb_push = 0.0f; + noteFeet(game, p); p->climbing = true; p->velocity = vec3_zero(); if (hard) p->needs.stamina = fmaxf(0.0f, p->needs.stamina - 0.04f * rise / s); @@ -172,10 +181,10 @@ static void climbFeet(Game *game, Object *p, float t, bool high, float s) { /* on top: a little over the edge, or under you once you're up there */ float along_top = fmaxf(face + 0.2f * s, root_along); float y_top = top + 0.08f * s; - { /* (on what's right under that foot up there - the top isn't always level) */ - Vec3 q = vec3_add(a, vec3_add(vec3_scale(f, along_top), vec3_scale(side, sign * 0.11f * s))); - float g = World_groundHeight(&game->world, q.x, q.z, top + 0.3f * s); - if (g > top - 0.25f * s && g < top + 0.05f * s) y_top = g + 0.08f * s; + { /* (on what's under that foot where it ends up - the top isn't always level; the same all along: no jumps) */ + Vec3 q = vec3_add(b, vec3_scale(side, sign * 0.11f * s)); + float g = World_groundHeight(&game->world, q.x, q.z, top + 1.0f * s); /* (from well above: a roof slope may rise there) */ + if (g > top - 0.6f * s) y_top = clampf(g, top - 0.3f * s, top + 0.15f * s) + 0.08f * s; /* (clamped, not cut off: no jumps on a slope) */ } /* up first (clear of the edge), then over */ float up = smoothstepf(0.0f, 0.6f, u), across = smoothstepf(0.35f, 1.0f, u); @@ -185,15 +194,21 @@ static void climbFeet(Game *game, Object *p, float t, bool high, float s) { } float along = lerpf(along_below, along_top, across); float yy = lerpf(y_below, y_top, up) + 0.12f * s * sinf(PI_F * u); - if (along > face - 0.05f * s) yy = fmaxf(yy, y_top); /* (over it: on it, not in it) */ - else along = kneeClear(along, yy, root_along, p->position.y, face, top, s); + /* over it: on it, not in it; below the edge: the knee kept clear of the face - one into the other, no jump */ + float over = smoothstepf(face - 0.14f * s, face - 0.03f * s, along); + yy = lerpf(yy, fmaxf(yy, y_top), over); + /* (the foot up over the top already needs no room for the knee) */ + float free = fmaxf(over, smoothstepf(top - 0.04f * s, top + 0.08f * s, yy)); + if (free < 1.0f) along = lerpf(kneeClear(along, yy, root_along, p->position.y, face, top, s), along, free); Vec3 ankle = vec3_add(a, vec3_add(vec3_scale(f, along), vec3_scale(side, sign * 0.11f * s))); ankle.y = yy; /* toes: at the wall pointing into it (on the toes), on top flat ahead */ Vec3 toe = vec3_add(ankle, vec3_scale(f, 0.14f * s)); toe.y = ankle.y - lerpf(0.06f, 0.05f, across) * s; - p->climb_ankle[i] = ankle; - p->climb_toe[i] = toe; + /* (from where they were when it started: eased onto the climb's path) */ + float onto = smoothstepf(0.0f, 0.15f, t); + p->climb_ankle[i] = vec3_lerp(game->climb_ankle0[i], ankle, onto); + p->climb_toe[i] = vec3_lerp(game->climb_toe0[i], toe, onto); } p->climb_feet = true; } @@ -345,6 +360,7 @@ void game_climbLadder(Game *game, const Input *in, float dt) { if (game->message_time <= 0.0f) say(game, "Nothing to stand on up there"); return; } + noteFeet(game, p); Ladder_getOff(p); p->climbing = true; /* pulled over the edge like any ledge (see game_climb) */ game->climb_from = p->position; @@ -352,7 +368,11 @@ void game_climbLadder(Game *game, const Input *in, float dt) { game->climb_edge = edge; game->climb_hang = p->position.y; /* (already up there: no hanging on) */ game->climb_across = vec3_normalize(vec3_cross(Object_facing(p), vec3(0.0f, 1.0f, 0.0f))); - game->climb_time = 1.0f; + { /* (the face of it: where the ladder's top rests) */ + Vec3 to_edge = vec3_sub(edge, p->position); + game->climb_face = fmaxf(0.05f, -(to_edge.x * n.x + to_edge.z * n.z)); + } + game->climb_time = 1.6f; /* (pulled up over it like a high ledge: from the ladder the feet start well below) */ game->climb_t = 0.0f; say(game, "You climb over the edge"); } diff --git a/entropie/src/world/ladder.c b/entropie/src/world/ladder.c index 6377464..2fb14e6 100644 --- a/entropie/src/world/ladder.c +++ b/entropie/src/world/ladder.c @@ -14,6 +14,7 @@ #define CLIMB_SPEED 0.8f /* meters along the ladder per second */ #define HANDS_ABOVE 1.05f /* hands this far above the feet (along the ladder) */ #define MOUNT_REACH 1.2f +#define LADDER_ONTO 1.6f /* m/s the body moves over onto it, getting on */ #define RAISE_ANGLE 1.05f /* a raised ladder: this steep (rad) looking straight ahead ... */ #define RAISE_FOLLOW 0.9f /* ... steeper looking up, flatter looking down ... */ #define RAISE_LOW 0.75f @@ -446,7 +447,7 @@ static float highest(const Object *l) { static void place(Object *who) { const Object *l = who->on_ladder; Vec3 n = l->lean_normal; - who->position = vec3_add(pointAt(l, who->ladder_at), vec3_scale(n, STAND_OUT)); + who->position = vec3_add(vec3_add(pointAt(l, who->ladder_at), vec3_scale(n, STAND_OUT)), who->ladder_shift); who->rotation.y = atan2f(-n.z, -n.x) + PI_F / 2.0f; who->velocity = who->movement = vec3_zero(); who->is_grounded = false; @@ -454,15 +455,30 @@ static void place(Object *who) { } void Ladder_mount(Object *who, Object *l, bool at_top) { + /* hands and feet go onto the rungs from where they are now (eased, see limbTo) */ + const Vec3 f = Object_facing(who); + for (int i = 0; i < 2; i++) who->ladder_from[i] = who->body.feet[i].ankle; + who->ladder_from[2] = Figure_toWorld(who->position, f, who->skeleton.joints[JOINT_HAND_L]); + who->ladder_from[3] = Figure_toWorld(who->position, f, who->skeleton.joints[JOINT_HAND_R]); + for (int k = 0; k < 4; k++) { + who->ladder_to[k] = who->ladder_from[k]; + who->ladder_t[k] = 1.0f; + } + who->ladder_limbs_ok = true; who->on_ladder = l; who->ladder_at = at_top ? highest(l) : 0.0f; - who->ladder_limbs_ok = false; who->climbing = true; who->sitting = false; + const Vec3 was = who->position; + who->ladder_shift = vec3_zero(); place(who); + who->ladder_shift = vec3_sub(was, who->position); /* (from where you stood onto it: eased, see Ladder_climb) */ + who->position = was; + Object_syncColliders(who); } void Ladder_getOff(Object *who) { + who->ladder_shift = vec3_zero(); who->on_ladder = NULL; who->climbing = false; } @@ -471,6 +487,10 @@ int Ladder_climb(Object *who, float input, float dt) { Object *l = who->on_ladder; if (!l) return CLIMB_OFF_BOTTOM; who->ladder_at += input * CLIMB_SPEED * Object_vigor(who) * dt; + { /* just got on: the body eases over onto it */ + float left = vec3_length(who->ladder_shift), step = LADDER_ONTO * dt; + who->ladder_shift = left > step ? vec3_scale(who->ladder_shift, (left - step) / left) : vec3_zero(); + } if (who->ladder_at < 0.0f) { /* down: step off backwards onto the ground */ Vec3 off = vec3_add(l->position, vec3_scale(l->lean_normal, 0.45f)); Ladder_getOff(who); diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index 2fb3d92..b6e4275 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -224,6 +224,7 @@ typedef struct Object { float ladder_at; /* ... with the feet this far up along it */ Vec3 ladder_from[4], ladder_to[4]; /* ... feet and hands on their way from rung to rung */ float ladder_t[4]; + Vec3 ladder_shift; /* ... the body still this far from its place on it (just got on: eases away) */ bool ladder_limbs_ok; /* Characters only */