newtonian-physics 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 pyphysics contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.4
2
+ Name: newtonian-physics
3
+ Version: 0.2.0
4
+ Summary: A deterministic pure-Python 2D and 3D rigid-body physics engine.
5
+ Author: UeCollaxion-
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yourusername/newtonian-physics
8
+ Project-URL: Repository, https://github.com/yourusername/newtonian-physics
9
+ Project-URL: Issues, https://github.com/yourusername/newtonian-physics/issues
10
+ Keywords: physics,simulation,rigid-body,collision,2d,3d,game-engine
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Education
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering :: Physics
23
+ Classifier: Topic :: Games/Entertainment :: Simulation
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Dynamic: license-file
28
+
29
+ # pyphysics
30
+
31
+ `pyphysics` is a pure-Python rigid-body physics engine with deterministic 2D and
32
+ 3D simulation APIs. It is built for games, prototypes, education, robotics
33
+ experiments, and simulation tools that need a readable engine core without
34
+ runtime dependencies.
35
+
36
+ > PyPI name note: the `pyphysics` distribution name is already owned on PyPI by
37
+ > another project. This package can still be installed locally as `pyphysics`,
38
+ > but publishing it so `pip install pyphysics` resolves to this library requires
39
+ > ownership or maintainer access to that existing PyPI project.
40
+
41
+ ## Highlights
42
+
43
+ - 2D rigid bodies: dynamic, static, and kinematic
44
+ - 3D rigid bodies: dynamic, static, and kinematic
45
+ - 2D shapes: `Circle`, `Box`, `ConvexPolygon`
46
+ - 3D shapes: `Sphere`, `Box3D`, `ConvexPolyhedron`
47
+ - SAT-based convex polygon and polyhedron collision
48
+ - Impulse collision response with restitution and friction
49
+ - Gravity, force accumulation, persistent acceleration, and damping
50
+ - Distance joints for 2D constraints
51
+ - Sensors, contact callbacks, collision categories, and collision masks
52
+ - Ray casting and AABB queries in 2D and 3D
53
+ - `PhysicsClock` for fixed timesteps, scaled time, frame count, and accumulation
54
+ - Continuous substepping for fast-moving bodies
55
+ - No runtime dependencies
56
+
57
+ ## Installation
58
+
59
+ For local development:
60
+
61
+ ```powershell
62
+ python -m pip install -e .
63
+ ```
64
+
65
+ When published under an available PyPI distribution name:
66
+
67
+ ```powershell
68
+ python -m pip install <distribution-name>
69
+ ```
70
+
71
+ The import package is always:
72
+
73
+ ```python
74
+ import pyphysics
75
+ ```
76
+
77
+ ## 2D Quick Start
78
+
79
+ ```python
80
+ from pyphysics import Body, Box, Circle, Vec2, World
81
+
82
+ world = World(gravity=Vec2(0, -9.81))
83
+
84
+ world.add(Body.static(position=Vec2(0, -2), shape=Box(20, 1)))
85
+ ball = world.add(
86
+ Body.dynamic(
87
+ position=Vec2(0, 5),
88
+ shape=Circle(0.5),
89
+ mass=1.0,
90
+ restitution=0.55,
91
+ )
92
+ )
93
+
94
+ for _ in range(120):
95
+ world.step(1 / 60)
96
+
97
+ print(ball.position)
98
+ ```
99
+
100
+ ## 3D Quick Start
101
+
102
+ ```python
103
+ from pyphysics import Body3D, Box3D, Sphere, Vec3, World3D
104
+
105
+ world = World3D(gravity=Vec3(0, -9.81, 0))
106
+
107
+ world.add(Body3D.static(position=Vec3(0, -2, 0), shape=Box3D(20, 1, 20)))
108
+ ball = world.add(
109
+ Body3D.dynamic(
110
+ position=Vec3(0, 5, 0),
111
+ shape=Sphere(0.5),
112
+ mass=1.0,
113
+ restitution=0.55,
114
+ )
115
+ )
116
+
117
+ for _ in range(120):
118
+ world.step(1 / 60)
119
+
120
+ print(ball.position)
121
+ ```
122
+
123
+ ## Convex Shapes
124
+
125
+ ```python
126
+ from pyphysics import Body, ConvexPolygon, ConvexPolyhedron, Vec2, Vec3, World, World3D
127
+
128
+ world2 = World(gravity=Vec2())
129
+ ship = world2.add(
130
+ Body.dynamic(
131
+ shape=ConvexPolygon.regular(5, 1.0),
132
+ mass=2,
133
+ acceleration=Vec2(15, 0),
134
+ )
135
+ )
136
+
137
+ world3 = World3D(gravity=Vec3())
138
+ rock = world3.add(
139
+ Body.dynamic(
140
+ shape=ConvexPolyhedron.tetrahedron(1.0),
141
+ mass=1,
142
+ acceleration=Vec3(0, 0, 8),
143
+ )
144
+ )
145
+ ```
146
+
147
+ ## Time And Continuity
148
+
149
+ `PhysicsClock` gives the world a single place for fixed timestep state, frame
150
+ count, elapsed simulation time, and time scaling.
151
+
152
+ ```python
153
+ from pyphysics import PhysicsClock, Vec2, World
154
+
155
+ world = World(
156
+ gravity=Vec2(),
157
+ clock=PhysicsClock(fixed_dt=1 / 120, time_scale=1.0),
158
+ max_translation_per_step=0.25,
159
+ )
160
+
161
+ for stats in world.tick(elapsed=1 / 60):
162
+ print(stats.frame, stats.time, stats.substeps)
163
+ ```
164
+
165
+ Fast bodies are automatically split into substeps when `continuous=True`:
166
+
167
+ ```python
168
+ world = World(gravity=Vec2(), continuous=True, max_translation_per_step=0.25)
169
+ ```
170
+
171
+ ## Sensors And Contact Events
172
+
173
+ ```python
174
+ from pyphysics import Body, Box, Circle, Vec2, World
175
+
176
+ world = World(gravity=Vec2())
177
+ trigger = world.add(Body.static(shape=Box(3, 3), sensor=True, name="trigger"))
178
+ player = world.add(Body.dynamic(shape=Circle(0.5), position=Vec2(), mass=1, name="player"))
179
+
180
+ world.on_begin_contact = lambda contact: print(contact.a.name, contact.b.name)
181
+ stats = world.step(1 / 60)
182
+
183
+ assert stats.sensor_contacts == 1
184
+ ```
185
+
186
+ ## Examples
187
+
188
+ ```powershell
189
+ python examples/basic_scene.py
190
+ python examples/basic_scene_3d.py
191
+ ```
192
+
193
+ ## Development
194
+
195
+ Run tests:
196
+
197
+ ```powershell
198
+ python -m unittest discover -s tests -v
199
+ ```
200
+
201
+ Build distributions:
202
+
203
+ ```powershell
204
+ python -m build
205
+ ```
206
+
207
+ Check distributions before upload:
208
+
209
+ ```powershell
210
+ python -m twine check dist/*
211
+ ```
212
+
213
+ Upload to PyPI, only after choosing an available distribution name and creating
214
+ a PyPI API token:
215
+
216
+ ```powershell
217
+ python -m twine upload dist/*
218
+ ```
219
+
220
+ ## Package Status
221
+
222
+ This repository currently provides the import package `pyphysics`. The desired
223
+ PyPI command `pip install pyphysics` cannot point to this project unless the
224
+ existing PyPI owner grants access or transfers the name. A practical publishing
225
+ path is to keep the import name `pyphysics` and publish under a new distribution
226
+ name such as `pyphysics-engine`, then users would install it with:
227
+
228
+ ```powershell
229
+ python -m pip install pyphysics-engine
230
+ ```
231
+
232
+ and import it with:
233
+
234
+ ```python
235
+ import pyphysics
236
+ ```
@@ -0,0 +1,208 @@
1
+ # pyphysics
2
+
3
+ `pyphysics` is a pure-Python rigid-body physics engine with deterministic 2D and
4
+ 3D simulation APIs. It is built for games, prototypes, education, robotics
5
+ experiments, and simulation tools that need a readable engine core without
6
+ runtime dependencies.
7
+
8
+ > PyPI name note: the `pyphysics` distribution name is already owned on PyPI by
9
+ > another project. This package can still be installed locally as `pyphysics`,
10
+ > but publishing it so `pip install pyphysics` resolves to this library requires
11
+ > ownership or maintainer access to that existing PyPI project.
12
+
13
+ ## Highlights
14
+
15
+ - 2D rigid bodies: dynamic, static, and kinematic
16
+ - 3D rigid bodies: dynamic, static, and kinematic
17
+ - 2D shapes: `Circle`, `Box`, `ConvexPolygon`
18
+ - 3D shapes: `Sphere`, `Box3D`, `ConvexPolyhedron`
19
+ - SAT-based convex polygon and polyhedron collision
20
+ - Impulse collision response with restitution and friction
21
+ - Gravity, force accumulation, persistent acceleration, and damping
22
+ - Distance joints for 2D constraints
23
+ - Sensors, contact callbacks, collision categories, and collision masks
24
+ - Ray casting and AABB queries in 2D and 3D
25
+ - `PhysicsClock` for fixed timesteps, scaled time, frame count, and accumulation
26
+ - Continuous substepping for fast-moving bodies
27
+ - No runtime dependencies
28
+
29
+ ## Installation
30
+
31
+ For local development:
32
+
33
+ ```powershell
34
+ python -m pip install -e .
35
+ ```
36
+
37
+ When published under an available PyPI distribution name:
38
+
39
+ ```powershell
40
+ python -m pip install <distribution-name>
41
+ ```
42
+
43
+ The import package is always:
44
+
45
+ ```python
46
+ import pyphysics
47
+ ```
48
+
49
+ ## 2D Quick Start
50
+
51
+ ```python
52
+ from pyphysics import Body, Box, Circle, Vec2, World
53
+
54
+ world = World(gravity=Vec2(0, -9.81))
55
+
56
+ world.add(Body.static(position=Vec2(0, -2), shape=Box(20, 1)))
57
+ ball = world.add(
58
+ Body.dynamic(
59
+ position=Vec2(0, 5),
60
+ shape=Circle(0.5),
61
+ mass=1.0,
62
+ restitution=0.55,
63
+ )
64
+ )
65
+
66
+ for _ in range(120):
67
+ world.step(1 / 60)
68
+
69
+ print(ball.position)
70
+ ```
71
+
72
+ ## 3D Quick Start
73
+
74
+ ```python
75
+ from pyphysics import Body3D, Box3D, Sphere, Vec3, World3D
76
+
77
+ world = World3D(gravity=Vec3(0, -9.81, 0))
78
+
79
+ world.add(Body3D.static(position=Vec3(0, -2, 0), shape=Box3D(20, 1, 20)))
80
+ ball = world.add(
81
+ Body3D.dynamic(
82
+ position=Vec3(0, 5, 0),
83
+ shape=Sphere(0.5),
84
+ mass=1.0,
85
+ restitution=0.55,
86
+ )
87
+ )
88
+
89
+ for _ in range(120):
90
+ world.step(1 / 60)
91
+
92
+ print(ball.position)
93
+ ```
94
+
95
+ ## Convex Shapes
96
+
97
+ ```python
98
+ from pyphysics import Body, ConvexPolygon, ConvexPolyhedron, Vec2, Vec3, World, World3D
99
+
100
+ world2 = World(gravity=Vec2())
101
+ ship = world2.add(
102
+ Body.dynamic(
103
+ shape=ConvexPolygon.regular(5, 1.0),
104
+ mass=2,
105
+ acceleration=Vec2(15, 0),
106
+ )
107
+ )
108
+
109
+ world3 = World3D(gravity=Vec3())
110
+ rock = world3.add(
111
+ Body.dynamic(
112
+ shape=ConvexPolyhedron.tetrahedron(1.0),
113
+ mass=1,
114
+ acceleration=Vec3(0, 0, 8),
115
+ )
116
+ )
117
+ ```
118
+
119
+ ## Time And Continuity
120
+
121
+ `PhysicsClock` gives the world a single place for fixed timestep state, frame
122
+ count, elapsed simulation time, and time scaling.
123
+
124
+ ```python
125
+ from pyphysics import PhysicsClock, Vec2, World
126
+
127
+ world = World(
128
+ gravity=Vec2(),
129
+ clock=PhysicsClock(fixed_dt=1 / 120, time_scale=1.0),
130
+ max_translation_per_step=0.25,
131
+ )
132
+
133
+ for stats in world.tick(elapsed=1 / 60):
134
+ print(stats.frame, stats.time, stats.substeps)
135
+ ```
136
+
137
+ Fast bodies are automatically split into substeps when `continuous=True`:
138
+
139
+ ```python
140
+ world = World(gravity=Vec2(), continuous=True, max_translation_per_step=0.25)
141
+ ```
142
+
143
+ ## Sensors And Contact Events
144
+
145
+ ```python
146
+ from pyphysics import Body, Box, Circle, Vec2, World
147
+
148
+ world = World(gravity=Vec2())
149
+ trigger = world.add(Body.static(shape=Box(3, 3), sensor=True, name="trigger"))
150
+ player = world.add(Body.dynamic(shape=Circle(0.5), position=Vec2(), mass=1, name="player"))
151
+
152
+ world.on_begin_contact = lambda contact: print(contact.a.name, contact.b.name)
153
+ stats = world.step(1 / 60)
154
+
155
+ assert stats.sensor_contacts == 1
156
+ ```
157
+
158
+ ## Examples
159
+
160
+ ```powershell
161
+ python examples/basic_scene.py
162
+ python examples/basic_scene_3d.py
163
+ ```
164
+
165
+ ## Development
166
+
167
+ Run tests:
168
+
169
+ ```powershell
170
+ python -m unittest discover -s tests -v
171
+ ```
172
+
173
+ Build distributions:
174
+
175
+ ```powershell
176
+ python -m build
177
+ ```
178
+
179
+ Check distributions before upload:
180
+
181
+ ```powershell
182
+ python -m twine check dist/*
183
+ ```
184
+
185
+ Upload to PyPI, only after choosing an available distribution name and creating
186
+ a PyPI API token:
187
+
188
+ ```powershell
189
+ python -m twine upload dist/*
190
+ ```
191
+
192
+ ## Package Status
193
+
194
+ This repository currently provides the import package `pyphysics`. The desired
195
+ PyPI command `pip install pyphysics` cannot point to this project unless the
196
+ existing PyPI owner grants access or transfers the name. A practical publishing
197
+ path is to keep the import name `pyphysics` and publish under a new distribution
198
+ name such as `pyphysics-engine`, then users would install it with:
199
+
200
+ ```powershell
201
+ python -m pip install pyphysics-engine
202
+ ```
203
+
204
+ and import it with:
205
+
206
+ ```python
207
+ import pyphysics
208
+ ```
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.4
2
+ Name: newtonian-physics
3
+ Version: 0.2.0
4
+ Summary: A deterministic pure-Python 2D and 3D rigid-body physics engine.
5
+ Author: UeCollaxion-
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yourusername/newtonian-physics
8
+ Project-URL: Repository, https://github.com/yourusername/newtonian-physics
9
+ Project-URL: Issues, https://github.com/yourusername/newtonian-physics/issues
10
+ Keywords: physics,simulation,rigid-body,collision,2d,3d,game-engine
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Education
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering :: Physics
23
+ Classifier: Topic :: Games/Entertainment :: Simulation
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Dynamic: license-file
28
+
29
+ # pyphysics
30
+
31
+ `pyphysics` is a pure-Python rigid-body physics engine with deterministic 2D and
32
+ 3D simulation APIs. It is built for games, prototypes, education, robotics
33
+ experiments, and simulation tools that need a readable engine core without
34
+ runtime dependencies.
35
+
36
+ > PyPI name note: the `pyphysics` distribution name is already owned on PyPI by
37
+ > another project. This package can still be installed locally as `pyphysics`,
38
+ > but publishing it so `pip install pyphysics` resolves to this library requires
39
+ > ownership or maintainer access to that existing PyPI project.
40
+
41
+ ## Highlights
42
+
43
+ - 2D rigid bodies: dynamic, static, and kinematic
44
+ - 3D rigid bodies: dynamic, static, and kinematic
45
+ - 2D shapes: `Circle`, `Box`, `ConvexPolygon`
46
+ - 3D shapes: `Sphere`, `Box3D`, `ConvexPolyhedron`
47
+ - SAT-based convex polygon and polyhedron collision
48
+ - Impulse collision response with restitution and friction
49
+ - Gravity, force accumulation, persistent acceleration, and damping
50
+ - Distance joints for 2D constraints
51
+ - Sensors, contact callbacks, collision categories, and collision masks
52
+ - Ray casting and AABB queries in 2D and 3D
53
+ - `PhysicsClock` for fixed timesteps, scaled time, frame count, and accumulation
54
+ - Continuous substepping for fast-moving bodies
55
+ - No runtime dependencies
56
+
57
+ ## Installation
58
+
59
+ For local development:
60
+
61
+ ```powershell
62
+ python -m pip install -e .
63
+ ```
64
+
65
+ When published under an available PyPI distribution name:
66
+
67
+ ```powershell
68
+ python -m pip install <distribution-name>
69
+ ```
70
+
71
+ The import package is always:
72
+
73
+ ```python
74
+ import pyphysics
75
+ ```
76
+
77
+ ## 2D Quick Start
78
+
79
+ ```python
80
+ from pyphysics import Body, Box, Circle, Vec2, World
81
+
82
+ world = World(gravity=Vec2(0, -9.81))
83
+
84
+ world.add(Body.static(position=Vec2(0, -2), shape=Box(20, 1)))
85
+ ball = world.add(
86
+ Body.dynamic(
87
+ position=Vec2(0, 5),
88
+ shape=Circle(0.5),
89
+ mass=1.0,
90
+ restitution=0.55,
91
+ )
92
+ )
93
+
94
+ for _ in range(120):
95
+ world.step(1 / 60)
96
+
97
+ print(ball.position)
98
+ ```
99
+
100
+ ## 3D Quick Start
101
+
102
+ ```python
103
+ from pyphysics import Body3D, Box3D, Sphere, Vec3, World3D
104
+
105
+ world = World3D(gravity=Vec3(0, -9.81, 0))
106
+
107
+ world.add(Body3D.static(position=Vec3(0, -2, 0), shape=Box3D(20, 1, 20)))
108
+ ball = world.add(
109
+ Body3D.dynamic(
110
+ position=Vec3(0, 5, 0),
111
+ shape=Sphere(0.5),
112
+ mass=1.0,
113
+ restitution=0.55,
114
+ )
115
+ )
116
+
117
+ for _ in range(120):
118
+ world.step(1 / 60)
119
+
120
+ print(ball.position)
121
+ ```
122
+
123
+ ## Convex Shapes
124
+
125
+ ```python
126
+ from pyphysics import Body, ConvexPolygon, ConvexPolyhedron, Vec2, Vec3, World, World3D
127
+
128
+ world2 = World(gravity=Vec2())
129
+ ship = world2.add(
130
+ Body.dynamic(
131
+ shape=ConvexPolygon.regular(5, 1.0),
132
+ mass=2,
133
+ acceleration=Vec2(15, 0),
134
+ )
135
+ )
136
+
137
+ world3 = World3D(gravity=Vec3())
138
+ rock = world3.add(
139
+ Body.dynamic(
140
+ shape=ConvexPolyhedron.tetrahedron(1.0),
141
+ mass=1,
142
+ acceleration=Vec3(0, 0, 8),
143
+ )
144
+ )
145
+ ```
146
+
147
+ ## Time And Continuity
148
+
149
+ `PhysicsClock` gives the world a single place for fixed timestep state, frame
150
+ count, elapsed simulation time, and time scaling.
151
+
152
+ ```python
153
+ from pyphysics import PhysicsClock, Vec2, World
154
+
155
+ world = World(
156
+ gravity=Vec2(),
157
+ clock=PhysicsClock(fixed_dt=1 / 120, time_scale=1.0),
158
+ max_translation_per_step=0.25,
159
+ )
160
+
161
+ for stats in world.tick(elapsed=1 / 60):
162
+ print(stats.frame, stats.time, stats.substeps)
163
+ ```
164
+
165
+ Fast bodies are automatically split into substeps when `continuous=True`:
166
+
167
+ ```python
168
+ world = World(gravity=Vec2(), continuous=True, max_translation_per_step=0.25)
169
+ ```
170
+
171
+ ## Sensors And Contact Events
172
+
173
+ ```python
174
+ from pyphysics import Body, Box, Circle, Vec2, World
175
+
176
+ world = World(gravity=Vec2())
177
+ trigger = world.add(Body.static(shape=Box(3, 3), sensor=True, name="trigger"))
178
+ player = world.add(Body.dynamic(shape=Circle(0.5), position=Vec2(), mass=1, name="player"))
179
+
180
+ world.on_begin_contact = lambda contact: print(contact.a.name, contact.b.name)
181
+ stats = world.step(1 / 60)
182
+
183
+ assert stats.sensor_contacts == 1
184
+ ```
185
+
186
+ ## Examples
187
+
188
+ ```powershell
189
+ python examples/basic_scene.py
190
+ python examples/basic_scene_3d.py
191
+ ```
192
+
193
+ ## Development
194
+
195
+ Run tests:
196
+
197
+ ```powershell
198
+ python -m unittest discover -s tests -v
199
+ ```
200
+
201
+ Build distributions:
202
+
203
+ ```powershell
204
+ python -m build
205
+ ```
206
+
207
+ Check distributions before upload:
208
+
209
+ ```powershell
210
+ python -m twine check dist/*
211
+ ```
212
+
213
+ Upload to PyPI, only after choosing an available distribution name and creating
214
+ a PyPI API token:
215
+
216
+ ```powershell
217
+ python -m twine upload dist/*
218
+ ```
219
+
220
+ ## Package Status
221
+
222
+ This repository currently provides the import package `pyphysics`. The desired
223
+ PyPI command `pip install pyphysics` cannot point to this project unless the
224
+ existing PyPI owner grants access or transfers the name. A practical publishing
225
+ path is to keep the import name `pyphysics` and publish under a new distribution
226
+ name such as `pyphysics-engine`, then users would install it with:
227
+
228
+ ```powershell
229
+ python -m pip install pyphysics-engine
230
+ ```
231
+
232
+ and import it with:
233
+
234
+ ```python
235
+ import pyphysics
236
+ ```