The Diablo Duck
As a kid I used game trainers for Diablo: little programs that found your gold in memory and let you change it. Last Friday I wanted to know how they worked. Two days later, Diablo's warrior was a rubber duck with eighty-five animations, a voice line in my own voice, and two menus inside the game that didn't exist on Thursday.
I did it with Claude Code, Anthropic's LLM coding tool, in my terminal. It generated nearly all of the code. I made the calls: what looked wrong, what mattered, when to stop and preview. This post walks through it in order, including the wrong turns, because the wrong turns are where the interesting parts are. It's long. It's also written so another LLM could pick this project up later; there's a structured summary at the end.
1A trainer the 1998 way
The game is DevilutionX, an open-source rebuild of Diablo that runs natively on a modern Mac, with the free shareware data. The original trainers had no map of where anything lived in memory. They searched for it.
You have 112 gold. Scan the whole game for the number 112: about seventeen thousand hits. Pick up some gold so you have 122, and scan only those hits for 122. Two addresses left. Write 5,000 to both, and the game shows 5,000.
Why two? One is the total; the other is the gold pile item in your inventory. The game recalculates the total from the piles, so writing only the total gets undone. That was the first lesson: the number on screen is often derived from something else.
From there the trainer became a small web page with live Gold, Health and Mana, a Lock button, and later commands to learn spells and max out stats. It reads and writes the game's memory directly. That needed a copy of the game re-signed so macOS allows another program to attach to it.
2The first duck, and why image generators failed
The warrior's sprites are pre-rendered: Blizzard built a 3D model in the 90s and rendered it from eight angles, every frame of every animation, then reduced the results to a 256-color palette. Each animation is a file of eight strips of frames.
The first try was the obvious one: ask image generators for a duck sprite sheet.


Every frame was a slightly different duck: different bill, different eyes, different proportions. Animation needs the same duck in every frame. The fix was to do what Blizzard did: one 3D model in Blender, rendered from eight angles. Since it's always the same model, it's always the same duck.
3Waving, then slapping, then slicing
The first 3D attack looked fine in a still and wrong in motion. The duck swept his sword sideways across his front, as if waving it at the monster. The swing was turning the wrong way. Fixing that gave an overhead chop that hit with the flat of the blade: he was slapping enemies. The blade's wide side faced forward. Turning the blade a quarter turn on its own axis made him slice.
Each of these meant a full render, minutes long at the time. So the second thing built was a preview: a few key frames from a few angles at low quality, in seconds, with a red box showing the game's frame so you can see what gets clipped. The shadow running off the left edge got caught that way.
4The palette fights back
In the dungeon the duck glowed like a toy under studio lights. Diablo's art is painted dark. Darkening him turned him khaki, because the game's palette has almost no dark, saturated yellows; every darker yellow lands on the nearest color it has, which is olive.

Then the bill turned blue. An earlier experiment had added a palette swap that recolored the warrior's shield blue. The game applies it to every warrior sprite, including the duck, and it repainted a range of reds as blues, which included the duck's darker oranges. The fix was to drop the swap, since the duck's shield is blue in the model anyway. The lesson stuck: anything that recolors a sprite at load time recolors everything that uses those colors.
5Seeing changes immediately
Partway through I asked for a talk I'd seen years ago, Bret Victor's Inventing on Principle. His principle is that creators need an immediate connection to what they create: make a change, see the effect, nothing hidden. I'd adopted it as my own, and it became the test for the tools:
- Reload in the running game. The game loads a sprite only when its slot in memory is empty. The trainer clears those slots, and the new sprites appear on the duck's next step. No restart.
- A previewer in the web app: every warrior animation, the original next to the duck, at game speed with the game's sound effects on the right frames. It watches the mod folder, so a new sprite shows up by itself.
- A 3D viewer: the duck model in the browser, orbitable, reloading whenever the model script changes.
- One command to the saved game, skipping the intro and menus.


6From snowman to rubber duck, using a real duck
Seen next to the warrior at game size, the duck was a snowman: two stacked balls, a disc for a bill, boxes for feet. I took photos of an actual rubber duck I have, a black eight-ball one, from the side, the front and the top. The best ones were shot level and square-on, the way an artist would set up reference.



Instead of eyeballing proportions, a script traced the duck's outline from each photo, rendered the 3D model from the same angle at the same height, and overlaid the two. White is where they agree, green is only the photo, magenta is only the model. Each round, Claude Code generated an edit to the model script and the overlay ran again.

The body is built from metaballs, blobby shapes that melt into each other, so the head joins the body without a seam. One trick: a "negative" blob that carves material away, used to cut the dip between the head and the tail.
Then came the details, each from a note of mine and a round of previews:
- The bill. First a flat disc, then two discs, then a pursed shape that looked like a finch's beak. A rubber duck's bill is a broad spoon: running front to back it dips, then flips up at the tip, with a crest along the lips, and its base climbs onto the face in an arch.
- The tuft. The little swoop of "hair" that sells a rubber duck. Two bumps looked wrong. One soft dollop, like the toothpaste in a commercial, then lowered to a hint.
- The eyes. Painted-on decals, not beads: upright ovals, pupils toward the front, and the glint on the same side in both eyes, because there's one light. Set too far apart, he looked like a fish.
- The feet. Webbed, three toes with scalloped webbing, set back under his center so he doesn't look about to tip over.



7Eighty-five animations
The warrior has one animation set per weapon setup: sword and shield, sword, shield, nothing, club and shield, club, bow, staff, axe. Each has a stand, a walk, an attack, getting hit, three spell casts, and a town stand and walk. The shield setups add a block, and only the unarmed set has a death. In the shareware data that's 85 files.
Some things only showed up when every animation sat side by side:
- Spell effects are painted into the warrior's sprites. Repair's dust tornado, the fire, the lightning: they're part of his cast animations, not drawn by the game. Swap in the duck and they vanish. They're now modeled in Blender and rendered as a separate pass that isn't dimmed with the duck, so they stay as bright as the originals.
- Matching the warrior, not my imagination. The first poses were generic. Side by side, the warrior holds his weapon on guard in front of him; the duck held his out at his sides. Every dungeon pose was redone from a reference sheet of the warrior's own stances and swings. A staff that chopped like a club became a horizontal sweep, the staff fighter's side strike.
- The death. A rubber duck goes belly-up: wobbles, tips over backward, feet in the air, one bounce.






8From eighty minutes to eight seconds
A full rebuild of every animation started at well over an hour. Measuring where the time went, instead of guessing, found most of it was overhead:
| Change | Why it helped |
|---|---|
| Cycles to EEVEE | Path tracing is wasted on a sprite that ends up 33 pixels tall in 256 colors. The real-time renderer was about 15 times faster per frame and looked the same at game size. |
| 16 samples to 4 | Another 2.2 times; a side-by-side at game resolution showed no visible difference. |
| One Blender session per worker | Starting Blender for every animation cost seconds each. |
| Parallel workers | The M3 had spare capacity. |
| numpy for the palette conversion | The pixel-by-pixel Python loop was the slow step once rendering got fast. |
| Skip what didn't change | Most edits touch one animation. |
Changing one animation now takes about 8 seconds, start to finish, including the reload in the running game. Changing the whole duck takes about fifteen minutes. Getting that under a minute would mean renting GPUs in the cloud, or putting an old PC to work. That's a later problem.
9My voice as Cain
Cain the Elder greets you with his famous line. A small script records your own version: a beep, you speak, it trims the silence, matches the original's loudness, converts it to the game's format and installs it. The game streams voice lines from disk, so the next time you click Cain, he's you. The first takes were choppy because the recording tool was dropping audio. Switching recorders fixed it, and the beep that started recording got trimmed out of the take.
10Menus inside the game
A web page for the trainer works, but I wanted it in the game. That meant building DevilutionX from source with a patch. Pressing T opens a trainer in the quest log's panel: god mode, fill health and mana, gold, level up, max stats, learn all spells, repair, and give a bow, an axe and a staff. Actions go through the game's own functions, so derived numbers stay consistent and everything saves normally. The memory edits from outside didn't survive a restart; these do.
Before the patched game ran, a script (generated with Claude Code) drew the menu offline from the game's own files: the panel art, the font, the spinning pentagram selector, placed with the same coordinates the code uses. The mockup and the real thing match.


Y opens the item cycler: the inventory panel with arrows beside the hand slots. The arrows preview every weapon and shield, and the backpack area becomes a readout of what's equipped against what's previewed: damage or armor, requirements, and which of the duck's animation sets it will use. Apply equips it. It's also the fastest way to check all nine weapon setups' animations.

11Side quests, parked
- The browser. DevilutionX can compile to WebAssembly, and the patched build compiled on the second try. That would let family without Macs play. It can't ship the game data, though, which is Blizzard's, so Microsoft's: visitors would supply their own.
- A render farm. Planned and costed, not built.
- Menu ideas for later: slow motion and frame stepping, duck skins (an eight-ball duck), photo mode, a soundboard.
12Next installment
Diablo's warrior has three armor classes, light, medium and heavy, each with a complete set of animations. The game picks the set from your chest armor. That's 255 animations, 170 more than the duck has. The shareware data only includes light armor, so the other two need the full game's data. And the duck needs a design for it: perhaps a little helmet for medium and a breastplate for heavy. That's part two.
For the next LLM: structured summary
Project: ~/Projects/diablo-trainer (git). Game: DevilutionX 1.5.5, shareware spawn.mpq. setup.sh fetches pinned dependencies.
| Area | Files | Notes |
|---|---|---|
| Trainer | agent.py, web/, scan.py | mach memory access to a re-signed copy (get-task-allow). Player record found by name; offsets verified live. agent.py reload clears sprite slots so new files load. |
| Duck model | duck_render.py | Blender script: metaball body, sculpted bill, decal eyes, webbed feet, weapons on pivots, a guard pose per weapon, a pose() per animation, effects as a second pass (DUCK_PASS=fx). |
| Build | build_fast.py, render_batch.py, duck3d_np.py | EEVEE, 4 samples, parallel Blender sessions, numpy conversion to the game palette (player colors 128-255), skip-unchanged stamps. |
| Checking | preview.sh, look.sh, fit_photo.sh, make_reel.py | Previews, one frame at game resolution, photo outline overlays, MP4 reel with sound. |
| Live tools | web/app/preview, web/app/duck | Next.js: animation previewer (watches mods/), 3D glTF viewer (reloads on script edits). |
| Game patch | patches/devilutionx-1.5.5-trainer-menu.patch, build_game.sh | T trainer menu (quest log panel), Y item cycler (inventory panel), god mode hook. Build flags documented in the script. |
| Voice | voice.sh | SoX recording, cue trimming, loudness match, MP3 into mods/sfx/. |
| Docs | docs/animations.md, docs/pipeline.md, docs/todo.md | Running list, pipeline decisions, parked ideas. |
Gotchas worth knowing: image generators can't keep a character consistent across frames; palette swaps (TRN) recolor every warrior sprite; the warrior's spell effects are baked into his sprites; gold is items plus a derived total; memory edits don't persist across a restart, game-function edits do; check the screen is unlocked before sending keystrokes; ask "bow and arrow or bo staff?"
子どものころ、Diablo でゲームトレーナーを使っていました。メモリの中から所持ゴールドを見つけて、書き換えさせてくれる小さなプログラムです。先週の金曜日、その仕組みが知りたくなりました。二日後、Diablo の戦士はラバーダックになっていました。アニメーションは85種類、私自身の声のボイス、そして木曜日にはなかったゲーム内のメニューが二つ。
使ったのは Claude Code です。Anthropic の LLM コーディングツールで、私のターミナルで動きます。コードはほぼすべて Claude Code が生成しました。判断は私がしました。何がおかしく見えるか、何が大事か、いつ止めてプレビューするか。この記事では、回り道も含めて順を追って書きます。面白いところは回り道にあるからです。長い記事です。別の LLM があとでこのプロジェクトを引き継げるようにも書いていて、最後に構造化した要約があります。
11998年流のトレーナー
ゲームは DevilutionX です。Diablo をオープンソースで作り直したもので、最新の Mac でネイティブに動き、無料のシェアウェア版データで遊べます。昔のトレーナーには、メモリのどこに何があるかの情報がありませんでした。探していたのです。
所持ゴールドが112だとします。ゲーム全体から112という数字を探すと、約一万七千件ヒットします。ゴールドを拾って122にし、さっきのヒットの中だけから122を探します。残るアドレスは二つ。両方に5,000を書き込むと、ゲームの表示も5,000になります。
なぜ二つなのか。一つは合計で、もう一つはインベントリにあるゴールドの山というアイテムです。ゲームは山から合計を計算し直すので、合計だけ書き換えても元に戻されます。これが最初の教訓でした。画面に出ている数字は、別の何かから計算されていることが多い。
そこからトレーナーは小さなウェブページになりました。ゴールド、ライフ、マナをリアルタイムで表示し、ロックボタンがあり、のちに呪文を覚えたり能力値を最大にしたりするコマンドも加わりました。ゲームのメモリを直接読み書きします。そのためには、別のプログラムがアタッチすることを macOS が許すように、ゲームのコピーに署名し直す必要がありました。
2最初のアヒルと、画像生成がうまくいかなかった理由
戦士のスプライトはプリレンダリングです。Blizzard は90年代に3Dモデルを作り、すべてのアニメーションのすべてのフレームを八つの角度からレンダリングし、その結果を256色のパレットに落としました。アニメーション一つが、フレームの帯が八本入ったファイル一つです。
最初に試したのは分かりやすい方法でした。画像生成ツールにアヒルのスプライトシートを頼むことです。


どのフレームも少しずつ違うアヒルでした。くちばしも、目も、体の比率も違う。アニメーションには、すべてのフレームで同じアヒルが必要です。解決策は、Blizzard と同じことをすることでした。Blender で3Dモデルを一つ作り、八つの角度からレンダリングする。いつも同じモデルなので、いつも同じアヒルです。
3振って見せる、はたく、そして斬る
最初の3Dの攻撃は、静止画では問題なく、動かすとおかしく見えました。アヒルは剣を体の前で横に払っていて、まるでモンスターに剣を振って見せているようでした。振りの回転方向が逆だったのです。それを直すと上からの振り下ろしになりましたが、刃の平らな面で当たっていました。敵をはたいていたのです。刃の広い面が前を向いていました。刃をその軸のまわりに90度回すと、斬るようになりました。
どれも完全なレンダリングが必要で、当時は一回に何分もかかりました。だから二番目に作ったのはプレビューです。いくつかのキーフレームを、いくつかの角度から、低画質で、数秒で出します。ゲームの表示枠を赤い枠で示すので、どこが切れるかが分かります。影が左端からはみ出しているのも、それで見つかりました。
4パレットの逆襲
ダンジョンの中で、アヒルはスタジオ照明の下のおもちゃのように光っていました。Diablo の絵は暗く描かれています。アヒルを暗くすると、カーキ色になりました。ゲームのパレットには、暗くて彩度の高い黄色がほとんどないからです。暗い黄色はどれも、パレットにある一番近い色、つまりオリーブ色に落ちます。

次はくちばしが青くなりました。以前の実験で、戦士の盾を青く塗り替えるパレットスワップを入れていたのです。ゲームはそれを戦士のすべてのスプライトに適用します。アヒルも含めてです。そしてそれはある範囲の赤を青に塗り替えていて、そこにアヒルの暗めのオレンジが入っていました。解決策はスワップをやめることでした。アヒルの盾は、モデルの段階でもともと青いからです。教訓は残りました。読み込み時にスプライトの色を塗り替えるものは、その色を使うものすべてを塗り替えます。
5変更をすぐに見る
途中で、何年も前に見た講演を探してもらいました。Bret Victor の Inventing on Principle です。彼の原則は、作り手は自分が作るものと即座につながっていなければならない、というものです。変更したらすぐ効果が見え、何も隠れていない。私はそれを自分の原則として取り入れていて、それがツールを判断する基準になりました。
- 動いているゲームの中で再読み込み。ゲームは、メモリ上のスロットが空のときにだけスプライトを読み込みます。トレーナーがそのスロットを空にすると、アヒルが次に一歩踏み出したときに新しいスプライトが現れます。再起動は要りません。
- ウェブアプリのプレビューア:戦士のすべてのアニメーションを、元の戦士とアヒルを並べて、ゲームと同じ速度で、ゲームの効果音を正しいフレームに付けて再生します。mod フォルダを監視しているので、新しいスプライトは自動で表示されます。
- 3Dビューア:ブラウザの中のアヒルのモデル。回して見ることができ、モデルのスクリプトが変わるたびに再読み込みします。
- セーブデータまでコマンド一つ。オープニングとメニューを飛ばします。


6雪だるまからラバーダックへ、実物のアヒルを使って
ゲームと同じ大きさで戦士の隣に並べると、アヒルは雪だるまでした。球が二つ重なって、くちばしは円盤、足は箱。そこで、手元にある実物のラバーダック、黒いエイトボールのアヒルを、横、正面、上から撮影しました。一番よかったのは、水平に、真正面から撮ったものです。画家が資料を用意するときのように。



比率を目分量で決める代わりに、スクリプトが各写真からアヒルの輪郭をなぞり、同じ角度・同じ高さで3Dモデルをレンダリングして、二つを重ねました。白は一致しているところ、緑は写真だけ、マゼンタはモデルだけです。毎回、Claude Code がモデルのスクリプトの編集を生成し、重ね合わせをもう一度実行しました。

体はメタボールでできています。互いに溶け合う、ぷよぷよした形です。だから頭と体が継ぎ目なくつながります。工夫が一つあります。素材を削り取る「マイナス」のボールで、頭と尾のあいだのくぼみを作りました。
それから細部です。どれも、私のメモ一つとプレビュー一巡から生まれました。
- くちばし。最初は平らな円盤、次に円盤二枚、次はすぼめた形で、フィンチのくちばしのようでした。ラバーダックのくちばしは幅の広いスプーンです。前から後ろへたどると、いったんくぼみ、先端で反り上がります。唇に沿って稜線があり、根元はアーチを描いて顔の上に乗っています。
- 冠羽。ラバーダックらしさを決める、小さな「髪」のカール。突起二つでは変でした。CM の歯磨き粉のような、ふんわりした一盛りにして、それからほのめかす程度まで低くしました。
- 目。ビーズではなく、描かれたデカールです。縦長の楕円で、瞳は前寄り、ハイライトは両目とも同じ側。光は一つだからです。離しすぎると、魚のような顔になりました。
- 足。水かきつきで、三本の指のあいだに波形の水かきがあります。重心の下、少し後ろに置いて、倒れそうに見えないようにしました。



785のアニメーション
戦士には、武器の組み合わせごとにアニメーションのセットがあります。剣と盾、剣、盾、素手、こん棒と盾、こん棒、弓、杖、斧。それぞれに、立ち、歩き、攻撃、被弾、三種類の呪文詠唱、町での立ちと歩きがあります。盾のあるセットには防御が加わり、死亡があるのは素手のセットだけです。シェアウェア版のデータでは、合わせて85ファイルです。
すべてのアニメーションを並べて、初めて見えたこともあります。
- 呪文のエフェクトは戦士のスプライトに描き込まれている。Repair の砂ぼこりの竜巻、炎、稲妻。これらはゲームが描いているのではなく、戦士の詠唱アニメーションの一部です。アヒルに差し替えると消えてしまいます。今は Blender でモデル化し、アヒルと一緒には暗くしない別パスとしてレンダリングしているので、元と同じ明るさのままです。
- 私の想像ではなく、戦士に合わせる。最初のポーズはありきたりでした。並べてみると、戦士は武器を体の前に構えています。アヒルは両脇に広げて持っていました。ダンジョンでのポーズはすべて、戦士自身の構えと振りを集めた参照シートから作り直しました。こん棒のように振り下ろしていた杖は、横払いになりました。杖で戦う者の横打ちです。
- 死亡。ラバーダックはお腹を上にしてひっくり返ります。ぐらついて、後ろに倒れ、足を宙に上げて、一回弾みます。






880分から8秒へ
全アニメーションの再ビルドは、最初は一時間を大きく超えていました。推測ではなく、時間がどこにかかっているかを測ってみると、大半はオーバーヘッドでした。
| 変更 | 効果があった理由 |
|---|---|
| Cycles から EEVEE へ | 最終的に256色で高さ33ピクセルになるスプライトに、パストレーシングは無駄です。リアルタイムレンダラーは1フレームあたり約15倍速く、ゲームのサイズでは見た目も同じでした。 |
| サンプル数を16から4へ | さらに2.2倍。ゲームの解像度で並べて比べても、目に見える違いはありませんでした。 |
| ワーカーごとに Blender セッションを一つ | アニメーションごとに Blender を起動すると、一回ごとに数秒かかっていました。 |
| 並列ワーカー | M3 には余力がありました。 |
| パレット変換に numpy | レンダリングが速くなると、ピクセルを一つずつ回す Python のループが遅い工程になっていました。 |
| 変わっていないものは飛ばす | ほとんどの編集は、アニメーション一つにしか関わりません。 |
アニメーション一つの変更は、今では最初から最後まで約8秒です。動いているゲームでの再読み込みも含めてです。アヒル全体を変えると約15分。それを一分以内にするには、クラウドで GPU を借りるか、古い PC を働かせることになります。それはまた今度の問題です。
9私の声の Cain
長老 Cain は、おなじみのセリフで出迎えてくれます。小さなスクリプトで、自分版を録音できます。ビープ音が鳴ったら話す。スクリプトが無音を切り取り、元の音量に合わせ、ゲームの形式に変換してインストールします。ゲームはボイスをディスクからストリーミングするので、次に Cain をクリックすると、彼は私になっています。最初の録音は途切れ途切れでした。録音ツールが音を取りこぼしていたのです。録音ツールを替えたら直り、録音開始のビープ音もテイクから切り取られるようになりました。
10ゲームの中のメニュー
トレーナーはウェブページでも動きますが、ゲームの中に入れたくなりました。そのためには、パッチを当てて DevilutionX をソースからビルドする必要がありました。T を押すと、クエストログのパネルにトレーナーが開きます。無敵モード、ライフとマナの全回復、ゴールド、レベルアップ、能力値の最大化、全呪文の習得、修理、そして弓、斧、杖の付与。操作はゲーム自身の関数を通すので、計算で出る数値も整合したままで、すべて普通にセーブされます。外からのメモリ書き換えは再起動すると消えましたが、こちらは残ります。
パッチを当てたゲームを動かす前に、スクリプト(Claude Code で生成)がゲーム自身のファイルからメニューをオフラインで描きました。パネルの絵、フォント、回転する五芒星の選択カーソルを、コードと同じ座標で配置しています。モックアップと実物は一致しています。


Y を押すとアイテムサイクラーが開きます。インベントリのパネルで、手のスロットの横に矢印が付きます。矢印ですべての武器と盾をプレビューでき、バックパックの部分は、装備中のものとプレビュー中のものを比べる表示になります。ダメージや防御力、必要能力値、そしてアヒルのどのアニメーションセットが使われるか。Apply で装備します。九つの武器の組み合わせのアニメーションを確かめる、一番速い方法でもあります。

11寄り道、保留中
- ブラウザ。DevilutionX は WebAssembly にコンパイルでき、こちらのパッチ版も二回目でできました。Mac を持っていない家族も遊べるようになります。ただしゲームデータは配布できません。データは Blizzard のもの、つまり Microsoft のものです。訪れた人が自分で用意することになります。
- レンダーファーム。計画して費用も見積もりましたが、作ってはいません。
- 今後のメニューのアイデア:スローモーションとコマ送り、アヒルのスキン(エイトボールのアヒル)、フォトモード、サウンドボード。
12次回
Diablo の戦士には、軽装、中装、重装の三つの鎧クラスがあり、それぞれにアニメーション一式があります。ゲームは胸の鎧でセットを選びます。合わせて255のアニメーションで、アヒルより170多い数です。シェアウェア版のデータには軽装しかないので、残りの二つには製品版のデータが必要です。そしてアヒルにもデザインが要ります。中装には小さなヘルメット、重装には胸当て、でしょうか。それはパート2で。
次の LLM へ:構造化した要約
プロジェクト:~/Projects/diablo-trainer(git)。ゲーム:DevilutionX 1.5.5、シェアウェア版 spawn.mpq。setup.sh がバージョン固定の依存関係を取得します。
| 領域 | ファイル | メモ |
|---|---|---|
| トレーナー | agent.py, web/, scan.py | 再署名したコピー(get-task-allow)への mach のメモリアクセス。プレイヤーのレコードは名前で検索。オフセットは実行中に検証済み。agent.py reload がスプライトのスロットを空にし、新しいファイルが読み込まれる。 |
| アヒルのモデル | duck_render.py | Blender スクリプト:メタボールの体、造形したくちばし、デカールの目、水かきの足、ピボットに付けた武器、武器ごとの構えのポーズ、アニメーションごとの pose()、エフェクトは別パス(DUCK_PASS=fx)。 |
| ビルド | build_fast.py, render_batch.py, duck3d_np.py | EEVEE、4サンプル、並列の Blender セッション、numpy でゲームのパレットに変換(プレイヤー色 128-255)、未変更スキップ用のスタンプ。 |
| 確認 | preview.sh, look.sh, fit_photo.sh, make_reel.py | プレビュー、ゲーム解像度での1フレーム、写真の輪郭の重ね合わせ、音つきの MP4 リール。 |
| ライブツール | web/app/preview, web/app/duck | Next.js:アニメーションプレビューア(mods/ を監視)、3D glTF ビューア(スクリプト編集で再読み込み)。 |
| ゲームパッチ | patches/devilutionx-1.5.5-trainer-menu.patch, build_game.sh | T でトレーナーメニュー(クエストログのパネル)、Y でアイテムサイクラー(インベントリのパネル)、無敵モードのフック。ビルドフラグはスクリプトに記載。 |
| ボイス | voice.sh | SoX で録音、合図音のトリミング、音量合わせ、MP3 を mods/sfx/ へ。 |
| ドキュメント | docs/animations.md, docs/pipeline.md, docs/todo.md | 作業リスト、パイプラインの決定事項、保留中のアイデア。 |
知っておくべき落とし穴:画像生成ツールはフレーム間でキャラクターを一貫させられない。パレットスワップ(TRN)は戦士のすべてのスプライトの色を変える。戦士の呪文エフェクトはスプライトに焼き込まれている。ゴールドはアイテムと、そこから計算される合計。メモリ書き換えは再起動で消えるが、ゲーム関数経由の変更は残る。キー入力を送る前に画面のロックが解除されているか確認する。「弓矢(bow and arrow)か、棒術の棒(bo staff)か?」と聞くこと。
Want the next one?
New posts by email, now and then. Nothing else.