Magnetism

Compute bounded magnetic forces between poles and neutral metal, then apply them yourself in the engine's physics step: registration, sampling, settings, saves, hooks.

Source: module-kits:kits/world_magnetism/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs world-magnetismMCP tool: gripforge_docs { "topic": "world-magnetism" }

Magnetic attraction and repulsion in your game (world.magnetism) #

What it is for #

world.magnetism computes forces between gameplay objects: opposite poles attract, equal poles repel, and neutral susceptible metal is pulled toward either pole. It is a simplified gameplay model, not an electromagnetic simulation. The kit only returns forces in newtons. It never moves a body, adds gravity or creates a second physics world: your engine applies each force once per fixed physics step and keeps mass, damping and collisions.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "world.magnetism" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "world.magnetism",
                              config: { "coupling": 100, "maxForce": 1000 } }

The kit has no requirement. Its default instance is created from the installed settings; create(id, config) adds up to 128 named instances, each a complete magnetic world.

First example #

<!-- test: kits/game_engine/host/tests/world_magnetism.rs::shared_core_drives_real_bodies_only_when_engine_applies_forces --> Two bodies are registered with opposite poles, sampled once, and the returned forces are applied by the engine. Nothing moves until the engine applies them; they then approach each other.

{ "op": "register", "id": "a", "properties": { "polarity": 1 } }
{ "op": "register", "id": "b", "properties": { "polarity": -1 } }
{ "op": "sample", "bodies": [ { "id": "a", "position": [-2, 0, 0] }, { "id": "b", "position": [2, 0, 0] } ] }

Each command is sent with the service call request("default", command). The sample answers { forces: [{ id, force }], pairs }, sorted by id, with force as a vector in newtons.

Settings and defaults #

SettingTypeDefaultMeaning
couplingnumber100Force coefficient, 0 to 1e6.
softeningnumber0.25Distance softening in metres, 0.001 to 1e6.
maxForcenumber1000Force budget per pair and per object, in newtons, 0.001 to 1e6.
maxBodiesinteger128Maximum registered objects per instance, 1 to 256.

Settings are fixed once an instance exists. Unknown fields and out-of-range values are rejected without changing state.

Services, commands and properties #

Service world.magnetism:

  • create(id, config): a new instance; duplicate ids are rejected.
  • request(id, command): runs a command.
  • remove(id): drops an instance and its forces; returns whether it existed.
  • ids(): the instance ids.

Commands: register {id, properties?}, set {id, properties}, remove {id}, clear, sample {bodies}, status, config, save, load {save}, preview {command}. A sample must list every registered object exactly once, including disabled ones; a missing, unknown or duplicate id rejects the whole sample. preview evaluates a command on a copy, and previews cannot be nested.

PropertyDefaultMeaning
polarity0-1 or 1 for a pole, 0 for neutral material.
strength1Pole strength, 0 to 1e6.
susceptibility1Response of neutral metal, 0 to 1e6. Use 0 for nonmetal.
radius10Pole range in metres.
enabledtrueWhen false, the object neither emits nor responds.
group1Category bitset (non-zero 32-bit).
mask4294967295Categories it accepts; both bodies must accept each other.

Two neutral bodies do not interact. Beyond the range the force is zero. Each pair is capped at maxForce, and the total per object is kept under the same budget while preserving equal and opposite pair forces.

Events, hooks and modding #

  • world.magnetism.created (event): an instance was created.
  • world.magnetism.removed (event): an instance was removed.
  • world.magnetism.changed (event): a decided command ran; carries the instance, the op and its result.
  • world.magnetism.refused (event): a hook cancelled a command; carries the op, who refused and why.
  • world.magnetism.create (hook): asked before an instance is created; a mod may change the config or refuse it.
  • world.magnetism.request (hook): asked before a decided command applies; a mod may change the command or cancel it.

Reads (status, config, save, preview, load) and fixed-step commands are not decisions and skip the request hook. A config may name a preset from the presets registry, merged under the config keys.

Saves #

save returns a document of schema gripforge.magnetism/1 with the configuration and the properties of every object. load is atomic and requires the same configuration. Positions, velocities and masses stay in the engine: restore them together with the magnetic save, then sample again. No cached force is replayed.

When it does not do what you expect #

  • Nothing moves: the kit returns forces only; apply each vector once as a force before the physics step.
  • A sample is rejected: it lists a missing, unknown or duplicate object, or one with a non-finite position.
  • A body is never attracted: its mask, group or enabled excludes it, or two neutral bodies are paired.
  • A force looks weaker than expected: the per-object budget maxForce scaled it down.

Limits #

No occlusion, torque, rotation alignment or material detection: your game sets the properties. Forces pass through walls; collisions stay with the engine. Work grows with the square of the object count, bounded by 256 objects.

Versions #

Kit 1.1.0 adds the hooks, presets, events and script verbs. 1.0.0 introduced the force model and saves.