1.9 KiB
Adding a talkable NPC
An NPC/sign is just an immovable Entity that mixes in Dialogable. Bumping it
(a rejected move) opens the dialogue box. Talking is the same everywhere — you
only supply art + a story.
1. Write the story
Create stories/<name>.ink — a line, a few choices, an ending:
yo wassup
* kick the sign
it doesnt budge.
* [say nothing] you have nothing to say to a sign.
- -> END
2. Compile it
The game can't parse .ink (LÖVE has no lpeg), so compile to a .lua book:
lua tools/compile_ink.lua <name>
Re-run this every time you edit the .ink — the game loads the .lua, not
the .ink. (Needs lua + lua-lpeg installed.)
3. Load the book
In main.lua, next to startSignBook:
<name>Book = require "stories.<name>"
4. Make the entity
In npc.lua, copy Sign — pick your art and name your book:
Oracle = class("Oracle", Entity)
Oracle:include(Dialogable)
function Oracle:initialize(x, y)
self.book = oracleBook -- from step 3
Entity.initialize(self, {
x = x, y = y, color = "red",
collision = "unmoveable",
sprites = {
red = loadSprite("art/npc/oracle_r.png"),
green = loadSprite("art/npc/oracle_g.png"),
blue = loadSprite("art/npc/oracle_b.png"),
},
})
end
Per-channel art lives in art/npc/ as <name>_r/_g/_b.png (16px cells).
5. Place it in a room
Map a save class to your entity in Room:createEntity (room.lua), alongside
the npc → Sign branch:
if class == "oracle" then
local entity = Oracle:new(x, y)
self:registerNpc(entity)
return entity
end
Then add it to a room's rooms/<room>.sav objects list:
{ class = "oracle", x = 4, y = 8 }
That's it — walk into it and it talks. NPCs are stamped into every colour's collision matrix, so they block movement and obey the world's colour rules (a red-only player reads them in red).