Metadata-Version: 2.4
Name: SimVX-Core
Version: 0.0.0.dev1496+gc464d742
Summary: A full-featured game engine written entirely in Python.
Project-URL: Homepage, https://simvx.com
Project-URL: Source, https://fezzik.dev/Fezzik/simvx
Author-email: SimVX Team <simvx@simvx.com>
License-Expression: AGPL-3.0-or-later
Classifier: Development Status :: 1 - Planning
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.14
Requires-Dist: cffi>=1.17
Requires-Dist: freetype-py>=2.5.0
Requires-Dist: miniaudio>=1.60
Requires-Dist: numpy
Requires-Dist: parso<0.9,>=0.8
Provides-Extra: graphics
Requires-Dist: pillow; extra == 'graphics'
Requires-Dist: simvx-graphics==0.0.0.dev1496+gc464d742; extra == 'graphics'
Requires-Dist: trimesh; extra == 'graphics'
Provides-Extra: pymunk
Requires-Dist: pymunk>=7.0; extra == 'pymunk'
Description-Content-Type: text/markdown

# SimVX Core

Backend-agnostic game engine providing the node system, scene tree, and all gameplay systems. Core has zero dependencies on any rendering backend: it works with Vulkan or headless.

## Node System

All game objects inherit from `Node`. Nodes form a tree with parent-child relationships, lifecycle callbacks, and automatic signal dispatch.

**Class hierarchy:**

```
Node
├── Node2D                 2D spatial (position, rotation, scale)
│   ├── CharacterBody2D    2D physics body with collision
│   └── CollisionShape2D   Circle collision shape
├── Node3D                 3D spatial (position, rotation, scale as Quat)
│   ├── CharacterBody3D    3D physics body with collision
│   ├── CollisionShape3D   Sphere collision shape
│   ├── Camera3D           View/projection matrices
│   │   └── OrbitCamera3D   Orbit/pan/zoom camera
│   ├── MeshInstance3D     Visible 3D object (mesh + material)
│   ├── Light3D            Base light
│   │   ├── DirectionalLight3D
│   │   ├── PointLight3D
│   │   └── SpotLight3D
│   ├── Text3D             World-space text
│   └── AudioPlayer3D
├── Timer                  Fires timeout signal after duration
├── AudioPlayer      Non-positional audio
├── AudioPlayer2D    2D spatial audio
└── Text2D                 Screen-space text overlay
```

## Key Concepts

**Signals**: Observer pattern for decoupled communication:

```python
timer.timeout.connect(on_timeout)
timer.timeout.emit()
```

**Properties**: Editor-visible property descriptors with validation:

```python
class Player(Node3D):
    speed = Property(5.0, range=(0, 20), hint="Movement speed")
    mode = Property("walk", enum=["walk", "run", "fly"])
```

**Coroutines**: Generator-based async within the game loop:

```python
def spawn_wave(self):
    for i in range(5):
        self.spawn_enemy()
        yield from wait(0.5)

def on_ready(self):
    self.start_coroutine(self.spawn_wave())
```

**Scenes**: Python source is the canonical (and only) scene format. A scene is a `Node` subclass; loading imports the module and instantiates the primary class. Round-trip saves preserve user formatting via `simvx.core.scene_io`:

```python
from simvx.core.scene_io import SceneFile, load_scene

scene = load_scene("level.py")               # imports module, instantiates the primary class

# Greenfield emit:
SceneFile.from_runtime(root).save("level.py")

# Format-preserving update:
sf = SceneFile.load("level.py")
apply_runtime_diff(sf.scene_class(), root)   # see simvx.editor.scene_diff
sf.save()
```

Save-game data (game state, checkpoints, replays) is a separate concern and may use any serialisation; the rule above applies specifically to authored scene files.

## Systems

| System | Module | Description |
|--------|--------|-------------|
| Animation | `animation.py` | Tweens, sprite sheets, keyframe clips, state machines |
| Audio | `audio.py` | 2D/3D spatial audio, buses, resource caching |
| UI | `ui.py` | Controls, containers, theming, focus management |
| Collision | `collision.py` | GJK + AABB broadphase, raycasting |
| Particles | `particles.py` | Particle emitter node |
| Skeleton | `skeleton.py` | Bone hierarchy and skinning |

## Math Types

Pure Python vector and quaternion types (no PyGLM dependency):

```python
from simvx.core import Vec2, Vec3, Quat

v = Vec3(1, 2, 3)
v.normalized()       # Unit vector
v.dot(other)          # Dot product
v.cross(other)        # Cross product

q = Quat.from_euler(pitch=45, yaw=90)
q.rotate((0, 1, 0), 30)  # Compose rotations
q.slerp(other, 0.5)      # Spherical interpolation
```

## Usage

```python
from simvx.core import Node, Node3D, Camera3D, Timer, Signal

class MyGame(Node):
    def on_ready(self):
        cam = Camera3D(position=(0, 5, 10))
        self.add_child(cam)

        t = Timer(duration=2.0, one_shot=False, autostart=True)
        t.timeout.connect(self.on_tick)
        self.add_child(t)

    def on_tick(self):
        print("tick!")
```
