Ajan API'si

Nibble, AI ajanlar tarafından kullanılmak üzere tasarlandı. Editörü aç ve window.nibble.help() çağır: bu çağrı el sıkışmadır.

Editörü aç

Altın kurallar

  1. Pikselleri tek tek gönderme. Bir sprite'ı tek drawFromText çağrısında çiz. 32×32 tuvalde piksel piksel tıklamak 1024 eylem demektir.
  2. Çok adımlı işi beginBatch("etiket") / endBatch() arasına al ki kullanıcı yaptığın her şeyi tek Ctrl+Z ile geri alabilsin.
  3. Ne çizdiğini görmek için readCanvas() kullan. Yazma formatının aynısını döndürür; ekran görüntüsü gerekmez.
  4. Her dönüş değerindeki hint alanını oku. Site seni aktif olarak yönlendiriyor.

Tipik akış

// 1: el sıkışma / handshake
await nibble.help()

// 2: palet / palette
nibble.usePalette("sweetie-16")

// 3: tek çağrıda bir sprite / a whole sprite in one call
nibble.drawFromText({
  rows: [
    "..AAAA..",
    ".AABBAA.",
    "AABBBBAA",
    "AABBBBAA",
    ".AABBAA.",
    "..AAAA..",
  ],
  legend: { A: 3, B: 4 },
  x: 12, y: 12,
})

// 4: animasyon / animation
nibble.addFrame({ copyFrom: 0 })
nibble.setPixels([{ x: 12, y: 11, c: 3 }])
nibble.setFps(10)

// 5: ne çizdiğini oku / read back what you drew
nibble.readCanvas()

İskelet: parça adıyla konuş

Bir sprite'ı kare kare yeniden çizmek bir ajan için en pahalı yol. Bunun yerine parçalara bir kez isim ver: bundan sonra “sol bacağı iki piksel yukarı al” tek çağrı. Tutamakları poz olarak anahtarlarsan aradaki kareleri Nibble üretir.

// bir parçaya isim ver / name a part: tutamak + piksel kutusu
nibble.definePart({
  name: "left_leg",
  x: 12, y: 24,                            // tutamak / handle
  box: { x: 10, y: 22, w: 5, h: 8 },       // taşınacak pikseller / pixels it carries
})

// artık piksel değil PARÇA konuşuyorsun / now you speak in parts
nibble.movePart("left_leg", 0, -2)         // tutamak + pikseller
nibble.flipPart("left_leg", "x")           // kayıpsız / lossless
nibble.recolorPart("left_leg", { to: "#b13e53" })

// poz anahtarla, aradakileri Nibble üretsin / key the poses, let Nibble fill in
nibble.addFrame({ copyFrom: 0 })
nibble.movePart("left_leg", 0, -3)
nibble.setActiveFrame(0)
nibble.tween({ count: 2 })

nibble.describeRig()   // hangi parçanın kutusu/tutamağı eksik, söyler

Sadece öteleme: ezme veya bükme yok. Pixel art deforme edilince çamura döner.

Ajan izinleri

Ajan yalnızca burada işaretli olanları yapabilir. Değişiklik anında geçerli olur.

Çizim · varsayılan: açıkPiksel boyama, kova ile doldurma, aktif kareyi temizleme.
Animasyon · varsayılan: açıkKare ekleme, FPS değiştirme, oynatma/duraklatma.
Katmanlar · varsayılan: açıkKatman ekleme, gizleme/gösterme, kilitleme, adlandırma.
Palet · varsayılan: açıkProjenin renk paletini değiştirme.
Yıkıcı işlemler · varsayılan: kapalıBoyut değiştirme, yeni proje açma, kare veya katman silme. Varsayılan kapalı.
Dosya ve ağ · varsayılan: kapalıDışa aktarım indirme ve URL'den görsel yükleme. Varsayılan kapalı.

Karşılaşacağın sınırlar

rate limit: 120 / 10s · rows ≤ 4096 · setPixels ≤ 250000 · canvas ≤ 512px · part box ≤ 2048px

Referans

help(topic?)API + canvas state + a hint for what to do next
getState() · describe()Canvas, frames, layers, palette, parts, permissions
getPermissions()What you are currently allowed to do
readCanvas(frame?)Reads back rows + legend, in the same format you write
drawFromText({rows, legend, x, y})Draw a whole sprite in one call
setPixels([{x, y, c}])Bulk pixel writes
fill(x, y, c, opts?)Flood fill
clearFrame(frame?)Clears unlocked layers of a frame
addFrame({copyFrom?}) · duplicateFrame(i)New frame (blank, or a copy)
setActiveFrame(i) · setFrameDuration(i, cs)Navigate / time frames
setFps(n) · play() · pause()Playback (fps must divide 100)
addLayer(name?) · setLayer(id, props)Layer create / visibility / lock / rename
getPalette() · setPalette([]) · usePalette(id)Colour palette
definePart({name, x, y, box?})Name a part: a handle plus the pixels it carries
setPartBox(name, box) · clearPartBox(name)Attach or detach the pixel box
setPartHandle(name, x, y)Move the handle only. This is how you key a pose
movePart(name, dx, dy, opts?)Move handle AND pixels in one undo step
flipPart(name, axis) · rotatePart(name, deg)90° multiples lossless, other angles are not
recolorPart(name, {to, from?, tolerance?})Repaint just that part
renamePart(a, b) · deletePart(name)Edit the part list
defineBone({name, from, to}) · deleteBone(name)Named link between two parts
getRig() · describeRig()The skeleton, and what is still missing from it
tween({from?, count})In-between frames from the handle positions
importImage(src, opts?)Image → pixel art (data:/blob: free, http(s) needs files)
beginBatch(label) · endBatch()Group everything into one undo step
undo() · redo()History
exportGif() · exportPng()Downloads (needs the files permission)
exportApng()Lossless animation: full RGBA alpha, no 256-colour limit
exportSpriteSheet()PNG + Aseprite JSON; rig parts become Aseprite "slices"
resize(w, h) · newProject() · deleteFrame(i) · deleteLayer(id)Destructive, off by default

AJAN NE YAPABİLİR, NE YAPAMAZ