{"id":23435518,"url":"https://github.com/customcommander/agricola","last_synced_at":"2025-06-30T11:06:03.918Z","repository":{"id":40593262,"uuid":"507316416","full_name":"customcommander/agricola","owner":"customcommander","description":"A recreational reactive programming project aiming at implementing the solo version of the popular board game. Work in progress...","archived":false,"fork":false,"pushed_at":"2025-01-16T22:49:05.000Z","size":600,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-30T11:06:01.626Z","etag":null,"topics":["lit","rxjs","xstate"],"latest_commit_sha":null,"homepage":"https://customcommander.github.io/agricola/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/customcommander.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-25T13:19:39.000Z","updated_at":"2025-01-16T22:49:07.000Z","dependencies_parsed_at":"2024-12-23T12:51:50.015Z","dependency_job_id":"4c57f738-99af-4218-8bc3-d2d5ea21c434","html_url":"https://github.com/customcommander/agricola","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/customcommander/agricola","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fagricola","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fagricola/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fagricola/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fagricola/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/customcommander","download_url":"https://codeload.github.com/customcommander/agricola/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fagricola/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262762468,"owners_count":23360330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lit","rxjs","xstate"],"created_at":"2024-12-23T12:51:44.778Z","updated_at":"2025-06-30T11:06:03.864Z","avatar_url":"https://github.com/customcommander.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)\n\n# Agricola\n\nA deep dive exploration of reactive programming combining state machines ([XState][]) and observables ([RxJS][]) with a web-component-based ([Lit][]) single page application. In the end I hope to build the solo version of the popular board game.\n\n## Development\n\n### Requirements\n\n- Node.js v19+\n\n### Tests\n\n```\nnpm test\n```\n\n## Architecture\n\n### Boundaries\n\nThe game engine is managed by a single state machine split into multiple services.\n\nWe can produce a diverse range of observables from the state machine. The user interface components subscribe to these observables.\n\nEven though the user interface is not allowed to subscribe directly to the state machine, it can however trigger events that will ultimately lead to state changes and new data being emitted by the observables.\n\nIn all circumstances data flows in **one and only one** direction.\n\n```mermaid\nflowchart LR\nGE(((Game Engine)))    -- produces --\u003e\nO(((Observables)))     --     feed --\u003e\nUI(((User Interface))) -- triggers --\u003e GE\n```\n\n### States Machines\n\n#### Overview\n\nThe main state machine is kept relatively simple (YMMV) as each state is expected to spawn one or more services.\n\n```mermaid\nstateDiagram-v2\n    state after_harvest \u003c\u003cchoice\u003e\u003e\n    state after_work \u003c\u003cchoice\u003e\u003e\n\n    [*] --\u003e setup\n\n    note left of setup\n    All the things we need to do\n    before we can start the game.\n    end note\n\n    setup --\u003e setup : SETUP_GAME\n    setup --\u003e work  : SETUP_DONE\n\n    note left of work\n    Keep working until we reach\n    the end of a stage (i.e. harvest time)\n    end note\n\n    work --\u003e after_work : WORK_DONE\n    after_work --\u003e work : not_harvest\n    after_work --\u003e harvest\n\n    harvest --\u003e after_harvest: HARVEST_DONE\n\n    after_harvest --\u003e work : not_end_of_game\n    after_harvest --\u003e end_of_game\n    end_of_game --\u003e [*]\n```\n\n#### Work Service\n\nThe **Work Service** is given the number of workers for the active turn and remains active until all the workers are placed on the board.\n\n```mermaid\nstateDiagram-v2\n    state after_perform \u003c\u003cchoice\u003e\u003e\n\n    [*] --\u003e init\n    init --\u003e select\n    select --\u003e perform: TASK_SELECTED\n    perform --\u003e select: TASK_CANCELLED\n    perform --\u003e after_perform: TASK_DONE\n    after_perform --\u003e select: workers_left\n    after_perform --\u003e done\n    done --\u003e [*]\n```\n\n#### Harvest Service\n\n```mermaid\nstateDiagram-v2\n    [*] --\u003e init\n    init --\u003e fields\n    fields --\u003e feed: HARVEST_FIELDS_DONE\n    feed --\u003e breed:  HARVEST_FEED_DONE\n    breed --\u003e done: HARVEST_BREED_DONE\n    done --\u003e [*]\n```\n\n[XState]: https://xstate.js.org/\n[RxJS]: https://rxjs.dev/\n[Lit]: https://lit.dev/","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcustomcommander%2Fagricola","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcustomcommander%2Fagricola","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcustomcommander%2Fagricola/lists"}