Skip to content

Advanced conversations, NPC mobs, followers - #10

Merged
LoneWolfHT merged 5 commits into
LoneWolfHT:masterfrom
cosmic-vole:ForUpstreamAdvancedConversationsFollowers
Apr 5, 2026
Merged

LoneWolfHT merged 5 commits into
LoneWolfHT:masterfrom
cosmic-vole:ForUpstreamAdvancedConversationsFollowers

Conversation

@cosmic-vole

Copy link
Copy Markdown
Contributor

Hi @LoneWolfHT , me again ☺

As discussed, here are the features I have coded so far for Voxel Knights.

  1. Conversations can now be nested and replies can have basic conditions and actions attached.
  2. The tavern keeper is now an NPC mob, combining features and animations of mobkit with your NPC features.
  3. A follower spawns in the tavern, another NPC mob who you can hire as a mercenary to fight for you.

I have spent a lot of time testing all this new code and cleaning it up as best I can but I am sure you won't be surprised to hear even these features are very much still WIP.

Known Issues:

  • There is a strange bug where conversation lines starting with "I" sometimes have a space stripped out when displayed. Any ideas about this? It may be a bug in Luanti.
  • The follower doesn't seem to use proper path finding yet and will often get stuck in the tavern. I have not had time to look into this yet.
  • When defining nested conversations, you may see an extra pair of curly brackets around some nested responses. I had a little trouble when there was originally more than one way of defining a conversation (and only just got my head around Lua tables versus other types honestly) so I did what I could to make it run reliably but it could do with looking into when there is more time.

cosmicvole added 2 commits March 29, 2026 18:39
Nested conversations now possible with conditions and actions attached.
NPCMobs combine the features of NPCs with mobkit movement, combat etc.
Code for followers added with a follower automatically spawning in every
tavern.
The tavern keeper will now take money for a drink.
Signed-off-by: cosmicvole <notyourbusiness@example.com>

@LoneWolfHT LoneWolfHT left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks!

I'm fine with merging this now, although the NPC condition feature should be fixed before I add a new ContentDB release (ContentDB only gets updated when I create a new Github tag/release).
For whatever you don't want to address before merging this PR you could probably just copy my review text into a multiline TODO: comment in the relevant section of code so that we don't forget. Or maybe I make an issue and link all my reviews there

Comment thread mods/vk_enemies/mobkit_custom/init.lua Resolved
Comment thread mods/vk_enemies/spawners/init.lua Resolved
Comment on lines +132 to +141
if (node.name == "vk_npcs:tavern_keeper") then
minetest.log("info", "Found a tavern keeper at: "..dump(pos))
-- Need to remove her and add a marker
minetest.remove_node(pos)
minetest.remove_node( {x = pos.x, y = (pos.y + 1), z = pos.z} )
minetest.set_node( {x = pos.x, y = pos.y + 4, z = pos.z}, { name = "vk_npcs:tavern_marker" })
-- Add her back as an npcmob that can walk around
minetest.add_entity({x = pos.x, y = (pos.y + 1), z = pos.z}, "vk_npcs:tavern_keeper")
return 1
end

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to use the original node as a marker, we may need to respawn the tavern keeper sometimes too, entities can randomly or accidentally (/clearobjects, etc) get deleted.

It was one of the reasons I went with nodes for NPCs, I figured if they needed to move for anything I could temporarily convert them into a temp entity and walk them around. Random wandering does make the place feel less lonely, but when you realize they are walking around without any purpose it kind of ruins the effect. And there are probably a decent amount of walking tasks you could give an NPC that would work with a node->entity->node method

@cosmic-vole cosmic-vole Mar 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entities can randomly or accidentally (/clearobjects, etc) get deleted.

This has been one of my biggest worries with coding for Luanti (Well that and the risk of structures and/or entities failing to properly spawn).

I think it would be better to use the original node as a marker, we may need to respawn the tavern keeper sometimes too

In this particular case, I do have another lbm in vk_npcs/init.lua, line 935. The lbm runs on every load, attached to the airlike tavern_marker node, and it searches the local area for tavern keeper entities and does respawn her then if she cannot be found (i.e. failed to spawn or wandered off too far). In future this sort of code may need to teleport an entity or quest character back into the correct location as well.

I do not really mind if the original tavern keeper node inside your town structure becomes the tavern marker, but however we do it, I still need it to be a node that always stays fixed inside the tavern in order to identify the tavern (Currently used to spawn a follower there for example). The problem comes if we do want the tavern keeper to turn into a mobile mob, because in that case the original tavern keeper node needs to become invisible (and it cannot just be deleted because the code would have no way to find the tavern). Rather than editing your town.mts file, I went for the option of making a new, airlike, unbreakable tavern_marker node in the code.

It was one of the reasons I went with nodes for NPCs, I figured if they needed to move for anything I could
temporarily convert them into a temp entity and walk them around.

Yeah I get the logic but in that case I feel like there are other things the mobkit provides support for than just animation and I wouldn't want to end up in a situation where a load of state has to be copied over and converted to switch between the two.

Random wandering does make the place feel less lonely, but when you realize they are walking around without any purpose it kind of ruins the effect.

Yes I know what you mean. Characters standing guard should stay mostly still. The tavern keeper should spend a lot of her time standing at the bar. There are probably more extreme cases too where something may need features of an NPC but never any wandering around (An enchanted statue, a crystal ball, maybe even a book you could look things up in).

If it was my game, I would ideally still want a little bit of animation added to the human characters that stand still, say moving arms and legs a little occasionally or turning their head just to bring them to life a little more although this is not too much of a major concern for me.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points, go with whatever gets the job done fastest I guess, with room to add that polish later

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, for now I have kept the tavern keeper as an npc mob but now she stands still at the bar, and she and the barbarian always face the same way relative to the bar when they spawn.

Comment thread mods/vk_npcs/init.lua Resolved
Comment thread mods/vk_npcs/init.lua Resolved
Comment thread mods/vk_npcs/init.lua Resolved
@LoneWolfHT

Copy link
Copy Markdown
Owner

If you use VSCode I highly recommend these extensions: https://marketplace.visualstudio.com/items?itemName=sumneko.lua
https://marketplace.visualstudio.com/items?itemName=dwenegar.vscode-luacheck
https://marketplace.visualstudio.com/items?itemName=GreenXenith.minetest-tools
The luacheck one requires luacheck to be installed I think, which might be a bit of a hassle if you're on Windows. Although I managed to install it somehow, so I could help you with that

@LoneWolfHT

Copy link
Copy Markdown
Owner
  • There is a strange bug where conversation lines starting with "I" sometimes have a space stripped out when displayed. Any ideas about this? It may be a bug in Luanti.

  • The follower doesn't seem to use proper path finding yet and will often get stuck in the tavern. I have not had time to look into this yet.

  • When defining nested conversations, you may see an extra pair of curly brackets around some nested responses. I had a little trouble when there was originally more than one way of defining a conversation (and only just got my head around Lua tables versus other types honestly) so I did what I could to make it run reliably but it could do with looking into when there is more time.

1: sounds potentially like a formspec leakage. You could check that you're using core.formspec_escape() on all text that isn't supposed to contain formspec stuff

2: Pathfinding is always hard. Might be worth looking at how https://content.luanti.org/packages/ElCeejo/animalia/ solves it

3: As long as your code is easy to change later it should be fine, it's almost impossible to nail a dialogue system first try as far as I know

@cosmic-vole

cosmic-vole commented Apr 2, 2026 •

Copy link
Copy Markdown
Contributor Author

2: Pathfinding is always hard. Might be worth looking at how https://content.luanti.org/packages/ElCeejo/animalia/ solves it

I am fairly sure I have a fix for that now using the astar algorithm you used for the spider. The issue was the collisonbox was slightly too tall for the follower to get through the doorways!

Edit: I actually changed it back to the mobkit follow function as the diagonal movement worked better for that character and it was just easier to use.

* Npc mob registration moved into npcs.lua as init.lua was getting too
big.
* Conversation conditions are now specified as functions inline instead
of text that has to be parsed.
* Fixed follower bugs: Collision box height reduced so they fit through
the door. Unfollow and stand down should now work.
* The tavern keeper now stays still again and she and the follower are
rotated to consistent initial orientations when spawned.
@cosmic-vole

cosmic-vole commented Apr 2, 2026 •

Copy link
Copy Markdown
Contributor Author
  • There is a strange bug where conversation lines starting with "I" sometimes have a space stripped out when displayed. Any ideas about this? It may be a bug in Luanti.

1: sounds potentially like a formspec leakage. You could check that you're using core.formspec_escape() on all text that isn't supposed to contain formspec stuff

On a quick look, I believe formspec_escape() is being used. I will have to dig a lot deeper into this bug another day. I think it is intermittent as well. It is when the line starts with "I ", the space after the "I" is intermittently deleted.

@cosmic-vole
cosmic-vole requested a review from LoneWolfHT April 2, 2026 17:22
Comment from review added to code:
"
This feels like a slightly dangerous habit to start (Using
playerrefs/luaents interchangeably), eventually this should probably get
swapped out for a core.is_player() check, and an is_npc check or
something depending on if we'd want all mobs to have a strength stat, or
just npcs
"
@LoneWolfHT

Copy link
Copy Markdown
Owner

Looking at https://github.com/LoneWolfHT/voxel_knights/actions/runs/23926488718/job/69910372398?pr=10
there are some errors that might indicate an actual problem, e.g:

mods/vk_npcs/init.lua:277:11: shadowing definition of variable npcself on line 141

I'm down to merge this whenever you want though, I can go through and make luacheck happy whenever I feel like making a change

@cosmic-vole

cosmic-vole commented Apr 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Looking at https://github.com/LoneWolfHT/voxel_knights/actions/runs/23926488718/job/69910372398?pr=10 there are some errors that might indicate an actual problem, e.g:

mods/vk_npcs/init.lua:277:11: shadowing definition of variable npcself on line 141

Ah, yeah, we can just delete the first declaration of npcself on line 141 as it isn't needed until after line 277 anyway.

I'm down to merge this whenever you want though, I can go through and make luacheck happy whenever I feel like making a change

That's kind of you, thanks. At this point I must admit I am feeling pretty lost regarding the proper way to share variables between init.lua and npcs.lua, given all the warnings from Luacheck about:

vk_npcs = {}

@LoneWolfHT

Copy link
Copy Markdown
Owner

At this point I must admit I am feeling pretty lost regarding the proper way to share variables between init.lua and npcs.lua, given all the warnings from Luacheck about:

vk_npcs = {}

For global variables you've made intentionally you have to add it to the .luacheckrc file

@cosmic-vole

Copy link
Copy Markdown
Contributor Author

Hopefully this 8b2f0f5 should resolve the vast majority of those Luacheck warnings.

I am happy for you to merge this now provided that last commit didn't horribly break it (It still seems to run fine on my system).

@LoneWolfHT
LoneWolfHT merged commit 39a02cf into LoneWolfHT:master Apr 5, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants