Stockings Naughtymare is an atmospheric narrative-driven game built with Godot 4.3 and Dialogic 2. This documentation is intended to help new developers understand the project structure, core modules, and development workflow so they can start contributing effectively.
- Project Overview
- Project Structure
- Core Modules and Scripts
- Dialogue Integration with Dialogic
- Setting Up Room Scenes
- Additional Assets and Configuration
- Development Workflow
- Contributing Guidelines
- References
Stockings Naughtymare is a game where you awaken in a mysterious, eerie mansion after striking a dangerous deal with Mary—a seductive yet terrifying Christmas spirit. The gameplay is driven by interactive dialogue, puzzle-solving, and smooth scene transitions. Dialogic 2 is used for dynamic narrative events, while Godot 4.3 powers the game’s core systems.
The repository follows a standard Godot project layout:
-
/Assets/
Contains art assets (images, fonts, shaders, etc.) used by the game. -
/Autoload/
Contains global scripts (autoload singletons) that include:Global.gd
– Manages the overall game state.SignalBus.gd
– Central hub for cross-module event signaling./SceneManager/scene_manager.gd
– Handles scene transitions.
-
/addons/dialogic/
Contains the Dialogic add-on along with supporting modules (e.g., custom portraits). -
main.gd
The main game controller script, handling scene transitions, input, and pause functionality. -
main.tscn
The main scene that sets up the node hierarchy for the 2D world, HUD, GUI, and loading transitions. -
project.godot
The Godot project configuration file (includes autoload settings, input mappings, and display settings). -
.gitignore
Configures version control to ignore files and folders generated by Godot that are not needed in the repository.
-
Purpose:
Acts as the primary controller for game logic, including scene and GUI transitions, input handling, and pausing. -
Key Responsibilities:
- Managing the current 2D scene and GUI scene.
- Handling input (e.g., toggling pause mode).
- Coordinating transition animations through signals (
transitioned_in
andtransitioned_out
).
-
Important Methods:
change_gui_scene(new_scene: String, transition: bool, delete: bool, keep_running: bool)
: Switches GUI scenes.change_2d_scene(new_scene: String, delete: bool, keep_running: bool)
: Switches the game world scenes.- A custom pause property updates process modes and emits a pause signal via
SignalBus
.
-
Purpose:
Defines the root node structure, including the containers for the 2D game world and GUI. -
Key Nodes:
- Node2D: Contains the game world scenes.
- GUI (CanvasLayer): Contains GUI elements (e.g., splash screen, pause menu).
- LoadManager: Manages transition animations and loading effects.
-
Purpose:
Maintains global game state, such as:- Current room (scene) identifier.
- Dialogue history (which dialogues have been seen).
- Unlockable content and various state flags.
-
Features:
- Provides utility functions such as an auto-incrementing ID generator.
- Acts as a central reference for state variables accessed by other modules.
-
Purpose:
Serves as a centralized event dispatcher for game-wide communication. -
Key Signals:
pause(is_paused: bool)
: Emitted when the game is paused or resumed.minigame_show(id: int, type: String)
andminigame_hide
: Manage minigame-related events.pop_open
andpop_close
: Handle modal overlay events.- Other signals for events like character interactions and dialogue-specific triggers.
-
Usage:
Modules emit and listen for these signals to maintain decoupled yet coordinated communication.
-
Location:
/Autoload/SceneManager/scene_manager.gd
-
Purpose:
Manages smooth transitions between scenes. -
Key Methods:
transition_in()
: Plays the entrance transition animation.transition_out()
: Plays the exit transition animation (with optional tweened scaling).transition_to()
: Combines entrance and exit animations, awaiting their completion.
-
Integration:
Called by the main game controller to facilitate scene changes while preserving game state and user experience.
-
Location:
Custom portrait scripts extend Dialogic’slayered_portrait.gd
(located in/addons/dialogic/Modules/LayeredPortrait/
). -
Purpose:
Provides dynamic character portraits that remain persistent on the HUD and respond to dialogue events. -
Key Functions:
_update_portrait(character: DialogicCharacter, portrait_name: String)
: (Optional) Updates the portrait based on dialogue._highlight()
and_unhighlight()
: Trigger animations (e.g., playing a mouth “talk” animation) when a character starts or stops speaking.
-
Usage Example:
Developers can refer to the provided sample code that includes timers for blinking and uses Dialogic’s signals (e.g.,about_to_show_text
andtext_finished
) to manage animation.
-
Integration Details:
- Dialogic 2 drives the game’s dialogue and narrative events.
- The dialogue system emits signals such as
about_to_show_text(info: Dictionary)
andtext_finished(info: Dictionary)
(see SubsystemText documentation).
-
How It Works:
- When a dialogue line is about to display, the connected portrait script checks if the dialogue is for its character.
- If yes, it calls
_highlight()
to play the “talk” animation. - Once the dialogue text finishes,
_unhighlight()
is called to stop the animation.
-
Customization:
- Developers can modify the character-check logic (for example, by checking if the dialogue’s character field contains a certain name) to suit their project’s needs.
Room scenes represent individual areas or levels within the game world. The Test Room is provided as an example of how to set up a room scene.
-
Location:
/Scenes/Rooms/TestRoom/TestRoom.tscn
-
Purpose:
The Test Room serves as a working example and template for creating new room scenes. It demonstrates how to integrate background visuals, interactive elements, dialogue triggers, and room transitions.
-
Create the Base Scene:
- Start with a
Node2D
(or a similar node) as the root. This node defines the coordinate space and serves as the container for all room-specific elements.
- Start with a
-
Design the Environment:
- Add background elements such as sprites, tilemaps, or color rectangles to establish the room’s visual style.
- In the Test Room, a background image or tilemap is used to set the mood.
-
Add Interactive Elements:
- Include nodes like
Area2D
(with attachedCollisionShape2D
) to act as interactive triggers. These triggers can start dialogue sequences or initiate scene transitions. - For example, you might have an Area2D that, when the player enters it, calls a function to start a dialogue via Dialogic.
- Include nodes like
-
Integrate Dialogue Triggers:
- If the room contains dialogue, add nodes that call Dialogic’s dialogue functions.
- In the Test Room, a designated node (such as a Button or Area2D) may trigger
Dialogic.start_dialogue("TestDialogue")
when activated.
-
Connect to Global State:
- When a room is entered, update
Global.current_room
with the room’s scene path. This ensures that the game’s state accurately reflects the player’s location. - You can achieve this by connecting the room’s
_ready()
signal to a function that sets the current room.
- When a room is entered, update
-
Configure Transitions:
- If the room requires custom transition effects, ensure it is integrated with the
LoadManager
andSceneManager
. The main game controller uses these managers to handle smooth transitions between rooms.
- If the room requires custom transition effects, ensure it is integrated with the
Developers can use the Test Room as a blueprint for new room scenes. Key points include:
- Consistent node structure (starting with a
Node2D
root). - Organized placement of background visuals and interactive elements.
- Clear integration points for dialogue triggers and global state updates.
- Proper configuration for scene transitions and interactions.
-
Assets:
All visual and audio assets are stored under/Assets/
, organized by type (e.g., UI, fonts, shaders). -
Shaders:
Example:horizontal_split.gdshader
implements a transition effect. -
Project Settings:
Theproject.godot
file includes:- Autoload settings (defining singletons like Global, SignalBus, etc.)
- Input mappings and window configuration.
- Dialogic-specific settings (e.g., directories for dialogue and custom portraits).
-
Setting Up:
- Clone the repository and open the project in Godot 4.3.
- Verify that all necessary add-ons (especially Dialogic) are installed correctly.
-
Coding Conventions:
- Use exported variables to expose node references for easy editing.
- Utilize autoload singletons (e.g., Global, SignalBus) to manage cross-module communication.
- Favor signals to decouple systems; for example, dialogue events trigger portrait animations.
-
Testing:
- Regularly test dialogue sequences to ensure portrait animations trigger correctly.
- Verify scene transitions using the Scene Manager.
- Use Godot’s debugger and logging to monitor state changes.
-
Saving and Loading:
- The game leverages Dialogic’s custom save system integrated into Global.gd. Ensure that any new state variables are added to the save/load routines.
-
Code Reviews:
Ensure all contributions adhere to the established project structure and coding conventions. -
Documentation:
Update this documentation when making significant changes or adding new features. -
Issue Tracking:
Use the GitHub issue tracker for bug reports, feature requests, and discussions. -
Communication:
Contact the project maintainer via the GitHub repository or the itch.io page for further discussion.
- Godot Engine Documentation
- Dialogic 2 Documentation
- Dialogic Custom Portraits Documentation
- Dialogic SubsystemText Signal Documentation
This documentation serves as an overview of the codebase, design decisions, and development practices for Stockings Naughtymare. Developers are encouraged to refer to this document and the external references as they contribute to and extend the project.