Metadata-Version: 2.4
Name: ethosoft
Version: 0.1.0
Summary: Gymnasium RL environment wrapping the 3D-Game raylib FPS as a headless native environment
Author: 331uw13
License: GPL-3.0-or-later
Project-URL: Source, https://github.com/331uw13/3D-Game
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Games/Entertainment :: First Person Shooters
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: gymnasium>=0.29
Requires-Dist: numpy>=1.23
Dynamic: license-file

# Ethosoft

A [Gymnasium](https://gymnasium.farama.org/) environment wrapping
[331uw13/3D-Game](https://github.com/331uw13/3D-Game) — a raylib/C first-person
shooter with procedural voxel terrain — as a headless, steppable RL environment.

The game runs off-screen (no visible window), driven one fixed timestep
(1/60s) at a time by actions from Python, via a small native library
(`game3denv.dll`) built from the game's own C source plus a thin env API
(see `src/env/` in the main repo). No game-logic files were modified to make
this possible — see `src/env/env_shim.c` for how input is injected instead.

```python
import gymnasium as gym
import ethosoft  # registers "Game3D-v0"

env = gym.make("Game3D-v0")
obs, info = env.reset()
for _ in range(1000):
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)
    if terminated or truncated:
        obs, info = env.reset()
env.close()
```

## Spaces

- **Action** (`Dict`): `move` (`MultiBinary(4)`: forward/back/left/right),
  `run`, `jump`, `shoot`, `aim` (`Discrete(2)`), `look` (`Box(-1, 1, (2,))`
  mouse-look delta, scaled by `look_scale`).
- **Observation** (`Dict`): `rgb` (`Box(0, 255, (H, W, 3), uint8)` off-screen
  render, resolution from `game.cfg`), `vector` (`Box(-inf, inf, (12,))`:
  health fraction, armor fraction, xp, total kills, position xyz, yaw, pitch,
  onground, nearest enemy distance in the current chunk, nearest enemy alive).
- **Reward**: `Δhealth * 0.1 + Δkills * 10 + 0.01` per step, `-50` on death.
- `terminated` when the player dies; `truncated` after `max_episode_steps`
  (default 2000, set via `Game3DEnv(max_episode_steps=...)`).

## Scope (v0.1)

- Same procedurally generated world persists across episodes in a process;
  `reset()` respawns the player, it does not regenerate terrain.
- Inventory, NPC dialogue, and item crafting are not part of the action/
  observation space yet.
- Only one `Game3DEnv` may be alive per process (the native library holds a
  single global game state) — use separate processes to parallelize.
- Prebuilt binary ships for **Windows x64 only**. On Linux/macOS, build
  `game3denv.so` yourself from the main repo (`mingw32-make envlib` on
  Windows or the equivalent GCC/Make invocation using the Makefile's `envlib`
  target on Linux/macOS with raylib installed) and drop it into
  `ethosoft/native/` alongside `res/`, `weapons_cfg/`, and `game.cfg`.

## License

GPL-3.0-or-later, same as the upstream game (raylib itself is zlib-licensed).
