Skip to content

Commit f29388d

Browse files
authored
Merge pull request #371 from endlessm/high-level-docs
High level docs
2 parents bc877a1 + 0030a9a commit f29388d

File tree

6 files changed

+157
-140
lines changed

6 files changed

+157
-140
lines changed

addons/block_code/README.md

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ See our [pedagogy and audience documentation](docs/PEDAGOGY.md) for more info.
3434

3535
3. Make sure to enable the plugin in **Project****Project Settings****Plugins**.
3636

37-
4. You're ready to get started! Open a scene, select a node, and observe that there's a **Block Code** section within the lower central pane of the Godot editor, where you usually find debugging, animation and shader functionality. Click **Block Code** and then use the **Add Block Code** button to create a block canvas.
38-
39-
5. Drag blocks from the picker and snap them together to create a script. You can switch to other Block Code scripts by selecting the respective node from the scene tree.
40-
41-
6. **Run** the scene to see your Block Code scripts in action. Block Code scripts are saved within the scene.
37+
You're ready to get started! You can continue reading our [user documentation](docs/USAGE.md).
4238

4339
If you clone the plugin's git repository and open it in Godot, you will be presented with a block-built Pong game as an example.
4440

@@ -54,22 +50,6 @@ We will now seek feedback from learners, educators and game makers, as well as r
5450

5551
There is no language or data format stability implemented or expected in these early stages. If you upgrade the block coding plugin within an existing project, expect any existing block scripts to stop working and need reimplementing from scratch. For now, you probably want to avoid updating the plugin within your project if it's meeting your needs, or only doing that very sporadically. We will consider offering stability guarantees in future stages of development.
5652

57-
## General user guidance
58-
59-
Block scripts run against the node where you created them. The "Queue Free" block is going to free that node, not any other.
60-
61-
The selection of available blocks varies based on the node type. For example, create a block script on an `Area2D` and you will notice that you have an `On body entered` signal handling block available. Create a node script on an `AnimationPlayer` node and you will observe blocks for starting and stopping animations.
62-
63-
If you wish to switch context to another node, you need to define a function in that other node, and then call it. Once execution jumps into that function, blocks will now act against that other node, and you'll have access to type-specific blocks belonging to that other node. You'll need do this kind of thing if you want to trigger the freeing of another node, or trigger an animation to start playing. This is both strong in conveying the concepts of objects and encapsulation, while also a bit tedious - we may revisit in future!
64-
65-
We have some high level blocks for simplifying common game elements. Add a SimpleCharacter node to get a game element that can be connected to keyboard and gamepad input with just one type-specific block. Add a SimpleScoring node to display a score on-screen, accompanied by simple blocks for adjusting that score.
66-
67-
Lean into animations! Godot's animations functionality goes beyond just simple animations of graphics. You can do so much by combining block coding with Godot's powerful animations editor.
68-
69-
If you want to access the node's property, you can drag the property from the Inspector dock and drop it into the block script as a getter block. And, if you want to modify the property's value, please press & hold Ctrl key when you drop the property, then it will be a setter block of the property in the block script.
70-
71-
You can also drag a file from the Resource Filesystem dock and drop it into the block script as a getter block. It will become a constant value block holding the file's resource full path.
72-
7353
## Feedback & Discussion
7454

7555
Please join our [Discussion Board](https://github.com/endlessm/godot-block-coding/discussions) to provide feedback, share ideas, and ask questions about building your games with Block Coding.

addons/block_code/code_generation/block_definition.gd

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,62 @@ const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{const (?<const
1111
## (for any node).
1212
@export var target_node_class: String
1313

14+
## A description for this block, which will be shown to the user in a tooltip.
1415
@export_multiline var description: String
16+
17+
## The category under which this block will appear in the Picker.
1518
@export var category: String
1619

17-
@export var type: Types.BlockType
20+
## Which kind of block is this. See [enum Types.BlockType].
21+
@export var type: Types.BlockType:
22+
set = _set_type
23+
24+
## Only relevant for Value blocks. The variant type that this block is
25+
## supposed to return.
1826
@export var variant_type: Variant.Type
1927

28+
## Template for creating the UI of this block. That is, the labels and the
29+
## parameters that will become user inputs with slots. The UI can be split
30+
## between basic and advanced using the [code]|[/code] character as separator.
31+
## Example:
32+
## [codeblock]
33+
## say {salute: STRING} | {fancy: BOOL}
34+
## [/codeblock]
2035
@export var display_template: String
36+
37+
## Template for the generated GDScript code. This must be valid GDScript. The
38+
## parameters in [member display_template] will be replaced by the user input
39+
## or by the resulting value of snapped blocks.
40+
## Following the example in [member display_template]:
41+
## [codeblock]
42+
## if {fancy}:
43+
## print_rich('[color=green][b]' + {salute} + '[/b][/color]')
44+
## else:
45+
## print({salute})
46+
## [/codeblock]
2147
@export_multiline var code_template: String
48+
49+
## Optional defaults for the variables defined in [member display_template].
50+
## The key must be of type String and match a variable name in both [member
51+
## display_template] and [member code_template]. The value must be of the same
52+
## type as defined in the [member display_template].
2253
@export var defaults: Dictionary
2354

24-
## Only for blocks of type Types.ENTRY. If non-empty, this block defines a
25-
## callback that will be connected to the signal with this name.
55+
## Only for blocks of type [member Types.BlockType.ENTRY]. If non-empty, this
56+
## block defines a callback that will be connected to the signal with this
57+
## name.
2658
@export var signal_name: String
2759

28-
## Empty except for blocks that have a defined scope
29-
@export var scope: String
30-
60+
## If checked, the block will be hidden by default in the Picker.
3161
@export var is_advanced: bool
3262

63+
## An optional script that can extend this block definition. For instance, to
64+
## dynamically add the defaults.
3365
@export var extension_script: GDScript
3466

67+
## Empty except for blocks that have a defined scope.
68+
var scope: String
69+
3570
static var _display_template_regex := RegEx.create_from_string(FORMAT_STRING_PATTERN)
3671

3772

@@ -65,6 +100,18 @@ func _init(
65100
is_advanced = p_is_advanced
66101

67102

103+
func _set_type(p_type):
104+
type = p_type
105+
notify_property_list_changed()
106+
107+
108+
func _validate_property(property: Dictionary):
109+
if property.name == "variant_type" and type != Types.BlockType.VALUE:
110+
property.usage |= PROPERTY_USAGE_READ_ONLY
111+
elif property.name == "signal_name" and type != Types.BlockType.ENTRY:
112+
property.usage |= PROPERTY_USAGE_READ_ONLY
113+
114+
68115
func create_block_extension() -> BlockExtension:
69116
if not extension_script:
70117
return null

addons/block_code/types/types.gd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
extends Node
22

33
enum BlockType {
4-
NONE,
5-
ENTRY,
6-
STATEMENT,
7-
VALUE,
8-
CONTROL,
4+
NONE, ## @deprecated
5+
ENTRY, ## A block that's the entry point. Statement or control blocks can be attached below it.
6+
STATEMENT, ## A block that executes a statement. Another statement or control block can be attached below it.
7+
VALUE, ## A block that represents a value. It could be a constant or the result of an operation. All blocks may have slots to attach value blocks in their body.
8+
CONTROL, ## A block that can conditionally execute other statement or control blocks. Another statement or control block can be attached below it.
99
}
1010

1111
const VARIANT_TYPE_TO_STRING: Dictionary = {

docs/OVERVIEW.md

Lines changed: 0 additions & 108 deletions
This file was deleted.

docs/TECH_OVERVIEW.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Technical Overview
2+
3+
## How to create a new block
4+
5+
Blocks can be created by adding a `BlockDefinition` resource. The global blocks live in resource files under `addons/block_code/blocks/` and are organized in folders by category. You can edit these files in the Godot editor directly, by opening them from the Filesystem Dock. As any other Godot resource, they show up in the Inspector. You can use current ones as reference.
6+
7+
Currently, blocks for custom nodes can't be defined in the same way. They are instead defined programmatically in their GDScript by adding two functions: `func get_custom_class()` and `static func setup_custom_blocks()`. This is expected to be fixed in the future. See the "Simple" nodes provided by this plugin for reference. For example, `addons/block_code/simple_nodes/simple_character/simple_character.gd`.
8+
9+
You don't have to worry for adding blocks for properties setter, getter or "changer". These are generated dynamically in `addons/block_code/code_generation/blocks_catalog.gd`.
10+
11+
## User Interface
12+
13+
The plugin adds a new tab "Block Code" to the editor bottom dock. This contains the `MainPanel` control scene. Which has the following elements:
14+
* The `Picker`: Contains the list of blocks organized in categories.
15+
* The `BlockCanvas`: Is where placed blocks live. It edits the `BlockScriptSerialization` that generates the code.
16+
* The `TitleBar`: Has a dropdown to switch the BlockCode being edited and other controls.
17+
* The `DragManager`: Determines how blocks are snapped, and what happens when you drag a block from either the `Picker` or the `BlockCanvas`.
18+
19+
The `DragManager` looks for the closest compatible snap point within a certain range, and if it exists, will show a preview where your `Block` will go if you drop it.
20+
* Each `Block` has a `block_type` property, and so does each snap point. They must match to snap.
21+
* If a `Block` has the block type `VALUE`, it should have a `variant_type` property (since it represents a value). In that case, it's `variant_type` is considered for snapping along with the snap point's `variant_type`.
22+
23+
The `Block` UI is a regular Godot scene. There is one per each `block_type`. One current discrepancy is that the UI for the `VALUE` block type is called `ParameterBlock`. All others match: eg. for the `CONTROL` type there is a `ControlBlock` scene.
24+
25+
The `BlockCanvas` is filled with blocks as defined in the `BlockScriptSerialization`. When the user interacts with the `BlockCanvas`, the `BlockScriptSerialization` regenerates its GDScript. For instance when the user attaches blocks, or changes the block text input or dropdowns (scene instances of `ParameterInput`).
26+

0 commit comments

Comments
 (0)