Final Fantasy Design Question

So i’m making a 2D final fantasy clone using paper2D and has some design questions. The game will be similar to Final Fantasy Mystic Quest (SNES). I’m trying to figure out the best way going about setting up the game. I need the ability to have 3 different control layouts (1 set for world map movement, 1 for level movement and 1 for combat). I also need different game states maybe? I need to process the combat and keep track of everything unlocked in the world, levels etc…

My thought is to have the world map be the main map with the towns and combat level be unreal sublevels. I found that i can change the player controller through the game mode but i don’t see a way to change the gamestate. Am i going down the right path with my though process?

So my issues are as following:

  1. Need to be able to move around the world map with logic to track which towns the player can move / enter
  2. Need to be able to move around the towns and interact with monsters / NPCs / Chests
  3. Need to be able to enter combat, keep track of all that and then return to where the player was before entering combat with all the player stats updated from the combat (XP, loot, gold)

I know i can use the game instance to store data across levels and have flags in the game state and player controller but that can get bloated real quick so ideally i want to have different player controllers, game state, game mode and maybe even player states for the different parts of the game. You can have a different game mode for each level the only issues is syncing data with the loading of the new level so my option is to use streaming levels which i don’t know if i can accomplish what i’m trying to do with the above.

Any help or suggestions would be great!!

I would use Finite State Machines and have both battle mode and map mode inside the same character controller =]
Also FMS in the Game State, so then I could easily switch from map mode to battle mode and back. without resorting to replacing the game instance class…

Keep as much of your logic separated to where it needs to be concerned.

For instance, world map, level map, and combat sounds like 2 - 3 different GameModes to me (level and world map may be the same, just different presentation). I would use seperate GameModes, PlayerControllers, etc. that are only for their relevant game state (Combat, World Map, Level Map). Throwing it all into one PlayerController, Game Mode will only leave an unnecessary mess later on. Using something like Game Instance or event Player state to pass data would not be as bad as having an overly-concerned PlayerController. You can pass the data back and forth all you want through various means. You don’t need to stream in the levels to carry over XP, loot, gold, inventory, etc. You could even save to a file on transition what you need and then load it when the new level opens up (such as save inventory to a file when going from Map -> Combat, and then loading that data when the Combat is ready).

Interesting; please explain how you’re going to change the game mode in runtime without loading another world map.
Because showing a loading screen to load another persistent map everytime a battle encounter happens in FF style, it’s a huge no-no for the players. If the battles happens in the same persistent level, he needs to address world controls and battle controls in the same controller to avoid a loading screen every minute in and out of the battle map, that would be unplayable otherwise.

But that is what this is doing… That smoke and mirrors sequence is a level load. If it is a 2D game it wouldn’t be a wait and if you are going for a classic feel, then this is definitely the way to do it. Look at Pokemon and a lot of other JRPG style games when you encounter with a monster fight.

And I didn’t say NOT to use level streaming. I said it could be done without it. That was in reply to a way to pass data back and forth.

Another way would be to use LoadStreamLevel to load in a game and manually set up the Game Mode and Player Controller.

Lets be honest though. Mixing all of that combat and world movement logic into one Player controller is going to lead to an unattainable, undebuggable, and untestable mess of code that will hurt in the long run. Don’t do what is easy at the beginning, do what is right. State management is always a nightmare and if you can write code that does less of it, then that is my professional advice, from years of professional experience.

If you really want to keep everything in the same persistent level and have no streaming or level loads, at least move the movement logic to one pawn, and then the combat to another pawn, then activate and possess based on the combat state of the game. Then the controller really just wraps the pawn actions. Of course, now you have a lot of type casts and have state based on type, which is a bad design choice as well.

Yeah, I’m talking 3D rpg using all UE4 rendering. What I mean is I’m pretty sure that streaming levels cannot change the persistent level’s game mode so streaming a level to change modes makes no sense to me; would have to save world map state, load battle as persistent level to change game mode, then load back world map after fight. Unreal would never do that without some black screens.

Loading a streamed battle level with its own skybox below the world map with extra pawns included to be possessed is a very viable option though. Different pawn controls in different blueprints without any loading screens.

You can use streaming, but you need to get creative in your code to be able to switch between different game “modes” without actually changing the Unreal GameMode. Here are some personal suggestions.

Create “sub-game modes” using Actor blueprints. It would work like this:

  • Create an Actor blueprint class called “SubGameModeBase”, flag it as “abstract” (so you don’t spawn it by accident). All your SubGameModes will be derived from this class.
  • Your actual gameMode class will act as a “game mode manager” or sorts (let’s call it GameModeManager). It will have a property called “ActiveSubMode”, of the type “SubGameModeBase”.
  • In the GameModeManager, you’ll have a “setActiveSubGameMode” function/event which takes as parameter the SubGameModeBase class it will use. It will then SpawnActorFromClass the SubGameModeBase and call some initialization function in it.
  • In the GameModeManager, you’ll forward the events/functions you wish to use in your game to use to the SubGameMode (creating the functions/events in the base class as you need them).

This way the UE game mode will act as a “router” for a different object that you can change whenever you want. You could also do things like using a SubGameMode stack so you can push/pop game modes and even have custom events from when you switch from a game mode to another (so you can perform some custom processing during transitions, for example.)

For control, the PlayerController has an internal stack of objects that receive and process inputs. By default it only has the possessed pawn on it’s stack. Any input events not handled by the pawn are passed to the PlayerController itself. You can add any other Actor-derived object into the stack by calling EnableInput() on that Actor and passing the PlayerController that will “control it”. That actor is added at the top of the stack, so it will have a chance to process input before the possessed Pawn. So you can override control completely without having to possess another pawn.

You’re right, it can’t. The game mode is what manages the seamless travel.

That said, you could just segment off your game mode with a state enum, although that would make a very messy, albeit single game mode.

This is why I said I would use a Finite State Machine.
I’ve made for my projects a State Machine component plugin exactly for situations like this…
So I would just make a FSM for World Map movement and another FSM for Battle mode then add them both to my Controller and keep programming both systems separately, no mess like that mess I used to have when using enums on the same Blueprint.
From the Player Controller then I would just use GoToFSM(Component Name) and quickly switch controller mode without loading another game mode and more important, without investing extra memory resources to keep those extra pawns loaded in memory to be possessed.

I save my State Machines as separate Blueprint assets, each FSM as a separate Graph which I save and organize in my content browser.
If/when there’s a programming mistake Unreal tells me exactly where the problem is and what must be fixed:

Oh yeah… that would be an utter mess in blueprints lol.