# Entropie – architecture How the code is put together. Read before adding a feature; update it in the same version when the structure changes (rules for working on it: [RULES.md](RULES.md)). ## Modules | Folder | What it is | May include | |---|---|---| | `src/core/` | window, GL loader (`gl.h`: every GL call is listed there), input, sound out (`audio.c`: a synthesizer and mixer, no sound files) | core | | `src/math/` | vectors, matrices, frustum, yaw conventions (`linalg.h`) | math | | `src/render/` | renderer and its passes, shaders' uniforms, meshes, procedural shapes (`shapes*.c`), figures, camera, sky, UI | core, math, render | | `src/world/` | `Object`, `World`, physics, terrain, the map (`site.c`, `scene.c`, `manor.c` - also the Berlin rooms off the map, `course.c`), everybody in the story (`cast.c`), the floors' stages (`stage.c`), the side jobs' ground (`field.c`: the Kartoffelacker's grass, the snails, Kerry's art), the why questions' content (`why.c`), the festival's guests (`guests.c`), the big old tree's places (`bigtree.c`), broken bones and casts (`injury.c`), tools, forestry, ladder, hose, camp, clothes, car, water, weather, grass, grid, day | everything but game | | `src/people/` | bodies (animation), hands, AI (the projects: `ai_project.c`, the side jobs and the big tree: `ai_jobs.c`, the festival weekend: `ai_fest.c`, held, hand in hand, stepping in: `ai_touch.c`), touching somebody and what it means (`touch.c`), talk, condition, dog, climbing | everything but game | | `src/game/` | the frame: input to actions, player, camera follow, talk and dev UI, the arrival by car at the start, the story (`game_story.c`: the crew turning up, the crew overview), the shopping run (`game_shop.c`), the meetings in Berlin and the weekends (`game_meeting.c`), the why questions coming up and your notebook (`game_why.c`), the festival weekend and the storm (`game_festival.c`), the supporters' shifts, the clean-up and the drive home (`game_cleanup.c`), the big tree's rope and fall (`game_bigtree.c`), the ambulance and the hospital (`game_injury.c`), reaching out, holding people and who saw it (`game_touch.c`), saves (`save.c`), what you hear (`sound.c`) | all | - `render` knows nothing of the world: it gets meshes, matrices and plain numbers. - `world` and `people` are one layer: an `Object` owns its `Body`, `Ai` and `Hands`. - `*_internal.h`: shared inside one module only. ## One frame `Game_update` → input, actions, talk, player → `World_update`: physics for every object (near ones from the `Grid`) → grid rebuilt → felling and cutting → hands (pushing, carrying) → hose → AI → bodies animated → props (gates, chairs, ashtray, pullovers put down). Then the camera follows (`game.c`), and `Game_render`: shadow pass, scene pass (terrain, objects, figures, grass), the sky, `Game_renderAir` (rain, smoke, chips: after the sky, so they show against it), ink pass, UI. `Sound_update` (main.c) after the update: the world's noises of the frame and the steady sounds. Budget: the update takes about 1 ms for ~950 objects. Drawing skips what's out of view (objects, 8×8 terrain tiles). ## Objects - One struct for every thing (`world/object.h`): `type`, `variant`, size, position, rotation (yaw `rotation.y`), up to 3 oriented box colliders. - Fields only some kinds use are commented with the kind ("characters:", "gates:", "chairs:"). Objects start zeroed: zero must be a safe default. - `is_static`: never moved by physics. Only their own code moves them (`Object_swingGate`, `Object_slideChair`), then `Object_syncColliders`. - Meshes come from `Shapes_*` and are rebuilt only when what they show changes (`shown` pattern in `world.c` showProps). ## Space and turning - y up, meters, seconds. Yaw: local +X turns to (cos, 0, sin), +Z to (-sin, 0, cos). - `yaw_along(dir)`: lengths along +X (logs, gates, wall pieces). `yaw_facing(dir)`: fronts along +Z (furniture, doors, windows, chairs). `yaw_front(yaw)`: where a front points. - The courtyard: `court(a, b)` in `site.c`. The main building: local x along it, +z towards the yard (`manor.c`). ## Building the map `Scene_load` (start things) → `Site_build` (static things, buildings, roads) → `World_buildTerrain` (levels the ground under static things) → `Site_finish` / `Scene_finish` (things that sit on the ground). - Buildings you walk into (`manor.c`): a `Plan` of boxes (`box`, `wallX`, `wallZ` with gaps, `opening`). The look is one `OBJ_STRUCTURE` mesh, the solid parts invisible `OBJ_WALL`s. - Below the ground: `Terrain_addPit` (a turned rectangle). The ground's height there is the pit floor, the ground isn't drawn there (`holes` in `scene.frag`). ## Physics - Per object, against near objects and the terrain. Characters: walk up stairs (up to `SNAP_UP_MOST`), higher edges and things to step over or onto are a set move (`over_t`, `beginStepOver`); sitting down is a set move too (`sit_moving`). - Rays: `Collider_ray` / `Object_rayToCollider` (one box), `World_rayCast` (the first thing along a ray, with a skip filter). Down to the ground: `World_groundHeight`. ## Rendering - One scene shader for everything not a figure: uniforms switch it to terrain (`terrainSize`), decals, grass, glow. Figures have their own shader. The ink pass draws the outlines over it all. - New GL calls: add them to the list in `core/gl.h`. ## Sound - `core/audio.c`: SDL3 audio stream, mixed on the audio thread. Short voices (noise, sine, saw or crackle; filters; attack and decay; pan; delay) and steady beds (wind, rain, fire, chainsaw, engine, crickets, hose) turned up and down. No device: silent, nothing else changes. - The world queues what makes a sound this frame: `World_noise` (steps with what's underfoot, chops, clinks, glass, thuds, a tree coming down, twigs). `game/sound.c` empties the list each frame and plays them by distance and side from the camera; the beds follow the weather, the fires, a chainsaw, the car. - M mutes; menus pause the beds. ## Crates - Each slot is known (`Object.crate_slot`: kind and sips, `CRATE_SLOT`): `stored`, `crate_empties` and the weight follow from it (`Crate_recount`). Bottles of another kind put into a crate stay there as such until somebody sorts them (`Crate_takeWrong`, the tidy: `ai_help.c` sortCrates). ## Saves - `src/game/save.c`: `.sav` (text: `key value` lines, `[game]`, then `[o id]` per object) and `.ground` (binary: the wear map, the wet chunks). In the user's data folder (`Platform_saveDir`). - Loading builds the world as at the start (`Game_initWorld(game, false)`: no drive in), finds the scene's things by `scene_id` / `spawn` / `spawn_type` (set when the scene is built), makes the rest anew (`Object_create` with the saved type, palette, size and `make_arg`), then sets the fields and rebuilds what looks different (trees, tents, gear, crates, bags, bottles, ladders, pullovers, the car). - What's saved: the tables `THING` and `PERSON` in save.c (plus skills, likes, keys, hands, the car's boot, asleep). Buildings, walls, roads, bushes: only found again. - Keeping old saves working: - A new field: add it to a table. Old saves don't have it: it keeps what the fresh world gives it. - A key renamed or its meaning changed: raise `SAVE_FORMAT` (save.h) and add a step to `migrate()` that rewrites the old lines. - A save from a newer format is refused, never guessed at. - A thing the scene no longer makes is dropped; one it newly makes keeps its fresh state. - Not kept (comes back fresh): what anybody was in the middle of (AI plans, paths, poses), sparks and smoke. Kept specially: the hose's rope (`rope` line: every point, melted, taped), who sits where (`sit` line: sat down again, staying a while), who's up a ladder (`ladder` line: you back on it as high, `Ladder_mountAt`; the others at its foot), what's in each crate slot (`slots` line; older saves: their own bottles, so many full and empty), holding on to something together (`grab`, `help` lines). ## Versions `Makefile` `VERSION`; the build id is an md5 of sources and assets (`make version`). `STATE.md` ends with the version it describes.