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.59.0: stepping up onto blocks; set moves only for things on the ground
- Walking at a block above knee high up to about hip high with room on top: you step up onto it, one leg after the other (no more knees through its face) - Set moves and jumps only for things standing on the ground in front of you (something lying up on a roof made people step over thin air) 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/README.md | 2 ++ entropie/STATE.md | 3 ++- entropie/commit_message.txt | 19 ++++++++++--------- entropie/src/world/object.h | 1 + entropie/src/world/physics.c | 40 ++++++++++++++++++++++++++++++---------- entropie/src/world/world.c | 2 +- 7 files changed, 47 insertions(+), 22 deletions(-) diff --git a/entropie/Makefile b/entropie/Makefile index 23c1ee3..371d4a5 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 1.58.0 +VERSION := 1.59.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/README.md b/entropie/README.md index 8c402ae..a606264 100644 --- a/entropie/README.md +++ b/entropie/README.md @@ -153,6 +153,8 @@ and satellite pictures (about 340 x 340 m). - Walking over something knee high is one smooth move: the first leg goes over, the body follows, the other leg comes after (higher things: up on the toes, that leg swung out). Once started it always finishes +- Walking at a block a bit higher than that (up to about the hip) with + room on top: you step up onto it the same way, one leg after the other - Running into something sober: low, you trip or go headlong over it; high, you stagger back or go down to the side you came in from. How badly depends on speed, fitness, energy and clumsiness diff --git a/entropie/STATE.md b/entropie/STATE.md index a2a3677..2ecdcf4 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -78,6 +78,7 @@ Talk topics: offer, ask, suggest, where (new woodpile spot), ask for a hand, ask - **Any frame rate**: springs are solved exactly per frame, people pushing each other ease apart gently, helpers stay put once there (or blocked close by): no flicker at low, high or uneven frame rates - **Approaching obstacles**: the sporty fit their steps to a good take-off spot; jogging or faster (2.9 m/s+, some energy, not very drunk) low things (15 cm up to about knee high, up to 0.7 m deep) are jumped on their own (`physics.c` hurdle / jumpOver): no slowing down before them (the run-up counts), off when the top of the jump comes over its middle, as high as it takes to clear it by 14 cm (feet tucked 18 cm) and long enough to land 25 cm past it, at most a full jump (else stepped over, slower); course test (jog / sprint): legs in obstacles about a third of before, joint jumps -30 %; running into something: trip or headlong over it if low, stagger back or fall to the side if high (speed, fitness, energy, clumsiness) - **Walking over knee-high things** (20 cm up to about the knee, walking, the landing free): a set move instead of the feet on their own (`physics.c` startStepOver / stepOverMove, `world.c` overFeet): 0.9 s + 1.6 s per m of height (less sporty: slower); the foot further back goes first (up, over, down 16 cm past it), the hips go to between the feet, then the other foot (swung out for higher things, the body up on the toes), then the body on past it. Always finishes. Course (walk): legs in obstacles from 60/15/1 frames (thigh/shin/foot, worst 25 cm) to 8/16/1 (10 cm), joint jumps 27 -> 16 +- **Stepping up** (the player, walking): a block above knee high up to 0.75 m (scaled) with 45 cm of room on top (fixed or 40 kg+, not furniture, bins or supplies): the same set move up onto it, the first foot 20 cm in from its edge, the body rising onto it from 30 to 78 % of the move. Course (walk, the static lane): legs in obstacles from 55/47 frames (thigh/shin) to 19/13, joint jumps 63 -> 37. Set moves, jumps and step-ups only for things standing on the ground in front of you (one up on something else: no) - **Up onto things at a run** (jogging or faster): a block up to 0.95 m high with 40 cm of room on top (fixed, or 40 kg and more) is jumped onto, timed to come down on it; higher (up to 2.05 m, sober, some energy) running into it you catch it (no bouncing off) and the climb starts - **Over obstacles**: lean into it, the leg swings out a little and back in; lift the foot first, then over; the body waits for the back leg; knee turns out, or the foot comes up; sprinting, leaps; careless people just step on small things; trips and scrapes by speed, height, condition - **Bushes**: trying to get over one ends in it, twigs snap @@ -156,4 +157,4 @@ Most important first. - The walking map rebuild takes ~9 ms when fixed things change (a felled tree) --- -State of `entropie 1.58.0 (build 20c9497)` +State of `entropie 1.59.0 (build 1eab5b0)` diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt index 23437af..5bf0914 100644 --- a/entropie/commit_message.txt +++ b/entropie/commit_message.txt @@ -1,10 +1,11 @@ -entropie 1.58.0: stepping over is one smooth move; up onto blocks at a run +entropie 1.59.0: stepping up onto blocks; set moves only for things on the ground -- Walking over something knee high is a set move: the first leg over, the - hips between the feet, the other leg after (higher things: up on the - toes, swung out); it always finishes - no more legs through things or - stuck half over (course, walking: legs in obstacles about a fifth) -- Jogging or faster at a block up to about hip high with room on top: a - timed jump up onto it -- Running at something you can climb: you catch the edge instead of - bouncing off, and the climb starts +- Walking at a block above knee high up to about hip high with room on + top: you step up onto it, one leg after the other (no more knees + through its face) +- Set moves and jumps only for things standing on the ground in front of + you (something lying up on a roof made people step over thin air) + +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 diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index ea756ac..6543dfb 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -186,6 +186,7 @@ typedef struct Object { Vec3 over_from, over_dir; float over_near, over_far, over_top; /* its faces along over_dir from over_from, its top over the feet */ int over_lead; /* the foot that goes first */ + bool over_up; /* ... up onto it rather than over it */ Vec3 over_foot0[2], over_land[2]; int sit_style; /* characters: SIT_GROUND (cross-legged) or SIT_SEAT */ struct { /* dogs */ diff --git a/entropie/src/world/physics.c b/entropie/src/world/physics.c index 39856bc..e33b404 100644 --- a/entropie/src/world/physics.c +++ b/entropie/src/world/physics.c @@ -47,6 +47,9 @@ #define OVER_MOVE_TIME 0.9f /* ... taking this long ... */ #define OVER_MOVE_HIGH 1.6f /* ... and this much more per meter high */ #define OVER_LAND 0.16f /* the first foot comes down this far past it */ +#define STEP_UP_MOST 0.75f /* walking up onto something this high at most (scaled; higher: climb) ... */ +#define STEP_UP_ROOM 0.45f /* ... with this much room on top ... */ +#define STEP_UP_IN 0.2f /* ... the first foot this far in from its edge */ #define ONTO_HIGHEST 0.95f /* up onto things this high at most (scaled) ... */ #define ONTO_ROOM 0.4f /* ... with this much room on top to land ... */ #define ONTO_HOLDS 40.0f /* ... (loose: this heavy, else it would go over) ... */ @@ -553,6 +556,8 @@ static bool jumpOver(const Object *obj, const Object *o, Vec3 dir, float speed, float reach = projectRadius(c, dir), side = projectRadius(c, vec3(-dir.z, 0.0f, dir.x)); float ahead = vec3_dot(rel, dir), beside = fabsf(rel.x * -dir.z + rel.z * dir.x); float height = Object_colliderCenter(o, 0).y + projectRadius(c, WORLD_UP) - obj->position.y; + float bottom = Object_colliderCenter(o, 0).y - projectRadius(c, WORLD_UP) - obj->position.y; + if (bottom > (0.2f + 0.15f * fmaxf(ahead, 0.0f)) * s || bottom < -0.5f * s - 0.15f * fmaxf(ahead, 0.0f)) return false; /* (not on the ground in front of you) */ if (beside > side + 0.2f || ahead - reach < 0.05f * s || ahead - reach > JUMP_LOOK * s) return false; if (height < HURDLE_LOWEST * s || 2.0f * reach > HURDLE_DEPTH * s) return false; /* high enough to clear it, long enough to land past it */ @@ -585,6 +590,8 @@ static bool jumpOnto(const Object *obj, const Object *o, Vec3 dir, float *v_up, float reach = projectRadius(c, dir), side = projectRadius(c, vec3(-dir.z, 0.0f, dir.x)); float ahead = vec3_dot(rel, dir), beside = fabsf(rel.x * -dir.z + rel.z * dir.x); float top = Object_colliderCenter(o, 0).y + projectRadius(c, WORLD_UP) - obj->position.y; + float bottom = Object_colliderCenter(o, 0).y - projectRadius(c, WORLD_UP) - obj->position.y; + if (bottom > (0.2f + 0.15f * fmaxf(ahead, 0.0f)) * s || bottom < -0.5f * s - 0.15f * fmaxf(ahead, 0.0f)) return false; if (beside > side - 0.15f || ahead - reach < 0.05f * s || ahead - reach > JUMP_LOOK * s) return false; if (top <= STEP_OVER_HEIGHT * s || top > ONTO_HIGHEST * s || 2.0f * reach < ONTO_ROOM * s) return false; float v = sqrtf(2.0f * GRAVITY * fmaxf(top + (ONTO_CLEAR - JUMP_TUCK) * s, 0.1f * s)); @@ -620,7 +627,9 @@ static bool startStepOver(Object *obj, Object *const *objects, int count, const if (vec3_dot(dir, Object_facing(obj)) < 0.7f) return false; /* (backing or sidling: as it comes) */ for (int i = 0; i < count; i++) { const Object *o = objects[i]; - if (!Physics_stepsOver(obj, o)) continue; + if (o->collider_count == 0 || o->is_character || o->is_held || o->lifted) continue; + /* over it (low for its own sake), or up onto it (higher, room on top, holds you) */ + bool over = (o->weight >= STEP_OVER_LIGHT || o->is_static) && Physics_lowObstacle(o) >= OVER_MOVE_LOWEST * s; const Collider *c = &o->colliders[0]; Vec3 rel = vec3_sub(Object_colliderCenter(o, 0), obj->position); rel.y = 0.0f; @@ -628,21 +637,28 @@ static bool startStepOver(Object *obj, Object *const *objects, int count, const float ahead = vec3_dot(rel, dir), beside = fabsf(rel.x * -dir.z + rel.z * dir.x); float top = Object_colliderCenter(o, 0).y + projectRadius(c, WORLD_UP) - obj->position.y; float near = ahead - reach, far = ahead + reach; - if (beside > side + 0.1f * s || near > OVER_MOVE_FROM * s || near < 0.08f * s || Physics_lowObstacle(o) < OVER_MOVE_LOWEST * s) continue; + bool up = !over && !neverOver(o) && obj->type == OBJ_PLAYER && /* (people walk round; and nobody walks up onto tables) */ + o->type != OBJ_FURNITURE && o->type != OBJ_BIN && o->type != OBJ_SUPPLY && (o->is_static || o->weight >= ONTO_HOLDS) && c->axes[1].y > 0.95f && + top > STEP_OVER_HEIGHT * s && top <= STEP_UP_MOST * s && 2.0f * reach >= STEP_UP_ROOM * s && side >= 0.3f * s; + if (!over && !up) continue; + float bottom = Object_colliderCenter(o, 0).y - projectRadius(c, WORLD_UP) - obj->position.y; + if (bottom > (0.2f + 0.15f * fmaxf(ahead, 0.0f)) * s || bottom < -0.5f * s - 0.15f * fmaxf(ahead, 0.0f)) continue; /* (up on something, or down in a hole: not in your way) */ + if (beside > side + (up ? -0.1f : 0.1f) * s || near > OVER_MOVE_FROM * s || near < 0.08f * s) continue; top = fmaxf(top, 0.05f * s); /* (downhill it may be lower than your feet) */ - /* where the feet come down: free? */ + /* where the feet come down: free? (on top of it, going up) */ Vec3 right = vec3(-dir.z, 0.0f, dir.x); - float land_at = far + OVER_LAND * s; + float land_at = up ? near + STEP_UP_IN * s : far + OVER_LAND * s; bool free = true; for (int k = -1; k <= 1 && free; k += 2) { Vec3 p = vec3_add(obj->position, vec3_add(vec3_scale(dir, land_at), vec3_scale(right, (float)k * 0.11f * s))); - p.y = Terrain_height(terrain, p.x, p.z) + 0.05f; + p.y = up ? obj->position.y + top + 0.12f * s : Terrain_height(terrain, p.x, p.z) + 0.05f; for (int j = 0; j < count && free; j++) - if (objects[j] != obj && !objects[j]->is_character && objects[j]->collider_count > 0 && objects[j]->type != OBJ_DECAL && + if (objects[j] != obj && (!up || objects[j] != o) && !objects[j]->is_character && objects[j]->collider_count > 0 && objects[j]->type != OBJ_DECAL && objects[j]->type != OBJ_PUDDLE && objects[j]->type != OBJ_STINK && pointIn(objects[j], p, 0.08f * s)) free = false; } if (!free) continue; obj->over_t = 1e-4f; + obj->over_up = up; obj->over_time = (OVER_MOVE_TIME + OVER_MOVE_HIGH * top / s) * (1.25f - 0.5f * obj->fitness) / fmaxf(Object_vigor(obj), 0.6f); obj->over_from = obj->position; obj->over_dir = dir; @@ -658,7 +674,8 @@ static bool startStepOver(Object *obj, Object *const *objects, int count, const if (fabsf(lateral) < 0.08f * s) lateral = (k == 0 ? -0.1f : 0.1f) * s; /* (feet apart) */ float at = k == obj->over_lead ? land_at : land_at + 0.08f * s; Vec3 land = vec3_add(obj->position, vec3_add(vec3_scale(dir, at), vec3_scale(right, lateral))); - land.y = Terrain_height(terrain, land.x, land.z) + (b->feet[k].ankle.y - Terrain_height(terrain, b->feet[k].ankle.x, b->feet[k].ankle.z)); + land.y = up ? obj->position.y + top + (b->feet[k].ankle.y - obj->position.y) + : Terrain_height(terrain, land.x, land.z) + (b->feet[k].ankle.y - Terrain_height(terrain, b->feet[k].ankle.x, b->feet[k].ankle.z)); obj->over_land[k] = land; } obj->movement = vec3_zero(); @@ -677,12 +694,15 @@ static void stepOverMove(Object *obj, const Terrain *terrain, float dt) { const int lead = obj->over_lead; float landed = vec3_dot(vec3_sub(obj->over_land[lead], obj->over_from), obj->over_dir); float behind = vec3_dot(vec3_sub(obj->over_foot0[1 - lead], obj->over_from), obj->over_dir); - float mid = fmaxf(0.5f * (landed + behind), 0.05f * s), end = obj->over_far + OVER_LAND * s + 0.04f * s; + float mid = fmaxf(0.5f * (landed + behind), 0.05f * s), end = obj->over_up ? landed + 0.02f * s : obj->over_far + OVER_LAND * s + 0.04f * s; float along = t < 0.5f ? mid * smoothstepf(0.08f, 0.5f, t) : lerpf(mid, end, smoothstepf(0.5f, 0.95f, t)); Vec3 p = vec3_add(obj->over_from, vec3_scale(obj->over_dir, along)); - p.y = Terrain_height(terrain, p.x, p.z) + (obj->over_from.y - Terrain_height(terrain, obj->over_from.x, obj->over_from.z)); + if (obj->over_up) /* up onto it: the body rises as the leading leg pushes up, over its foot */ + p.y = obj->over_from.y + obj->over_top * smoothstepf(0.3f, 0.78f, t); + else + p.y = Terrain_height(terrain, p.x, p.z) + (obj->over_from.y - Terrain_height(terrain, obj->over_from.x, obj->over_from.z)); /* (something high: up on the toes of the leading foot while the other one comes over, its knee clear of it) */ - p.y += clampf(obj->over_top - 0.3f * s, 0.0f, 0.1f * s) * smoothstepf(0.45f, 0.6f, t) * (1.0f - smoothstepf(0.85f, 1.0f, t)); + if (!obj->over_up) p.y += clampf(obj->over_top - 0.3f * s, 0.0f, 0.1f * s) * smoothstepf(0.45f, 0.6f, t) * (1.0f - smoothstepf(0.85f, 1.0f, t)); obj->position = p; obj->velocity = obj->movement = vec3_zero(); obj->is_grounded = true; diff --git a/entropie/src/world/world.c b/entropie/src/world/world.c index 7887e4a..48f6ea5 100644 --- a/entropie/src/world/world.c +++ b/entropie/src/world/world.c @@ -524,7 +524,7 @@ static void overFeet(Object *o) { at.y = base + up * (clear + (o->over_from.y - base)) ; /* (the trailing leg swings out a little going over) */ Vec3 right = vec3(-dir.z, 0.0f, dir.x); - float side = (i == 0 ? -1.0f : 1.0f) * (lead ? 0.03f * s : 0.09f * s + 0.5f * fmaxf(0.0f, o->over_top - 0.3f * s)) * up; + float side = (i == 0 ? -1.0f : 1.0f) * (lead || o->over_up ? 0.03f * s : 0.09f * s + 0.5f * fmaxf(0.0f, o->over_top - 0.3f * s)) * up; at = vec3_add(at, vec3_scale(right, side)); ft->ankle = at; ft->dir = dir;