v1 → v2 Migration Guide¶
Explains how to upgrade v1.x code to v2.0. v1 API is fully backward-compatible in v2 — existing code runs without modification. Follow this guide only when you want to adopt v2 features.
1. Installation¶
# v1
pip install pyforge3d==1.1.0
# v2 (includes Rust extension)
pip install pyforge3d==2.0.0
# Or from source: maturin build --release && pip install dist/pyforge3d-2.0.0-*.whl
Rust (rustup) is not required for installation — if the Rust build fails, the Python fallback is selected automatically.
2. Version check¶
3. Existing code — no changes needed¶
All v1 code runs unchanged in v2.
# v1 code — runs in v2 without modification
import forge3d as f3d
world = f3d.World(gravity=(0, 0, -9.81))
world.add_ground()
box = world.add_box(size=(1, 1, 1), position=(0, 0, 5), mass=1.0)
viewer = f3d.Viewer(world, max_frames=90)
while viewer.is_open:
world.step(dt=1 / 60)
viewer.draw()
4. Adopting v2 features — ECS¶
v1 style (still supported)¶
v2 ECS style (opt-in)¶
ew = f3d.EntityWorld()
box = ew.create_entity(
f3d.Transform(position=[0, 0, 5]),
f3d.MeshRenderer(mesh_id="box_1x1x1", material_id="red"),
f3d.Rigidbody(mass=1.0),
)
ew.add_system(f3d.PhysicsSystem())
ew.add_system(f3d.RenderSystem())
ew.step(1/60)
Bridging v1 Body → ECS entity¶
# Wrap an existing v1 Body as an ECS entity
from forge3d import body_to_entity
entity = body_to_entity(world, v1_box, ew)
5. Modern rendering pipeline (P26)¶
v1 — OpenGL 3.3 Blinn-Phong¶
v2 — Deferred PBR (automatic upgrade)¶
# Viewer uses DeferredRenderer internally (automatic)
viewer = f3d.Viewer(world, mode="realtime")
# Direct usage
from forge3d.render import DeferredRenderer
renderer = DeferredRenderer(width=1280, height=720)
frame = renderer.render(snapshot)
6. Audio system (P28)¶
# New in v2
clip = f3d.AudioClip.from_sine(freq=440.0, duration=0.5)
audio_sys = f3d.AudioSystem()
audio_sys.play(clip, volume=0.8)
# Collision event → sound trigger
handler = audio_sys.make_collision_handler(clip, max_volume=1.0)
world.on_collision_begin(handler)
7. Animation + IK (P29)¶
# Create skeleton
skel = f3d.Skeleton.chain([
np.array([0., 0., 0.]),
np.array([0., 1., 0.]),
np.array([0., 2., 0.]),
])
# FABRIK IK
solver = f3d.FABRIKSolver()
chain = [np.array([0., 0., 0.]), np.array([0., 1., 0.]), np.array([0., 2., 0.])]
solved = solver.solve(chain, target=np.array([1.5, 1.0, 0.]))
8. Particle system (P31)¶
ew = f3d.EntityWorld()
ew.create_entity(
f3d.Transform(position=np.array([0., 5., 0.])),
f3d.ParticleEmitter.preset("sparks", rate=500),
)
ps = f3d.ParticleSystem()
ew.add_system(ps)
ew.step(1/60)
print(f"{ps.total_alive} sparks alive")
9. Scene save / load (P30)¶
# Save ECS scene
from forge3d import save_scene, load_scene
save_scene(ew, "my_scene.json")
# Using scene manager
mgr = f3d.SceneManager(ew)
mgr.on_scene_loaded(lambda: print("Scene loaded"))
mgr.load_scene("level1.json")
10. Rust core control¶
# Disable Rust core (Python fallback)
USE_RUST_CORE=0 python my_game.py
# Force Rust core (error if unavailable)
USE_RUST_CORE=1 python my_game.py
11. Breaking changes¶
None. The v1 API is frozen.
12. Deprecated¶
None. v1 API is guaranteed until v3.