bullet-heaven.ahraz.me
An agent-ready bullet hell maker built with Phaser and WebMCP.
First seen 2026-11-05 · Last seen 2026-11-05 · Source: webmcp.com
Answer 4 · Act 15 · Transact 1 · Score: Not yet scored
Tool inspector
edit_emitter
Adds, updates, or removes a positioned emitter, covering its presentation, size, combat, lifetime, movement and simple firing settings, and returns { action, waveId, emitterId, emitter, waveCount, emitterCount } with the affected emitter in full. Remove reports the ids and the new counts with no emitter. fireInterval, projectileSpeed and aimMode are a shortcut that edits the emitter's first firing pattern; edit_firing_pattern handles bursts, formations and projectile motion. The result reflects the state after this call, so no follow-up read is needed. The result's 'evaluation' reports whether the project has been measured since it changed; on verified: false, run evaluate_encounter before calling the edit an improvement. This returns to the editor first, on its own. From a landing page or shared play link that needs a page load, it opens the editor and asks you to retry once WebMCP reconnects rather than editing during teardown. Call get_maker_state immediately before this: the person edits the same live state you do.
Page: /editor
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
action |
string | yes | 'add' generates the emitterId and rejects one you supply. 'update' and 'remove' require emitterId, and 'remove' accepts nothing but the ids. |
waveId |
string | yes | The wave the emitter belongs to. |
emitterId |
string | no | The emitter to change. Required to update or remove, omitted to add. |
name |
string | no | — |
enabled |
boolean | no | — |
x |
number | no | Horizontal position, normalized 0-1 across the arena. Values slightly outside that range place the emitter off-screen. |
y |
number | no | Vertical position, normalized 0-1 across the arena. |
angle |
number | no | Facing in screen-space degrees: 0 points right and -90 points up. |
radius |
number | no | Body size in pixels. This is also the damage circle, so a smaller emitter is harder to hit. |
visibleInPlay |
boolean | no | Whether the body is drawn during Play. It still fires when hidden. |
combatType |
string | no | 'destructible' can be shot down. 'invulnerable' cannot, and rejects hitPoints and countsTowardClear. |
hitPoints |
integer | no | Shots to destroy. Requires combatType destructible. |
countsTowardClear |
boolean | no | Whether the wave waits for this emitter to be defeated. Requires combatType destructible; when true the lifetime must be until_defeated, because the wave is waiting for it. |
lifetimeType |
string | no | 'until_defeated' lasts until shot down and is the only lifetime valid for an emitter that counts toward wave clear. 'duration' needs lifetimeSeconds. 'until_wave_complete' disappears when the wave ends. |
lifetimeSeconds |
number | no | Seconds the emitter lives. Required by, and only valid with, lifetimeType duration. |
movementType |
string | no | 'patrol' moves between (x, y) and (endX, endY) and needs all three patrol fields; 'stationary' rejects them. |
endX |
number | no | Patrol endpoint, normalized like x. Requires movementType patrol. |
endY |
number | no | Patrol endpoint, normalized like y. Requires movementType patrol. |
movementSpeed |
number | no | Patrol speed in pixels per second. Requires movementType patrol. |
fireInterval |
number | no | Seconds between enemy shots. Same setting as the pattern's interval. |
projectileSpeed |
number | no | Enemy projectile speed in pixels per second. Same setting as the pattern's speed. |
aimMode |
string | no | 'at_player' samples the player's position each volley; 'fixed' fires along the emitter's angle. |
Raw JSON schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"add",
"update",
"remove"
],
"description": "'add' generates the emitterId and rejects one you supply. 'update' and 'remove' require emitterId, and 'remove' accepts nothing but the ids."
},
"waveId": {
"type": "string",
"minLength": 1,
"description": "The wave the emitter belongs to."
},
"emitterId": {
"type": "string",
"minLength": 1,
"description": "The emitter to change. Required to update or remove, omitted to add."
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"enabled": {
"type": "boolean"
},
"x": {
"type": "number",
"minimum": -0.5,
"maximum": 1.5,
"description": "Horizontal position, normalized 0-1 across the arena. Values slightly outside that range place the emitter off-screen."
},
"y": {
"type": "number",
"minimum": -0.5,
"maximum": 1.5,
"description": "Vertical position, normalized 0-1 across the arena."
},
"angle": {
"type": "number",
"minimum": -180,
"maximum": 180,
"description": "Facing in screen-space degrees: 0 points right and -90 points up."
},
"radius": {
"type": "number",
"minimum": 2,
"maximum": 64,
"description": "Body size in pixels. This is also the damage circle, so a smaller emitter is harder to hit."
},
"visibleInPlay": {
"type": "boolean",
"description": "Whether the body is drawn during Play. It still fires when hidden."
},
"combatType": {
"type": "string",
"enum": [
"destructible",
"invulnerable"
],
"description": "'destructible' can be shot down. 'invulnerable' cannot, and rejects hitPoints and countsTowardClear."
},
"hitPoints": {
"type": "integer",
"minimum": 1,
"maximum": 999,
"description": "Shots to destroy. Requires combatType destructible."
},
"countsTowardClear": {
"type": "boolean",
"description": "Whether the wave waits for this emitter to be defeated. Requires combatType destructible; when true the lifetime must be until_defeated, because the wave is waiting for it."
},
"lifetimeType": {
"type": "string",
"enum": [
"until_defeated",
"duration",
"until_wave_complete"
],
"description": "'until_defeated' lasts until shot down and is the only lifetime valid for an emitter that counts toward wave clear. 'duration' needs lifetimeSeconds. 'until_wave_complete' disappears when the wave ends."
},
"lifetimeSeconds": {
"type": "number",
"minimum": 0,
"maximum": 3600,
"description": "Seconds the emitter lives. Required by, and only valid with, lifetimeType duration."
},
"movementType": {
"type": "string",
"enum": [
"stationary",
"patrol"
],
"description": "'patrol' moves between (x, y) and (endX, endY) and needs all three patrol fields; 'stationary' rejects them."
},
"endX": {
"type": "number",
"minimum": -0.5,
"maximum": 1.5,
"description": "Patrol endpoint, normalized like x. Requires movementType patrol."
},
"endY": {
"type": "number",
"minimum": -0.5,
"maximum": 1.5,
"description": "Patrol endpoint, normalized like y. Requires movementType patrol."
},
"movementSpeed": {
"type": "number",
"minimum": 1,
"maximum": 1200,
"description": "Patrol speed in pixels per second. Requires movementType patrol."
},
"fireInterval": {
"type": "number",
"minimum": 0.05,
"maximum": 30,
"description": "Seconds between enemy shots. Same setting as the pattern's interval."
},
"projectileSpeed": {
"type": "number",
"minimum": 20,
"maximum": 2000,
"description": "Enemy projectile speed in pixels per second. Same setting as the pattern's speed."
},
"aimMode": {
"type": "string",
"enum": [
"at_player",
"fixed"
],
"description": "'at_player' samples the player's position each volley; 'fixed' fires along the emitter's angle."
}
},
"required": [
"action",
"waveId"
],
"additionalProperties": false
}
Similar websites
wfsim.app
A Warframe calculator that simulates the fight instead of estimating it — builder, simulator, optimizer. Every formula cites its source, and the golden tests ar…
commonplace-webmcp.vercel.app
Commonplace is an editable social reading space built for people and their browser agents.
pixelforge-studio.appcaster.chatgpt.site
A professional browser pixel-art editor for drawing, frame animation, palettes, sprite sheets, GIF export, and WebMCP automation.
pixelite.taskcraft.site
Pixelite