本文へ移動
cccskills
無料GitHub で公開日本語紹介

defold-core

Defoldのゲームで、Luaの処理や入力、オブジェクト生成、ステージ読み込みを実装・修正するスキル。ファイル参照の点検からビルドと動作確認まで扱います。

原文原文の説明を見る

Build and debug the core of a Defold game in Lua: game.project settings, collections, game objects and components, script lifecycle and self state, go.property, input focus and bindings, URLs and message passing, factories, collection factories and collection proxies, plus building and smoke-running with Bob. Use when a project has game.project or .collection, .go, .script, .gui_script or .input_binding files, or the request mentions Defold, msg.post, on_message, on_input, acquire_input_focus, factory.create, collection proxy, bob.jar, or a Defold build error.

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • プレイヤー操作とLua処理の実装
  • オブジェクト生成とステージ読み込み
  • 参照切れやメッセージエラーの調査
  • Bobでのビルドと実行ログ確認

日本語での紹介

できること

Defoldのゲームを構成するファイルとLuaの処理を実装・修正します。ゲームオブジェクトの配置、入力の受け取り、オブジェクト間のメッセージ送受信、実行中の生成、別ステージの読み込みを扱います。付属のチェッカーでファイル参照を点検し、Bobでのビルドと、画面を表示しない実行による基本的な動作確認まで進めます。

こんなときに便利

操作に反応しない、生成先のファイルが見つからない、ステージ切り替え後に入力が届かないといった問題の調査に向いています。既存プロジェクトの構成や命名、Defoldのバージョンを保ちながら修正する方針です。

使い方の例

  • 「プレイヤーの左右移動と弾の生成を実装して」
  • 「Bobの参照エラーを調べて、原因のファイルを修正して」
  • 「collection proxyで次のステージを読み込んで」

注意点

例はDefold 1.14.0向けです。参照チェッカーにはPython 3.10以上、記載のビルド手順にはJDK 25とプロジェクトに合うbob.jarが必要です。画面なしの実行ではキーボードやマウスを確認できないため、入力はエディターかデスクトップ版で検証します。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

含まれるファイル(5)

  • SKILL.md12.6 KB
  • agents/openai.yaml229 B
  • references/build-and-run.md6.7 KB
  • references/file-formats.md7.2 KB
  • scripts/check_defold_project.py29.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Defold Core

Structure, wire and verify a Defold game: editor resource files, the Lua script lifecycle, addressing and messages, runtime spawning and world loading, and a Bob build-and-run check. Examples target Defold 1.14.0; they were built with Bob 1.14.0 and run on the 1.14.0 headless engine. An existing project keeps its Defold version (see Version).

When to use

  • Use when adding or fixing game objects, collections, scripts, input, messages, spawning or level loading in a Defold project (game.project in the root, .collection, .go, .script, .gui_script files), or when Bob reports a missing resource.

When not to use: plain Lua or LÖVE projects (love2d-core); GUI layout, sprites, tilemaps and physics depth beyond the pointers in the references; engine-agnostic design handled by the related skills below.

Workflow

  1. Inspect first. Read game.project ([bootstrap] main_collection, [input] game_binding, [project] dependencies), the main collection, and the scripts near the request. Follow the project's folder layout, id naming and message names; do not reorganize. Note which Defold/Bob version CI or the team uses.
  2. Edit the right file type. Game objects (.go) hold components; collections (.collection) place game objects and other collections; logic goes in .script (game objects), .gui_script (GUI) or shared .lua modules. Editor files are protobuf text: keep their structure, and copy shapes from references/file-formats.md instead of guessing fields.
  3. Check references. Run python scripts/check_defold_project.py <project-dir> (path relative to this skill folder; Python 3.10+, no Defold install needed). Fix every ERROR (missing or wrong-case /paths, a game.project path without the compiled c suffix, a require whose file does not exist). Warnings cover files nothing uses yet, unfetched library dependencies and runtime-loaded files. Re-run until it exits 0.
  4. Build with Bob. java -jar bob.jar --root . --variant headless --archive resolve build needs JDK 25 and a bob.jar matching the project's Defold version. Exit 1 plus an ERROR: line means a broken reference or a Lua syntax error (with file and line); references/file-formats.md shows how to trace an error that names a generated file.
  5. Run it. A build does not prove the game works. Run a headless bundle under a timeout (references/build-and-run.md) and read the log: ERROR:SCRIPT: lines are Lua runtime errors, ERROR:GAMEOBJECT: lines bad addresses or socket clashes. Require a line your test prints when it finishes; the exit code alone proves nothing. The headless engine has no keyboard or mouse, so check input changes in the editor or a desktop build, and say what you could not verify.

Patterns

Project and resource references

game.project is an INI file in the project root. Resource paths everywhere are root-absolute (/main/player.go). In game.project they name the compiled file, so the source path gets a trailing c:

[bootstrap]
main_collection = /main/main.collectionc

[input]
game_binding = /input/game.input_bindingc

Bob builds only what is reachable from game.project; /builtins/... ships with the engine.

Collections, game objects, components

A collection places instances and can override script properties per instance; a game object lists file components and embedded components (escaped data: strings). Full verified files are in references/file-formats.md.

# main.collection (excerpt): place player.go and override its script's speed
instances {
  id: "player"
  prototype: "/main/player.go"
  component_properties {
    id: "player"
    properties { id: "speed" value: "250.0" type: PROPERTY_TYPE_NUMBER }
  }
}

Script lifecycle, self and properties

go.property("speed", 200)                   -- top level only, literal default; editable per instance

local LEFT = hash("left")                   -- hash ids once, not every frame
local RIGHT = hash("right")
local FIRE = hash("fire")

function init(self)
	msg.post(".", "acquire_input_focus")    -- no focus, no on_input calls
	self.held = {}                          -- per-instance state lives on self
end

function update(self, dt)
	local dir = (self.held[RIGHT] and 1 or 0) - (self.held[LEFT] and 1 or 0)
	if dir ~= 0 then
		local pos = go.get_position()
		pos.x = pos.x + dir * self.speed * dt    -- dt-scaled: same speed at any frame rate
		go.set_position(pos)
	end
end

function on_input(self, action_id, action)
	if action_id == LEFT or action_id == RIGHT then
		if action.pressed then self.held[action_id] = true
		elseif action.released then self.held[action_id] = nil end
		return true                         -- consumed: listeners lower on the stack skip it
	elseif action_id == FIRE and action.pressed then
		factory.create("#bulletfactory", go.get_position(), nil,
			{ velocity = vmath.vector3(0, 600, 0) })
		return true
	end
end

function final(self)
	msg.post(".", "release_input_focus")
end

Callbacks: init, final, fixed_update, update, late_update (after every update, before render), on_message, on_input, on_reload. Update order between game objects is unspecified. fixed_update runs 0..N times per frame at [engine] fixed_update_frequency; set [physics] use_fixed_timestep = 1 too so physics steps at the same rate, and put physics-driven code there. self is userdata: store fields on it, but pairs(self) and pprint(self) do not work. Property types: number, boolean, hash, msg.url, vmath.vector3/vector4, vmath.quat, resources such as resource.atlas("/main/main.atlas"), and (since 1.13.2) strings.

Input bindings and the input stack

.input_binding maps devices to action names (key_trigger, mouse_trigger, plus gamepad, touch and text triggers). Every component that acquired focus sits on an input stack; the last to acquire is on top and gets input first, and returning true from on_input stops it there, which is how pause menus block gameplay input. Key actions report pressed and released; track held keys yourself as above.

Addressing and messages

A URL is [socket:][path][#fragment]: "." is this game object, "#" this component, "#sprite" a sibling component, "enemy#ai" a relative object, "/manager#controller" an absolute one, "main:/loader#loader" an object in another world. Collections create naming scopes, so a string id is resolved relative to the sender's collection; a pre-hashed id is always absolute.

msg.post("/manager#controller", "enemy_spotted", { id = go.get_id() })

function on_message(self, message_id, message, sender)
	if message_id == hash("enemy_spotted") then
		print("from", sender, "id", message.id)
	end
end

Messages are queued and dispatched later in the frame; the table is capped at 2 KB. A bad address logs ERROR:GAMEOBJECT: Instance '/x' could not be found when dispatching message.

Factories and collection factories

-- factory component "#bulletfactory" -> one game object; properties override go.property values
local id = factory.create("#bulletfactory", pos, nil, { velocity = vmath.vector3(0, 600, 0) })

-- collectionfactory component "#wavefactory" -> table of collection ids -> new instance ids
local ids = collectionfactory.create("#wavefactory", vmath.vector3(480, 500, 0))
local leader = ids[hash("/leader")]         -- e.g. hash: [/collection0/leader]
go.delete(ids, true)                        -- later: delete them and their children

Position and rotation default to the spawning object's. go.delete() takes effect at the end of the frame. Per-instance properties for a collection factory are keyed by id: { [hash("/leader")] = { hp = 5 } }.

Collection proxies (load another world)

-- excerpt from the loader script; the collection's "#levelproxy" component is a collectionproxy
function init(self)
	msg.post(".", "acquire_input_focus")        -- else the loaded world gets no input
	msg.post("#levelproxy", "async_load")       -- or "load"
end

function on_message(self, message_id, message, sender)
	if message_id == hash("proxy_loaded") then
		msg.post(sender, "init")
		msg.post(sender, "enable")
	elseif message_id == hash("level_done") then
		msg.post("#levelproxy", "unload")       -- disables and finalizes first
	elseif message_id == hash("proxy_unloaded") then
		-- safe to load the next level here
	end
end

The loaded world's socket is the name: of the loaded collection file, so scripts in it reply with msg.post("main:/loader#loader", ...) and its own URLs read level1:/level#level. set_time_step { factor = 0, mode = 0 } pauses a proxy world.

Version

game.project has no engine version key. Use the Defold editor or bob.jar version the project is built with (CI often pins a release sha1), and library.defold_min_version when the project is a library. java -jar bob.jar --version prints the version and sha1. Keep that version; do not migrate unless asked.

Pitfalls

  • Bob: the bootstrap.main_collection '/main/main.collectio' can't be found → the setting lacks the compiled suffix and Bob stripped the last letter. Write /main/main.collectionc (same for input.game_binding → .input_bindingc).
  • Bob: ERROR: build/default/_generated_….factory:0: the prototype '/main/x.go' can't be found → an embedded component in some .go points at a missing file. Search the sources for the quoted path (/main/x.go), not the generated name, or run the checker.
  • on_input never fires → the object never sent acquire_input_focus, the action name differs from the binding, input.game_binding points elsewhere, or a listener higher on the stack returns true.
  • Input dead inside a proxy-loaded level → the game object holding the collection proxy did not acquire input focus.
  • already a socket with the same name and the proxy never sends proxy_loaded → the loaded collection's name: equals an already loaded world (often both are "main" or "default"). Give every proxied collection a unique name.
  • fixed_update never runs → [engine] fixed_update_frequency is 0 (default 60). For physics also set [physics] use_fixed_timestep = 1, as the manual requires both.
  • module 'modules.util' not found at run time although Bob succeeded → a require used slashes (require "modules/util"). Use the dotted path from the project root, require "modules.util" for /modules/util.lua.
  • tostring(id) prints hash: [<unknown:…>] → hashes keep their source text only in debug builds. Compare hashes, never their strings.
  • A second engine logs Failed to initialize Remotery, or a test run never ends → the debug engine opens an engine service (port 8001), a log server and a profiler port, and waits forever without sys.exit. Run one engine at a time and always use a timeout.

References

  • references/file-formats.md — verified minimal game.project, .collection, .go, .atlas, .input_binding and script files, and how to trace build errors back to a source file; read before writing editor files by hand.
  • references/build-and-run.md — JDK 25 and bob.jar, Bob commands, platforms and variants, a headless smoke test with timeout and log checks, and pointers for GUI, sprites, tilemaps and collision objects.
  • scripts/check_defold_project.py — read-only reference checker; --help lists every check.

Related skills

  • input-systems — rebinding, gamepad support and buffering on top of Defold bindings.
  • game-ui-ux — HUD and menu design to build with GUI scenes and .gui_script.
  • physics-tuning — fixed-timestep and collision tuning for collision objects.
  • camera-systems — follow/deadzone logic, typically applied in late_update.
  • save-systems — save formats and slots; pair with Defold's sys.save/sys.load.
  • game-feel — juice built from go.animate and timers.
  • platformer, level-design — genre and layout guidance that binds to this skill.
  • love2d-core — the other Lua engine in this catalog, for LÖVE projects.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

敵やNPCの行動判断を、条件を順にたどる行動ツリーと選択肢を点数で比べるUtility AIで実装し、両者の組み合わせや判断の揺れの調整まで扱うスキル。

  • 再利用できる行動ツリーを作りたいとき
  • 点数で攻撃や標的を選びたいとき
  • 巡回・戦闘のツリーとUtility AIの併用
gamedev-skills/awesome-gamedev-agent-skills3,5452026年10月23日 更新

audio-design

無料概要あり

ゲームの音量バランスと状況に応じた音楽の変化を設計するスキル。音の種類ごとの一括調整、会話中のBGM抑制、効果音の変化、拍に合わせた演出を扱います。

  • BGM・効果音・音声の音量設計
  • 会話中だけBGMを下げたいとき
  • 状況に応じて音楽を変えたいとき
gamedev-skills/awesome-gamedev-agent-skills3,5452026年10月23日 更新

bevy-ecs

無料概要あり

RustのBevyゲームで、部品データと処理を分けるECS設計を支援。アプリ構成、データ検索、処理順序、移動速度やデータアクセス競合の修正を扱います。

  • Bevyアプリをプラグインで整理したいとき
  • 部品データと共通データを定義したいとき
  • 検索の競合や処理順序を直したいとき
gamedev-skills/awesome-gamedev-agent-skills3,5452026年10月23日 更新

camera-systems

無料概要あり

ゲームの2D追従カメラや3D視点操作を実装・調整するスキル。滑らかな追従、進行方向の先読み、表示範囲の制限、壁へのめり込み対策を扱います。

  • 2Dの追従カメラを滑らかにしたいとき
  • ステージ外が映るのを防ぎたいとき
  • 三人称カメラの壁抜けを直したいとき
gamedev-skills/awesome-gamedev-agent-skills3,5452026年10月23日 更新

card-game

無料概要あり

カードゲームの山札・手札・捨て札の管理から、ドロー、シャッフル、ターン進行、コストと効果の処理順まで、基本ルールを整理して実装につなげるスキル。

  • デッキ構築型ゲームやTCGを作りたいとき
  • ドローと捨て札の混ぜ直しを実装したいとき
  • ターン進行とカードのコスト設計
gamedev-skills/awesome-gamedev-agent-skills3,5452026年10月23日 更新

create-game-assets

無料概要あり

ゲームの見た目に統一感を持たせ、スプライトや背景、UI素材の制作・調達からサイズ調整、実機での見え方の確認、出典・ライセンス管理まで進めるスキル。

  • 絵柄のそろったスプライトや背景を作りたいとき
  • 素材の寸法・透過・タイルの継ぎ目の確認
  • 公開前の素材の出典・ライセンス整理
gamedev-skills/awesome-gamedev-agent-skills3,5452026年10月23日 更新

gamedev-skills のスキルをすべて見る

このスキルの問題を報告する