hello!
i am attempting to make an rpg style game with an element of turn based combat similar to pokémon! however, im a bit stumped on how exactly to implement this into the game. (both visual and logic)
any help would be greatly appreciated! (any examples of code or tutorials would also be helpful)
hi I am only a beginner with the engine but I was coming here to ask for feedback on my own setup of this so I can post it as a response and others can tell us both if it’s a good idea or not.
Before I do some long description of my approach as an example the basic idea is:
- I send a message to a game_gui collection when it is the player’s turn
- The game_gui collection pauses my game collection until it gets player move related input, then it sends that input to the player game object and unpauses
In my case pausing/unpausing is driven by a system where units gain energy every tick, but that’s because I am making a roguelike and plan to have a speed/agi sort of stat that affects turn frequency. If you’re doing pokemon/final fantasy style battles you could probably do something simpler like a state machine that swaps between enemy turn and player turn.
I have not added things like animations or complicated player/enemy actions so I’m not sure if the approach I have may fall apart, but I can post some code snippits to show how it is put together so you can try for your battle turns. If people who know more about how things work than me say that doing this via collection pauses is stupid then you can likely do the same thing by just having some shared lua module that stores your turn state and turn on/off updates and accepting input for the player and enemies according to that by just checking it everywhere.
Starting a game from my main menu loads a game_gui.collection
that has a proxy to my game.collection
where all the gameplay logic is
My game gui script immediately loads the game on init so that the energy loop and other game logic starts running and characters draw etc
function init(self)
msg.post(".", "acquire_input_focus")
msg.post("#gameproxy", "load")
self.accepting_input = false
end
function on_message(self, message_id, message, sender)
-- this message is sent from the player gobj when it has energy to move
if message_id == hash("player_move") then
msg.post("#gameproxy", "set_time_step", {factor = 0, mode = 0})
self.accepting_input = true
print("awaiting input")
elseif message_id == hash("proxy_loaded") then
msg.post(sender, "enable")
end
end
function on_input(self, action_id, action)
-- eventually I will have buttons on the ui, but for now I only care about gameplay input so I just abandon if this isn't set
if not self.accepting_input then
return
end
local move_vec = vmath.vector3()
-- omitting a code block setting up the vector based on input keys
if vmath.length(move_vec) > 0 then
msg.post("game:/player", "move", {position = move_vec})
self.accepting_input = false
msg.post("#gameproxy", "set_time_step", {factor = 1, mode = 0})
end
my player script has this in its update
to trigger the above actions in the game ui, but I think I may need to move it to the on_message handler so it can be sent right after the player is granted the energy tick to trigger a move. I also have some code in its on_message
to listen for the input from the game gui that sets the position based on the passed in vector.
function update(self, dt)
[[-- the set_time_step with factor 0 call above results in dt being 0,
so it's important that all of your updates/moves either at least check if dt is
0 or use it in calculations so things get zeroed out when it's "paused" --]]
if dt == 0 then
return
end
-- this threshold could be based on some speed related stats instead
if self.energy >= 5 then
print("signaling ui to take a move")
msg.post("game_gui:/game_gui#game_gui", "player_move")
end
end
Heyo! Some details about what you have so far for the game might be helpful for suggestion.
For example, do you walk around in the game, interact with objects etc, and then are looking to get into battles and “pause” for turn based combat? Or is everything turn based even when not in combat, eg on your turn you may move, interact with an object, then the enemies get their turn (or other things happen in the background) regardless of if you are fighting or not.
–
Suggestions
Design:
If it is similar to pokemon, sounds like you are entering battles separate from the rest of the exploration. Many RPGs have a separate scene appear with the characters. Characters could face each other (like pokemon) or be on a limited size battlefield, like FireEmblem, where the rules are different from normal exploration.
You can have some clickable buttons to take a specific action, and a grid on the ground for movement if that is part of your game.
Implementation:
First you may want a scene transition, either by using a plug-in manager like Monarch or by setting up your own system of collections and loading (see the Colorslide tutorial linked below)
Then @dodze suggestion of a machine that swaps between player and enemy turns makes sense. At the start of the battle, if its the players turn, nothing happens until the player clicks a button to take an action. Then you receive the action (usually in a GUI script or the game script), facilitate the selected option by sending messages from the script to the relevant game objects you want to affect, then take the enemy turn, and then return to the start of the loop.
This can often be accomplished with a LUA module which can help run the games logic internally and coordinate between different game object, although it can be a lot of frontloaded work to research and design using modules to run your game, it can save complexity in the long run.
Resources
If you haven’t done the first five tutorials on this page, definitely walk through them (maybe not movement for your RPG) Defold tutorials
Looking through the questions on this forum is a great resource as many people might have similar questions. Researching each part that you are trying to create on this forum could give you several different code examples that you can string together to accomplish what you are looking for.
If you are interested in using modules, here are the best resources I have found to help determine how you want to use modules to run your game: