How chobotov/yohoho-test works
1. Project type and shape
- This is a Unity 2022.3 mobile game project built around a small gameplay loop: move a player with a touch joystick, pick up items into a stack, and drop them into a release zone.
- The codebase is split cleanly between game-specific source under Assets/_src and imported dependencies/assets under Assets/Plugins and Assets/Imported Assets.
2. Main runtime entry and scene flow
- The project uses two main scenes: Entry Point.unity and Game.unity.
- AppController plus the lifetime-scope classes (AppLifetimeScope, GameLifetimeScope) appear to handle bootstrap and scene-level composition.
- EcsStartup is the likely bridge that initializes the ECS world/systems for the game scene.
3. Core gameplay architecture: ECS-first
- The game logic is organized into an ECS layer under Assets/_src/5 - Scripts/Runtime/Ecs.
- Data is split into components such as input, movement, rotation, unit, item, inventory, level, pickup, and drop.
- Behavior is split into systems that operate on those components rather than directly coupling objects together.
4. Input subsystem
- Touch control is handled by a joystick asset imported under Assets/Imported Assets/Joystick Pack.
- InputSystem converts player input into ECS-side input state/events, likely represented by InputEvent.
- This isolates platform-specific UI input from the gameplay logic.
5. Movement and orientation pipeline
- Movement is decomposed into separate ECS concerns:
- MoveVelocitySystem derives velocity,
- MoveSystem applies positional movement,
- RotationSystem handles facing direction,
- AnimatorSystem syncs animation with motion state.
- This separation makes the player controller easy to extend without putting all behavior into one script.
6. Stack / inventory gameplay
- The stack mechanic is represented by inventory-related components and runtime model classes:
- InventoryComponent in ECS,
- UnitInventory and Item in game domain classes.
- Pickup and drop flows are handled by dedicated systems:
- PickupItemDistanceSystem and DropZoneDistanceSystem decide eligibility,
- PickupItemSystem and DropItemSystem perform the actual transfer of items.
- This is the main gameplay loop boundary: proximity detection first, state mutation second.
7. Item generation and level content
- CreateItemSystem is the generator feature described in the README: items are produced on a timer.
- Level content is driven by LevelsConfig, ItemsConfig, and PlayerConfig assets under Assets/_src/2 - Data/Configs.
- CreateLevelSystem and CreateUnitSystem likely instantiate the level and player entities from those configs.
8. Game-domain factories and views
- LevelFactory, PlayerFactory, and ItemsFactory sit between the ECS/domain layer and Unity prefabs.
- View-facing classes like LevelView and UnitView represent the scene objects that ECS/entities are bound to.
- Prefabs in Assets/_src/3 - Prefabs provide the concrete Unity objects for the app controller, game level, player, and item stack.
9. Services and cross-cutting state
- LevelService and ScoreService are domain services, each with an interface and implementation.
- These services likely hold shared progression/state that is not purely entity-local, such as current level or score.
- GameState suggests a small runtime state container for overarching game status.
10. UI boundary
- MainCanvas is the primary UI root under Assets/_src/5 - Scripts/Runtime/UI.
- The README mentions a “minimal UI” for stack display, so UI is intentionally lightweight and probably reflects inventory/stack state rather than driving gameplay.
- Text rendering uses TextMesh Pro, imported as a standard Unity package asset set.
11. Imported libraries and why they matter
- UniTask is included and likely used for async flows such as timing, initialization, or scene/bootstrap sequencing.
- UniRx is also present, indicating reactive patterns may be used for UI binding, events, or state observation.
- These packages shape the architecture by reducing callback-heavy Unity code and making state propagation more declarative.
12. Visual/content assets are decoupled from gameplay code
- The repository contains large imported art packs: stickman character animations, a town environment pack, joystick UI assets, and TextMesh Pro resources.
- These are treated as external content, while the gameplay code in _src stays focused on logic and orchestration.
- For an architecture diagram, this is a useful boundary: game systems consume prefab/model/config assets, but do not own them.
13. Editor and assembly boundaries
- The codebase uses .asmdef files, separating runtime and editor code into distinct compilation units.
- There is an editor assembly for the joystick pack and a game editor assembly (YohohoEditor.asmdef), which helps isolate tooling from runtime gameplay.
- This supports faster iteration and clearer dependency direction.
14. Overall data flow
- Input comes from the joystick UI → becomes ECS input state → drives movement/rotation systems → player collides or reaches item zones → pickup/drop systems mutate inventory/stack state → UI and animation reflect the updated state.
- Separately, the level/item creation systems spawn content on timers or startup, feeding the same inventory loop.
- The architecture is therefore a scene/bootstrap layer + ECS gameplay core + prefab/config/view boundary, with imported assets feeding presentation and control.
Main entry points: EcsStartup.cs ECS Startup · CreateLevelSystem.cs Create Systems · MoveComponent.cs Move Data · InventoryComponent.cs Inventory
Components 34
Bootstrap
Scene startup, lifetime scopes, and game initialization.
- Entry Point · Bootstrap scene that starts the app.
Assets/_src/4 - Scenes/Entry Point.unity - Game Scene · Main gameplay scene.
Assets/_src/4 - Scenes/Game.unity - AppController · Scene-root controller for app startup.
Assets/_src/5 - Scripts/Runtime/App/App/AppController.cs - App Scope · Application-level composition root.
Assets/_src/5 - Scripts/Runtime/App/LifetimeScope/AppLifetimeScope.cs - Game Scope · Scene-level composition root for gameplay.
Assets/_src/5 - Scripts/Runtime/App/LifetimeScope/GameLifetimeScope.cs - ECS Startup · Initializes ECS world and systems.
Assets/_src/5 - Scripts/Runtime/App/Ecs/EcsStartup.cs
ECS Gameplay
Core entity/component/system gameplay loop.
- Input System · Converts joystick input into ECS input state.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Input/InputSystem.cs - Velocity · Derives movement velocity from input/state.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Velocity/MoveVelocitySystem.cs - Move · Applies positional movement.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Move/MoveSystem.cs - Rotation · Updates facing direction.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Rotation/RotationSystem.cs - Animator · Syncs animation with movement state.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Animator/AnimatorSystem.cs - Pickup Range · Detects when items are close enough to pick up.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Item/PickupItemDistanceSystem.cs - Pickup · Transfers eligible items into inventory.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Item/PickupItemSystem.cs - Drop Range · Detects when the release zone can accept items.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Item/DropZoneDistanceSystem.cs - Drop · Removes items from inventory into the release zone.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Item/DropItemSystem.cs - Create Systems · Spawns level, unit, and timed items.
Assets/_src/5 - Scripts/Runtime/Ecs/Systems/Create/CreateLevelSystem.cs - Input Event · ECS-side input event/state.
Assets/_src/5 - Scripts/Runtime/Ecs/Components/Input/InputEvent.cs - Move Data · Movement data for ECS entities.
Assets/_src/5 - Scripts/Runtime/Ecs/Components/Move/MoveComponent.cs - Inventory · Stack/inventory state for units.
Assets/_src/5 - Scripts/Runtime/Ecs/Components/Stack/InventoryComponent.cs - Item Marks · Pickup, drop, and item entity markers.
Assets/_src/5 - Scripts/Runtime/Ecs/Components/Item/ItemComponent.cs - Level Data · Level entity data.
Assets/_src/5 - Scripts/Runtime/Ecs/Components/Level/LevelComponent.cs
Domain
Factories, services, and runtime game models.
- Player Factory · Builds player-domain objects and prefabs.
Assets/_src/5 - Scripts/Runtime/Game/Player/PlayerFactory.cs - Level Factory · Builds level objects and scene binding.
Assets/_src/5 - Scripts/Runtime/Game/Level/LevelFactory.cs - Items Factory · Creates item-domain objects and views.
Assets/_src/5 - Scripts/Runtime/Game/Items/ItemsFactory.cs - Level Service · Tracks level progression/state.
Assets/_src/5 - Scripts/Runtime/Services/LevelService/LevelService.cs - Score Service · Tracks score/progression state.
Assets/_src/5 - Scripts/Runtime/Services/ScoreService/ScoreService.cs - Game State · Shared runtime game status container.
Assets/_src/5 - Scripts/Runtime/Game/GameState.cs - Unit View · Scene object bound to player/unit entities.
Assets/_src/5 - Scripts/Runtime/Game/Player/UnitView.cs - Level View · Scene object bound to level entities.
Assets/_src/5 - Scripts/Runtime/Game/Level/LevelView.cs
Assets
Imported content and Unity prefab/config boundaries.
- Player Config · Player tuning data.
Assets/_src/2 - Data/Configs/Player/Player Config.asset - Items Config · Item generation/content data.
Assets/_src/2 - Data/Configs/Items/Items Config.asset - Levels Config · Level progression/content data.
Assets/_src/2 - Data/Configs/Levels/Levels Config.asset - Joystick Pack · Imported touch joystick controls.
Assets/Imported Assets/Joystick Pack
UI
Minimal player-facing interface and display layer.
- Main Canvas · Primary UI root for minimal stack display.
Assets/_src/5 - Scripts/Runtime/UI/MainCanvas.cs
Connections 38
- Entry Point → AppController: loads · Entry scene hosts the app controller.
- AppController → App Scope: composes · App controller wires application lifetime scope.
- App Scope → Game Scope: spawns · Application scope prepares scene-level composition.
- Game Scene → Game Scope: hosts · Game scene contains the gameplay lifetime scope.
- Game Scope → ECS Startup: boots · Game scope starts ECS initialization.
- ECS Startup → Input System: registers · Startup installs input processing.
- ECS Startup → Velocity: registers · Startup installs movement derivation.
- ECS Startup → Move: registers · Startup installs movement application.
- ECS Startup → Rotation: registers · Startup installs facing updates.
- ECS Startup → Animator: registers · Startup installs animation syncing.
- ECS Startup → Pickup: registers · Startup installs pickup mutation.
- ECS Startup → Drop: registers · Startup installs drop mutation.
- ECS Startup → Create Systems: registers · Startup installs spawning systems.
- Input System → Joystick Pack: reads · Joystick UI is the player input source.
- Input System → Input Event: writes · Input becomes ECS-side input state.
- Input Event → Velocity: drives · Input state feeds movement calculation.
- Velocity → Move Data: updates · Velocity is stored on movement data.
- Move → Move Data: consumes · Movement system applies the movement data.
- Rotation → Move Data: uses · Facing is derived from motion state.
- Animator → Move Data: reads · Animation reflects locomotion state.
- Pickup Range → Item Marks: checks · Distance gate uses item markers.
- Pickup → Inventory: mutates · Pickup transfers items into inventory.
- Drop Range → Inventory: checks · Drop eligibility depends on inventory state.
- Drop → Inventory: mutates · Drop removes items from inventory.
- Create Systems → Player Config: uses · Player creation is driven by config.
- Create Systems → Items Config: uses · Item spawning uses item config.
- Create Systems → Levels Config: uses · Level creation uses level config.
- Create Systems → Level Data: creates · Level entity data is initialized.
- Player Factory → Unit View: binds · Player factory binds gameplay object to view.
- Level Factory → Level View: binds · Level factory binds level object to view.
- Items Factory → Item Marks: creates · Items factory produces item entities/data.
- Level Service → Game State: updates · Level service contributes shared state.
- Score Service → Game State: updates · Score service contributes shared state.
- Main Canvas → Inventory: reflects · UI shows stack/inventory status.
- Main Canvas → Score Service: observes · UI can react to score changes.
- Player Factory → Player Config: uses · Player factory reads player tuning.
- Level Factory → Levels Config: uses · Level factory reads level tuning.
- Items Factory → Items Config: uses · Item factory reads item tuning.