---
title: Plant reference project
description: A deep dive into building of the Plant experience, an experience where players plant seeds and harvest plants.
---
[Plant][planturl] is a reference experience where players plant and water seeds, so they
can later harvest and sell the resulting plants.
| Service | Types of instances |
|---|---|
| `Class.Workspace` |
Contains static models representing the 3D world, specifically parts of the world that don't belong to any player. You don't need to dynamically create, modify, or destroy these instances at runtime, so it's acceptable to leave them here. There is also an empty `Class.Folder`, to which players' farm models will be added at runtime. |
| `Class.Lighting` |
Atmospheric and lighting effects. |
| `Class.ReplicatedFirst` |
Contains the smallest possible subset of instances needed to display the loading screen and initialize the experience. The more instances that are placed in `Class.ReplicatedFirst`, the longer the wait for them to replicate before code in `Class.ReplicatedFirst` can run. - In the **Instances** folder exists the loading screen GUI. - In the **Source** folder exists the loading screen code and the code needed to wait for the rest of the experience to load. The `start` `Class.LocalScript` is the entry point for all client-side code in the project. |
| `Class.ReplicatedStorage` |
Serves as a storage container for all instances for which access is required on both the client and the server. - In the **Dependencies** folder exists some third party libraries used by the project. - In the **Instances** folder exists a wide range of prefabricated instances. - In the **Source** folder exists all code **not** required for the loading process that needs to be accessible from both the client and the server. |
| `Class.ServerScriptService` |
Contains a `Class.Script` serving as the entry point for all server-side code in the project. |
| `Class.ServerStorage` |
Serves as a storage container for all instances that do not need to be replicated to the client. - In the **Instances** folder exists a template **Farm** model. A copy of this is placed in `Class.Workspace` when the player joins the experience, where it will be replicated to all players. - In the **Source** folder exists all code that is exclusive to the server. |
| `Class.SoundService` |
Contains the `Class.Sound` objects used for sound effects in the experience. Under `Class.SoundService`, these `Class.Sound` objects have no position and are not simulated in 3D space. |
Each of these systems is a "singleton," in that it's a non-instantiable class
that is instead initialized by the relevant client or server `start` script. You
can read more about the [singleton pattern](#singletons) later in this guide.
#### Server
The following systems are associated with the server.
| System | Description |
|---|---|
| **Network** | - Creates all `Class.RemoteEvent` and `Class.RemoteFunction` instances. - Exposes methods for sending and listening to messages from the client. - Type validation for arguments received from the client at runtime. |
| **PlayerDataServer** | - Saves and loads persistent player data using `Class.DataStoreService`. - Stores player data in memory and replicates mutations to the client. - Exposes signals and methods for subscribing to, querying, and updating player data. |
| **Market** | - Handles soft currency transactions from the client. - Exposes a method to sell harvested plants. |
| **CollisionGroupManager** | - Assigns player character models to [collision groups](../workspace/collisions.md#collision-filtering). - Configures collision groups so player characters can not collide with plant wagons. |
| **FarmManagerServer** | - Re-creates a player's farm model from their player data when they join the experience. - Removes the farm model when a player leaves. - Updates the player data when a player's farm is changed. - Exposes a method to access the **Farm** class associated with a given player. |
| **PlayerObjectsContainer** | - Creates various objects associated with the lifetime of a player and provides a method to retrieve these. |
| **TagPlayers** | - Adds `Class.CollectionService` tags to all player and character objects. |
| **FtueManagerServer** | - During the FTUE, executes each stage and waits for it to complete. |
| **CharacterSpawner** | - Respawns characters when they die. Note that `Class.Players.CharacterAutoLoads` has been disabled so that spawning is paused until the player's data has loaded. |
| System | Description |
|---|---|
| **Network** | - Waits for the server to create all `Class.RemoteEvent` and `Class.RemoteFunction` instances. - Exposes methods for sending and listening to messages to and from the server. - Enforces runtime parameter type validation. - Runs `Global.LuaGlobals.pcall()` on remote functions. |
| **PlayerDataClient** | - Stores the local player's data in memory. - Exposes methods and signals for querying and subscribing to changes in player data. |
| **MarketClient** | - Exposes a method to request the server to purchase an item for soft currency. |
| **LocalWalkJumpManager** | - Exposes methods to modify the `Class.Humanoid.WalkSpeed|WalkSpeed` or `Class.Humanoid.JumpHeight|JumpHeight` of a character via multipliers to avoid conflicts when modifying these values from multiple places. |
| **FarmManagerClient** | - Listens for specific `Class.CollectionService` tags being applied to instances and creates "components" appending behavior to these instances. A "component" refers to a class that is created when a `Class.CollectionService` tag is added to an instance and destroyed when it is removed; these are used for the CTA prompts in the farm and various classes telegraphing farm state to the player. |
| **UISetup** | - Initializes all UI layers. - Configures certain layers to be visible only in physical sections of the world. - Hooks up a special camera effect for when menus are enabled. |
| **FtueManagerClient** | - Configures FTUE stages on the client. |
| **CharacterSprint** | - Uses **LocalWalkJumpManager** to increase `Class.Humanoid.WalkSpeed|WalkSpeed` when a player character is outside of their farm. |
| Approach | Advantages and drawbacks |
|---|---|
| **Imperative** |
In the imperative approach, UI is treated like any other instance hierarchy on Roblox. The UI structure is created before runtime in Studio and added to the data model, typically directly in `Class.StarterGui`. Then, at runtime, code manipulates specific pieces of the UI to reflect the state the creator requires. This approach comes with some advantages. You can create the UI from scratch in Studio and store it in the data model. This is a simple and visual editing experience that can accelerate UI creation. Because imperative UI code only concerns itself with what needs changing, it also makes simple UI changes easy to implement. A notable drawback is that, since imperative UI approaches require state to be manually implemented in the form of transformations, complex representations of state can become very hard to find and debug. It's common for errors to emerge when developing imperative UI code, especially when state and the UI becomes desynchronized due to multiple updates interacting in an unexpected order. Another challenge with imperative approaches is that it's harder to break down UI into meaningful components that can be declared once and reused. Because the entire UI tree is declared at edit time, common patterns may be repeated in multiple parts of the data model. |
| **Declarative** |
In the declarative approach, the desired state of UI instances are declared explicitly, and the efficient implementation of this state is abstracted away by libraries such as [Roact](https://github.com/Roblox/roact/) or [Fusion](https://github.com/Elttob/Fusion). The advantage of this approach is the implementation of state becomes trivial and you only need to describe what you want your UI to look like. This makes identifying and resolving bugs significantly easier. The key drawback is having to declare the entire UI tree in code. Libraries like Roact and Fusion have syntax to make this easier, but it's still a time consuming process and a less intuitive editing experience when composing UI. |
### Layer and components
In [Plant][planturl], all UI structures are either a `Layer` or a `Component`.
- `Layer` is defined as a top level grouping singleton that wraps prefabricated UI structures in `Class.ReplicatedStorage`. A layer may contain a number of components, or it may encapsulate its own logic entirely. Examples of layers are the inventory menu or the number of coins indicator in the heads up display.
- `Component` is a reusable UI element. When a new component object is instantiated, it clones a prefabricated template from `Class.ReplicatedStorage`. Components may in themselves contain other components. Examples of components are a generic button class or the concept of a list of items.
### View handling
A common UI management problem is view handling. This project has a range of menus and HUD items, some of which listen to user input, and careful management of when they are visible or enabled is required.
[Plant][planturl] approaches this problem with its **UIHandler** system which manages when a UI layer should or should not be visible. All UI layers in the experience are categorized as `HUD` or `Menu` and their visibility is managed by the following rules:
- The enabled state of `Menu` and `HUD` layers can be toggled.
- Enabled `HUD` layers are only shown if no `Menu` layers are enabled.
- Enabled `Menu` layers are stored in a stack, and only one `Menu` layer is visible at a time. When a `Menu` layer is enabled, it is inserted to the front of the stack and shown. When a `Menu` layer is disabled, it is removed from the stack and the next enabled `Menu` layer in the queue is shown.
This approach is intuitive because it allows menus to be navigated with history. If one menu is opened from another menu, closing the new menu will show the old menu again.
UI layer singletons register themselves with the **UIHandler** and are provided with a signal that fires when its visibility should change.
## Further reading
From this thorough overview of the [Plant][planturl] project, you may want to
explore the following guides which go further in depth on related concepts and
topics.
- [Client-Server Model](../projects/client-server.md) — An overview of the
client-server model in Roblox.
- [Luau](../luau/) — Details on **Luau**, the Roblox-created scripting language
descended from [Lua 5.1](https://www.lua.org/pil/5.1.html).
- [Remote Events and Callbacks](../scripting/events/remote.md) — All about
remote network events and callbacks for communication across the client-server
boundary.
- [UI](../ui/) — Details on user interface objects and design on Roblox.
[planturl]: https://www.roblox.com/games/14353060924/Plant