一键导入
moss-physics
Integrate Moss physics library for collision detection and physics simulation. Use when working with physics bodies, shapes, collisions, or forces.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Integrate Moss physics library for collision detection and physics simulation. Use when working with physics bodies, shapes, collisions, or forces.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
ArenaModule interface (api/) — arena-composition contract per ADR-0008. ModuleCatalog, ModuleLoader, and ArenaModuleSystem are live. Author new ArenaModule classes under infinity-server/src/main/java/infinity/modules/<category>/ and register them in ModuleCatalog.
Work with Subspace Infinity arena settings — the per-arena `arena.groovy` files under `zone/arenas/`, the Groovy `conf/` preset fragment library (section/shipSection/shipSections DSL), the recursive `include` directive, the `SettingsSystem` typed accessors, and the `~loadArena`/`~swapMap` commands. Use when adding or reading settings, creating a new arena, or splitting settings fragments.
Explains the api ↔ server ↔ client layering of Subspace Infinity — which module new code belongs in, how data flows between layers, which packages live in which Gradle module, and the SimEthereal + RMI boundaries. Use when deciding where a new file should live, tracing data across layers, or explaining the project structure.
Overview of Subspace Infinity project structure, tech stack, and conventions. Use when understanding the codebase, finding files, or learning project patterns.
Create Zay-ES EntityComponent classes for the ECS architecture. Use when creating new components, data holders, or entity attributes.
Debug Entity-Component-System issues including EntitySet problems, memory leaks, and component queries. Use when troubleshooting ECS bugs or entity processing issues.
基于 SOC 职业分类
| name | moss-physics |
| description | Integrate Moss physics library for collision detection and physics simulation. Use when working with physics bodies, shapes, collisions, or forces. |
Moss is the custom physics library for Subspace Infinity, integrated via sio2-mphys.
Moss must be built from source and published locally:
cd ~/github/assofohdz/moss
./gradlew publishToMavenLocal
The main physics system that manages the physics space:
import com.simsilica.ext.mphys.MPhysSystem;
import com.simsilica.mblock.phys.MBlockShape;
import com.simsilica.mphys.PhysicsSpace;
// Get the physics system
MPhysSystem<MBlockShape> physics = (MPhysSystem<MBlockShape>) getSystem(MPhysSystem.class, true);
// Get the physics space for direct manipulation
PhysicsSpace<EntityId, MBlockShape> space = physics.getPhysicsSpace();
// Get rigid body from physics space
RigidBody<EntityId, MBlockShape> rb = physics.getPhysicsSpace()
.getBinIndex()
.getRigidBody(entityId);
// Get static body
StaticBody<EntityId, MBlockShape> sb = physics.getPhysicsSpace()
.getBinIndex()
.getStaticBody(entityId);
Register custom initialization for physics bodies:
// In your system's initialize()
physics.getBodyFactory().addDynamicInitializer(new MyBodyInitializer());
// Initializer class
public class MyBodyInitializer implements BodyInitializer<EntityId, MBlockShape> {
@Override
public void initialize(RigidBody<EntityId, MBlockShape> body) {
// Custom initialization
}
}
public class ContactSystem<K, S extends AbstractShape> extends AbstractGameSystem
implements ContactListener<EntityId, MBlockShape> {
private MPhysSystem<?> physics;
@Override
protected void initialize() {
physics = getSystem(MPhysSystem.class);
physics.getPhysicsSpace().getContactDispatcher().addListener(this);
}
@Override
public void newContact(Contact contact) {
RigidBody<EntityId, MBlockShape> bodyOne = contact.body1;
AbstractBody<EntityId, MBlockShape> bodyTwo = contact.body2;
if (bodyTwo != null) {
EntityId one = bodyOne.id;
EntityId two = bodyTwo.id;
// Filter contacts
if (shouldDisable(one, two)) {
contact.disable();
return;
}
}
// Set restitution for bouncing
contact.restitution = 1.0f;
// CAUTION — body-vs-static friction: do NOT set contact.friction on body-vs-static
// contacts when the body is a sphere (ship). The resolver computes r × impulse torque
// at the contact point, which wrongly rotates the ship heading. Instead, keep
// contact.friction = 0.0 and damp body1.linearVelocity's tangential component
// manually after the step. See ContactSystem for the reference implementation.
}
}
// Use CollisionCategory component with CategoryFilter
CollisionCategory category = ed.getComponent(entityId, CollisionCategory.class);
CategoryFilter filter = category.getFilter();
// Check if collision allowed
if (!filterTwo.isAllowed(filterOne)) {
contact.disable();
}
MPhysSystem<S> system = getPhysicsSystem();
system.addPhysicsListener(myPhysicsObserver);
system.getBinEntityManager().addObjectStatusListener(myStatusListener);
public class PhysicsObserver implements PhysicsListener<EntityId, S>,
ObjectStatusListener<S> {
@Override
public void startFrame(long frameTime, double stepSize) {
// Called at start of physics frame
}
@Override
public void endFrame() {
// Called at end of physics frame
}
@Override
public void update(RigidBody<EntityId, S> body) {
// Called when body position updates
boolean active = !body.isSleepy();
Vec3d position = body.position;
Quatd orientation = body.orientation;
}
@Override
public void objectLoaded(EntityId id, RigidBody<EntityId, S> body) {
// Body became active
}
@Override
public void objectUnloaded(EntityId id, RigidBody<EntityId, S> body) {
// Body deactivated
}
}
For AI-controlled physics entities:
public class MobDriver implements ControlDriver<MBlockShape> {
private final MPhysSystem<MBlockShape> physics;
private final EntityId mob;
public MobDriver(MPhysSystem<MBlockShape> physics, EntityId mob) {
this.physics = physics;
this.mob = mob;
}
// Implement control methods for steering
}
public class MovementSettings {
public float groundImpulse = 40;
public float airImpulse = 25;
public float movementSpeed = 2;
}
ShapeFactoryRegistry<MBlockShape> shapeFactory = new ShapeFactoryRegistry<>();
registerShapeFactories(shapeFactory, ed);
systems.register(ShapeFactory.class, shapeFactory);
ShapeInfo - defines shape and massCollisionCategory - collision filteringParent - parent-child relationships (skip collisions)AttackVelocity - projectile velocitiesEntityId entity = ed.createEntity();
ed.setComponents(entity,
new Position(x, y, z),
new ShapeInfo(ShapeNames.SHIP, mass),
new CollisionCategory(CategoryFilter.PLAYER)
);