๐Ÿ“ฆ sleepyfran / duets

๐Ÿ“„ copilot-instructions.md ยท 51 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51This is an F# repository for a text-based music and life simulation game that runs in the terminal. The game allows the
player to create their own character, band and explore multiple cities to perform gigs, record albums and manage their
career as well as their life.

# Project Structure

The project is divided into several projects:

- `Duets.Cli`: The main entry point of the game, containing the game loop and user interface.
- `Duets.Entities`: Contains the domain entities and types used throughout every other project.
- `Duets.Simulation`: Contains the core game logic. Completely stateless and pure functions that receive the current game state
  and return a set of effects (as defined in `Duets.Entities`) that modify the game state, as well as the new game state. These
  effects are then interpreted by the `Duets.Cli` project to display the results to the player. This layer should **NEVER** contain
  any side effects or translation strings. Those should always be handled by the CLI.
- `Duets.Data`: Contains static data used in the game, such as the game world (cities, venues, etc.), genres, instruments, etc.
- `Duets.Agents`: Contains various asynchronous agents (implemented using MailboxProcessor) that handle background tasks such as
  saving/loading the game on every turn, logging game events, keeping the current state of the game and tracking the play time.
- `Duets.Common`: Contains common utilities and helper functions used across multiple projects.

# Sample flow of a turn

1. The player, currently in the world scene (free roam mode), is presented with a prompt and a list of available commands
   that are contextually generated based on the current game state, location and other factors (computed in `availableCurrently` on the `Interactions.fs` file).
   Interactions contain all information needed to execute the underlying command, for example in the case of a movement it contains
   the ID of the destination location.
2. The `World.fs` file that defines the world scene, maps the available interactions to commands that the player can execute.
3. The player executes a command in the terminal, for example `n` to move north.
4. The `Duets.Cli` project, running the `worldScene` function in a loop, receives and interprets the command, executing
   the handler for the `n` command (defined in `Movement.Command.fs`).
5. The handler gets the current game state from the `GameStateAgent` in the `Duets.Agents` project and then calls the `enter` function
   defined in the `Duets.Simulation` project, passing the current game state and the destination location ID as parameters.
6. The `enter` function applies the destination room policies to determine if the player can enter the room and, if so,
   returns a set of effects (e.g. `WorldMoveToPlace`).
7. Back in the command handler, the result is interpreted by the CLI, showing an error to the user if the player cannot enter the room,
   or calling the `apply` function in `Effect.fs`.
8. The `apply` function calls `tickOne` in `Simulation.fs` (in the `Duets.Simulation` project), gathering all final effects
   generated by it and displaying them to the user if necessary. 
     - The `tickOne` function might also generate additional effects (for example, if the effect has an event associated with it) that
       are also applied to the game state.

# Overview of a feature

- Everything should be defined in a type in the `Duets.Entities` project.
- The core logic should be defined in a pure function in the `Duets.Simulation` project that receives the current game state and
  any other needed arguments and returns a set of effects that modify the game state.
- The way the effects apply to the state should be defined in the `State.fs` function in the `Duets.Simulation` project.
- All core game logic should have unit tests in the `tests` folder under the `Simulation.Tests` project.
- The CLI should interpret the effects and display the results to the user in the `Duets.Cli` project. There are already
  a plethora of built-in components to display information in the `Components` folder, like layouts, notifications, tables, bar charts, etc.
- If needed, static data should be added to the `Duets.Data` project.