Project Details

  • Title: Solitaire
  • Tools: Visual Studio Code, Godot (v4.6.2), .NET/C#
  • Team: Nicholas Olsen (Lead Developer)
  • Purpose: Conceptal .NET Mobile Game

Features

  • Data Persistence: Utilizes Godot’s internal file system to manage and store user settings and game data within the local directory.
  • Turn Managment: Implements an "Undo" system by capturing and storing card coordinates and game variables after every valid move.
  • Interpolated Movement: Features "Active Design" where cards use smooth vector interpolation to slide into position rather than instantly snapping, creating a more tactile user experience.

Architecture

The application leverages the Godot Engine's node-based architecture for modularity.

C#/.NET Integration

Built with a C# backend to handle complex game logic and state management.

Scene Composition

Utilizes a highly reusable CardObject scene. By instantiating this scene 52 times, each instance manages its own textures, metadata, and state-driven properties, allowing for efficient memory usage and cleaner code.

Challenges

Throughout development as simple features grew into more complex ones several problems occurred such as:

  • Turn Managment: Capturing a "complete" turn proved difficult due to the game's physics. Cards would often be mid-animation when the state was saved, leading to "snap states" where the undo position was slightly off.
    • Fix: I decoupled the visual position from the logical position. Instead of saving the card's current coordinates, the system captures the target Vector2 of the destination, ensuring the undo function always returns cards to the exact intended grid point.
  • Auto Move: Implementing a double-click shortcut required an efficient way to determine the "best" legal move instantly.
    • Fix: I implemented a hierarchical decision tree. The algorithm prioritizes the Foundation stacks first to progress the game state, before checking for valid moves within the Tableau.
  • Parent-Child Stacking: A common issue in Godot is managing "re-parenting" nodes at runtime. Cards would occasionally "detach" from their stacks during a snap because the old parent-child relationship was being cleared before the new one was fully established.
    • Fix: I consolidated the re-parenting logic directly into the function that checks for correct snap. This ensures the hierarchy is updated in a single atomic operation, preventing cards from being "orphaned" in the scene tree.

Project Gallery

Check out some photos of the Solitaire Game in action. (played on emulator)