Skip to content

Zaltu/personax-godot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Overview

This is the (slowly being documented) Godot implementation of PersonaX.

Seems much better than Unreal at this point tbqhwys. We'll see how things go and if it can be done.

Filesystem Organization

For an understandable, simple and representative way or organizing the game resources, I follow this particular structure:

res://
    | project.godot
    |---> envs/
        |
        |---> <envname>/
            |
            | <envname>.tscn
            |---> scripts/
            |   | *.gd
            |
            |---> assets/
                |
                |---> 2d/
                |   | <2dresource>
                |---> 3d/
                    | <3dresource>
    |---> assets/
        |
        |---> 2d/
            | <2dresources>
        |---> 3d/
            | <3dresources>
    |---> ui/
        |
        |---> <uiscenes>

This is to separate envs as per the logical separation made by the model and the assets as those exclusive the the envs (and thus not configurable by the model) and generic assets to be loaded into any scene.

UI scenes are meant to be overlayable onto any active spatial scene. The exception in logical terms is ui/mainmenu, which doesn't have a better home.

Singleton scripts

There are a handful of singletons scripts used to ensure the consistency of various behaviors across the game. These scripts are loaded by Godot when the engine loads and, as a general rule, remain active throughout the entire runtime of the program. Obviously we don't want that in most cases, but our overall GSV functions in this way as well. Resulting, the full list of singletons is:

  • PersonaX/scripts/state.gd
  • PersonaX/scripts/inputhandler.gd

state.gd

This is the big one. This script holds and maintains the connection between Godot and the GSV. While I wouldn't bother documenting code in a ReadMe, this gets special treatment considering it's importance.

The state singleton can be accessed from anywhere by simply referencing state anywhere, once the engine has been initialized. It exposes a number of highly used functions to interface with the GSV.

  • init: Instatiate the PXLua object (full documentation found in the godot-luajit-module repo). THIS SHOULD ONLY BE CALLED ONCE! Calling it more than once will do nothing, as we do not want the state to get instantiated twice.
  • sendStateEvent: This is a wrapper around the same function defined by the PXLua object that is used to send events generated by user input from Godot to the GSV. Carefully read the GSV documentation for the appropriate context before firing events in this manner. As a reminder, sendStateEvent returns the same value as getUpdate will until sendStateEvent is called again.
  • getUpdate: This is a wrapper around the same function defined by the PXLua object which is used to fetch the latest update provided by the GSV (keep in mind, the PXLua object does not manage whether the latest update has already been fetched or not). The form the updates will take depends on the context, documentation for which can be found in the personax-lua-src repo.
  • start: This is a wrapper around the startGame function defined by the PXLua object. READ ITS DOC CAREFULLY, this will start the game.
  • set_context: The model's documentation makes it clear that the GSV is solely responsible for changing the state's context. Be that as it may, the engine must also adjust certain properties based on which context is currently in use. Primarily, inputs to be handled are defined by which context the state is in. Call this with the value received from a getUpdate call to change the inputhandler (documented below) to process the possible inputs for whichever context the update is valid for. This function is automatically called when getUpdate is called, as well as sendStateEvent.
  • save_state: TODO.
  • load_state: TODO.
  • exit: TODO.

inputhandler.gd

The input handler is responsible for responding to the correct type of inputs made by the player, depending on the context in which the game is currently running. This means that there are, in fact, about a dozen input handlers which are all loaded when the engine is initialized. The primary inputhandler singleton is responsible for knowing the active context in which to process the player's inputs, while the input contexts themselves are meant to be the ones directly affecting what is shown on-screen as a result of the player's inputs. When something (most likely the state.set_context above) calls the inputhandler's set_active function, the inputhandler updates it's active context.

The active contexts are the ones responsible for actually responding to the individual monitored button presses. When a key is pressed, inputhandler._input is called, which does nothing but forward the event to the currently active context's processInput function. The active context, whatever it may be, is responsible for finding anything in the current ENV which should be affected by the input.

An important thing to keep in mind is that a single ENV can have (and most will have) multiple valid contexts. A change in context can result in the engine needing to load more resources into the viewport, for example popping open an inline dialog box. It is up to the active context to request that the engine load these new resources. For example, since the battle context and the dungeon context take place in the same Godot scene (ENV), it is the dungeon context's responsibility to request that the engine load up the battle context within that scene, and the battle context's responsibility to request that the engine return the player character to the dungeon context of the scene once the battle is complete. When a cutscene starts, it is the freeroam context's responsibility to request that the engine load in the cutscene context, which will load in a textbox capable of displaying the contents of the cutscene, and the cutscene context's responsibility to close it when it is done. There are many other possible examples of this. As mentioned before, most environments have multiple valid contexts.

As an extension or clarification of the very important role of the active context, it is to be the liason between the engine and the GSV. In general, sendStateEvent calls should only be made as the result of an action taken by the player (unless there are some kind of timed events, which I have no plans for). This means that when the active context's processInput function is called, there is a chance that an event will be fired to the GSV. As the active context is acting as our liason, it is the active context's responsibility to read the result of the event (getUpdate, or the return value of sendStatuEvent) and request any updates required to the engine. To do so, every context defines a process_update function, which manages distributing displaying the result of the player's actions, as dictated by the GSV. If the context has changed in the state as a result of this event, the active state of the inputhandler will have changed. Always call the inputhandler's process_update or _input functions, never use an active context directly.

The documentation of which active contexts fire events in which circumstances is documented under DOCUMENTATION/CONTEXT/*.md (TODO).

About

Godot Persona X Project

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published