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.65.0: smooth off the ladder and taking it down
- Stepping off a ladder at the bottom: a short step back, one foot down after the other (the feet jumped 18 cm) - Taking a leaning ladder down: the hand reaches for the rail at chest height (it reached for the middle of the ladder, high up the wall) and the ladder stays as steep as it leaned - Getting up onto a roof from a ladder: no hop at the end - Audit ladder: joint jumps 65 -> 45 (163 in 1.63) Includes 1.64.0 (if not committed separately): - Smooth ladder and climbs: getting on, over the edge at the top, feet from where they are; 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 | 23 ++++++++++--------- entropie/src/game/game_actions.c | 28 +++++++++++++---------- entropie/src/people/hands.c | 2 ++ entropie/src/world/ladder.c | 48 +++++++++++++++++++++++++++++++++------- entropie/src/world/object.h | 2 ++ 7 files changed, 77 insertions(+), 34 deletions(-) diff --git a/entropie/Makefile b/entropie/Makefile index 7ef31b1..0090557 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 1.64.0 +VERSION := 1.65.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/STATE.md b/entropie/STATE.md index daa8fb8..6ef0b2d 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`). 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) +- **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; the body ends at its stand height on the roof, `standHeight`); stepping off at the bottom is a 0.6 s step back, one foot down after the other, the hands let go half way (`ladder_off`); taking a leaning ladder down, the hand reaches for its rail at chest height (not its middle up the wall) and it stays held as steep as it leaned. Audit ladder: joint jumps 163 -> 45; 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 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 +- Joint jumps left in the audit: jog+stop 191, sprint 358 (worst 28 cm) - running into things; ladder 45: toes on the sloping roof (a landing step's toes snap onto the slope, 16 cm; blending them in made all walking worse), toes turning onto the rungs getting on from the top (14 cm) **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.64.0 (build 55638db)` +State of `entropie 1.65.0 (build 7f81926)` diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt index b6d185d..67cd231 100644 --- a/entropie/commit_message.txt +++ b/entropie/commit_message.txt @@ -1,13 +1,16 @@ -entropie 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 +entropie 1.65.0: smooth off the ladder and taking it down + +- Stepping off a ladder at the bottom: a short step back, one foot down + after the other (the feet jumped 18 cm) +- Taking a leaning ladder down: the hand reaches for the rail at chest + height (it reached for the middle of the ladder, high up the wall) and + the ladder stays as steep as it leaned +- Getting up onto a roof from a ladder: no hop at the end +- Audit ladder: joint jumps 65 -> 45 (163 in 1.63) + +Includes 1.64.0 (if not committed separately): +- Smooth ladder and climbs: getting on, over the edge at the top, feet + from where they are; 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 diff --git a/entropie/src/game/game_actions.c b/entropie/src/game/game_actions.c index 3180c32..a2221b7 100644 --- a/entropie/src/game/game_actions.c +++ b/entropie/src/game/game_actions.c @@ -69,6 +69,20 @@ static void noteFeet(Game *game, const Object *p) { } } +/* Where the body will stand up there: the highest point under its footprint, + as the physics stands you - no hop once up. */ +static float standHeight(Game *game, const Object *p, Vec3 to, float s) { + const Collider *pc = &p->colliders[0]; + float under = to.y; + for (int cx = -1; cx <= 1; cx += 2) + for (int cz = -1; cz <= 1; cz += 2) { + Vec3 q = vec3_add(to, vec3_add(vec3_scale(pc->axes[0], (float)cx * pc->half_extents.x), vec3_scale(pc->axes[2], (float)cz * pc->half_extents.z))); + float g = World_groundHeight(&game->world, q.x, q.z, to.y + 0.4f * s); + if (g > under && g < to.y + 0.3f * s) under = g; + } + return under; +} + /* 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) { @@ -94,17 +108,7 @@ static bool startClimb(Game *game, float top, Vec3 probe) { Vec3 to = vec3(probe.x + f.x * 0.25f * s, top, probe.z + f.z * 0.25f * s); to.y = World_groundHeight(&game->world, to.x, to.z, top + 0.6f * s); /* (a sloping roof goes on up) */ if (to.y < top - 0.3f || to.y > top + 0.4f * s) to.y = top; - { /* (where the body will stand up there: the highest point under its footprint - no hop once up) */ - const Collider *pc = &p->colliders[0]; - float under = to.y; - for (int cx = -1; cx <= 1; cx += 2) - for (int cz = -1; cz <= 1; cz += 2) { - Vec3 q = vec3_add(to, vec3_add(vec3_scale(pc->axes[0], (float)cx * pc->half_extents.x), vec3_scale(pc->axes[2], (float)cz * pc->half_extents.z))); - float g = World_groundHeight(&game->world, q.x, q.z, to.y + 0.4f * s); - if (g > under && g < to.y + 0.3f * s) under = g; - } - to.y = under; - } + to.y = standHeight(game, p, to, s); game->climb_from = p->position; game->climb_to = to; @@ -364,7 +368,7 @@ void game_climbLadder(Game *game, const Input *in, float dt) { Ladder_getOff(p); p->climbing = true; /* pulled over the edge like any ledge (see game_climb) */ game->climb_from = p->position; - game->climb_to = vec3(over.x, top, over.z); + game->climb_to = vec3(over.x, standHeight(game, p, vec3(over.x, top, over.z), p->look.height / 1.75f), over.z); 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))); diff --git a/entropie/src/people/hands.c b/entropie/src/people/hands.c index 244d9f3..c4a2568 100644 --- a/entropie/src/people/hands.c +++ b/entropie/src/people/hands.c @@ -848,6 +848,8 @@ void Hands_update(Object *who, float dt) { Vec3 target = twoHanded(h) ? vec3_add(c, vec3_scale(right, sign * (extentAlong(item, right) + 0.01f))) : vec3_add(c, vec3(0.0f, extentAlong(item, UP), 0.0f)); + if (!twoHanded(h) && (item->type == OBJ_LADDER || target.y > who->position.y + 1.5f * s)) /* (long, or up high: where it's in reach) */ + target = closestPoint(item, vec3(target.x, who->position.y + 1.0f * s, target.z)); b->hand_active[i] = true; b->hand_target[i] = target; b->crouch_goal = fmaxf(b->crouch_goal, crouchFor(who, target.y)); diff --git a/entropie/src/world/ladder.c b/entropie/src/world/ladder.c index 2fb14e6..507497f 100644 --- a/entropie/src/world/ladder.c +++ b/entropie/src/world/ladder.c @@ -15,6 +15,7 @@ #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 STEP_OFF_TIME 0.6f /* seconds to step off at the bottom */ #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 @@ -433,6 +434,7 @@ bool Ladder_take(Object *who, Object *l) { l->lean_top = 0.0f; l->rest_time = 0.0f; if (stepLadder(l)) l->extend_goal = 0.0f; /* (folds up as you take it) */ + else l->raised = clampf(asinf(clampf(upAlong(l).y, -1.0f, 1.0f)), 0.15f, RAISE_HIGH); /* (held up as steep as it leaned: no swing down and up again) */ return Hands_pickUpObject(who, hand, l); } @@ -477,8 +479,12 @@ void Ladder_mount(Object *who, Object *l, bool at_top) { Object_syncColliders(who); } +/* Where you stand once off it at the bottom. */ +static Vec3 offSpot(const Object *l) { return vec3_add(l->position, vec3_scale(l->lean_normal, 0.45f)); } + void Ladder_getOff(Object *who) { who->ladder_shift = vec3_zero(); + who->ladder_off = 0.0f; who->on_ladder = NULL; who->climbing = false; } @@ -486,19 +492,28 @@ void Ladder_getOff(Object *who) { int Ladder_climb(Object *who, float input, float dt) { Object *l = who->on_ladder; if (!l) return CLIMB_OFF_BOTTOM; + if (who->ladder_off > 0.0f) { /* stepping off backwards onto the ground, one foot after the other */ + who->ladder_off = fminf(1.0f, who->ladder_off + dt / STEP_OFF_TIME); + Vec3 off = offSpot(l); + who->position = vec3_lerp(who->ladder_off_from, off, smoothstepf(0.0f, 1.0f, who->ladder_off)); + Object_syncColliders(who); + if (who->ladder_off < 1.0f) return CLIMB_ON; + Ladder_getOff(who); + who->is_grounded = true; + who->body.velocity = vec3_zero(); /* (the feet are down there already: they stay) */ + 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); - who->position = off; - who->is_grounded = true; - who->body.replant = true; - Object_syncColliders(who); - return CLIMB_OFF_BOTTOM; + if (who->ladder_at < 0.0f) { /* down: step off backwards onto the ground (see above) */ + who->ladder_at = 0.0f; + who->ladder_off = 1e-4f; + who->ladder_off_from = who->position; + for (int i = 0; i < 2; i++) who->ladder_from[i] = who->body.feet[i].ankle; /* (the feet go down from there) */ + return CLIMB_ON; } float top = highest(l); bool at_edge = who->ladder_at >= top && input > 0.0f && l->lean_top > 0.0f; @@ -550,6 +565,7 @@ void Ladder_poseHands(Object *who, float dt) { if (!l) return; const float s = who->look.height / 1.75f; Vec3 n = l->lean_normal, across = vec3_normalize(vec3_cross(n, UP)); + if (who->ladder_off > 0.5f) return; /* (stepping off: let go) */ int k = rungAbove(l, who->ladder_at + HANDS_ABOVE * s); for (int h = 0; h < 2; h++) { /* hand over hand: one a rung above the other, swapping as you go */ @@ -571,6 +587,22 @@ void Ladder_poseFeet(Object *who, float dt) { if (!l) return; const float s = who->look.height / 1.75f; Vec3 n = l->lean_normal, across = vec3_normalize(vec3_cross(n, UP)); + if (who->ladder_off > 0.0f) { /* stepping off: one foot down onto the ground, then the other */ + for (int i = 0; i < 2; i++) { + Foot *foot = &who->body.feet[i]; + float side = i == 0 ? 1.0f : -1.0f; + float u = smoothstepf(i == 0 ? 0.0f : 0.4f, i == 0 ? 0.6f : 1.0f, who->ladder_off); + Vec3 down = vec3_add(offSpot(l), vec3_add(vec3_scale(across, side * 0.11f * s), vec3_scale(n, -0.05f * s))); + down.y = l->position.y + 0.075f * s; /* (ankle height over the ground) */ + Vec3 at = vec3_lerp(who->ladder_from[i], down, u); + at.y += 0.08f * s * sinf(PI_F * u); /* (lifted off the rung, set down) */ + foot->ankle = at; + foot->dir = vec3_scale(n, -1.0f); + foot->toe = vec3_add(at, vec3_add(vec3_scale(n, -0.14f * s), vec3(0.0f, -lerpf(0.05f, 0.055f, u) * s, 0.0f))); + foot->stepping = false; + } + return; + } int k = rungAbove(l, who->ladder_at - 0.02f); for (int i = 0; i < 2; i++) { /* one foot a rung higher than the other, swapping as you climb */ diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index b6e4275..3e3cfd7 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -225,6 +225,8 @@ typedef struct Object { 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) */ + float ladder_off; /* ... stepping off at the bottom (0 = not, .. 1 = off), from ladder_off_from */ + Vec3 ladder_off_from; bool ladder_limbs_ok; /* Characters only */