Skip to content

Internal Ponder UI

LordGrimmauld edited this page Mar 27, 2021 · 1 revision

This page guides you through creating and editing scenes visible in the Ponder environment.


What's ponder?

Ponder is Create's approach to in-game user documentation. It was started as the ultimate approach to avoid the need of online wikis or lengthy tooltips on items.
Ponder Scenes can be created and assigned to items represented by them.
As a result, the user can then enter these scenes by holding down the 'forward' key on them in any other UI.

At the core of a Ponder Scene lies a Schematic. It provides the world and blocks required to show interactions explained by the editor. The same schematic file can be used in different scenes, but scene storyboards are usually coupled quite tightly to the blocks that make up their underlying schematic.

Schematics used by ponder can be found at src/main/resources/ponder and will be shipped with the mods' jar on release. Any users' ponder library cannot be updated live, they are packed and baked into each version of the Create mod.

This is a Scene. If more scenes are registered to this item, the player will be able to navigate to them using the buttons at the bottom.
In order to give the scene more than a static view of the structure you build, a Storyboard has to be created.
Storyboards are simplified java code, which queue Instructions on a scene. Upon opening the Ponder UI the script is assigned to, the instructions will then be executed in the order they were created in. In the above example, the storyboard created a text window, and made the gantry carriage animate to move along the x-Axis.

TLDR;

  • Any Item can be assigned multiple Ponder Scenes. In-game, these scenes can be navigated with ponder UI.
  • A Scene consists of a reference to a Schematic File, as well as a Storyboard
  • Storyboards are java code that define an ordered list of Instructions to be carried out while the scene plays.
  • A large amount of Instructions are provided by Ponder's API. Examples are showSection, idle, rotateCameraY, showText

Making the schematic

The first step of making any Ponder Scene is to prepare a suitable Schematic for it.
There are a couple of things to note when making them:

  • The Base Plate of the scene has to be included in the structure. In the above example it is a 5x5 checkered pattern of snow and concrete. The base plate itself must be a square. Notice how there is a large cogwheel on the same layer next to the base plate. This is perfectly viable- the schematic can exceed the base plates' dimensions. Whenever it does, the Storyboard has to specify the actual size of the base plate using the configureBasePlate Instruction.
  • In the initial camera angle, the Origin of the schematics' coordinates is closest to the camera. The origin is the position with the lowest x and z coordinate.
    Editors can use /tp @s ~ ~ ~ -35 25 to orient themselves approximately to the initial camera angle Ponder UI will view the schematic with.
    Ensure that your schematic will not be shown from an awkward angle in the Scene.
  • Schematics should try to contain all blocks that ever become visible during the Scene. The Storyboard can control which sections of the schematics are visible at any point in time. It will be much more convenient for you to just show and hide parts of the schematic as opposed to actually replacing blocks in the virtual world of the Scene at runtime. Sometimes this is unavoidable, however, so the option still exists.

Once the schematic is prepared and saved, move it from your standard schematic folder to a suitable location inside the ponder resource folder:
-> src/main/resources/ponder/<category>/<scene_name>.nbt

Where <category> and <scene_name> are up to the editor to decide. The names are only relevant to keep things organized. Mind that inside Minecrafts resource system, only lowercase letters and underscores are allowed.
Something like My Category/My Scene.nbt should be better off as my_category/my_scene.nbt

Note: Changes to Schematic files require a Resource Reload. It can be triggered by either re-launching or pressing [F3]+[T] in-game.


Preparing the writing process

Try to remember where exactly you saved your schematics. Soon you will need to tell Ponder where to look for them.
As stated earlier, a complete scene consists of one of your Schematics as well as a Storyboard. Open your java workspace and navigate to PonderIndex.java. This is where these pairs are registered. Here's an Example:

PonderRegistry.addStoryBoard(AllBlocks.GANTRY_CARRIAGE, "gantry/intro", GantryScenes::introForPinion);

Each of these calls will register a Scene with the assigned item.

  • Argument 1, AllBlocks.GANTRY_CARRIAGE
    specifies the item or block this scene should be assigned to. Any member of AllBlocks or AllItems is viable here.
  • Argument 2, "gantry/intro"
    specifies the location of the schematic. If your schematic is located at src/main/resources/ponder/<category>/<scene_name>.nbt,
    the resulting string passed to this method should be "<category>/<scene_name>".
  • Argument 3, GantryScenes::introForPinion
    points to the java function which serves as the Storyboard in this scene. In this case its the static method introForPinion() of the GantryScenes class.

For your new Scene, create a static method inside a suitable (new) class somewhere within the ponder.content package. It should accept two parameters as follows:

public static void myStoryboard(SceneBuilder scene, SceneBuildingUtil util) {
  
}

The method and class name is up to the editor- once again, for organization. If the above method were inside a class named MyScenes, then Argument 3 passed to the registration call above should be MyScenes::myStoryBoard.

Once item, schematic and storyboard have been registered in the ponder index, the resulting scene should become accessible in-game.
Note: Changes in PonderIndex.register() require a re-launch to take effect. Hot code replace usually won't allow the creation of classes or static methods either way.
Note: An empty storyboard will result in an empty scene. To at least see if everything loaded properly, you can add the following instruction inside your storyboard method: scene.debug.debugSchematic();

Sometimes, multiple scenes are created for the same item. And sometimes, multiple items share the same scenes.
For this purpose, some shortcuts are available in the registration process:

PonderRegistry.forComponents(AllBlocks.ANDESITE_FUNNEL, AllBlocks.BRASS_FUNNEL)
			.addStoryBoard("funnels/intro", FunnelScenes::intro)
			.addStoryBoard("funnels/direction", FunnelScenes::directionality);

is equivalent to:

PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/intro", FunnelScenes::intro);
PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/direction", FunnelScenes::directionality);
PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/intro", FunnelScenes::intro);
PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/direction", FunnelScenes::directionality);

Storyboards and Instructions

You now have a schematic and a storyboard method to add instructions into, this is where the fun begins.

Available Instructions range from timed delays, particle effects and block movement to spawning dancing parrots on your schematic.
A full reference with comments can be found inside SceneBuilder.java.
DebugScenes and other existing ponder content can serve as a good practical reference for scene building, too.
Here's a nice template to start out with:

public static void template(SceneBuilder scene, SceneBuildingUtil util) {
	scene.title("This is a template");
	scene.showBasePlate();
	scene.idle(10);
	scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
}

This will simply give your scene a title of your choice and fade base plate and rest of your schematic in after one another.
From here it's for you to experiment. Thanks to hot code replace, changes inside this method can be immediately applied in game, provided you are running the instance in debug-mode from your java IDE.
To load the updated storyboard into Ponder UI, simply press [Shift]+[S] while viewing the scene. Re-opening the UI is another option to refresh.


Blocking and Non-Blocking Instructions

  • scene.idle(t) is a Blocking Instruction. Everything queued after this call will not be executed until this instruction has finished. (after t ticks)
  • scene.showText(t) and currently all others are Non-Blocking Instructions. Even though this text window will appear for a set duration (t ticks), instructions queued after this one will still be executed immediately after this text window is created.

Example:

scene.overlay.showText(20)
	.independent(0)
	.text("I'm a text box");
scene.overlay.showText(20)
	.independent(20)
	.text("I'm another text box");

Will display two text boxes simultaneously for 1 second.

scene.overlay.showText(20)
	.independent(0)
	.text("I'm a text box");
scene.idle(20)
scene.overlay.showText(20)
	.independent(20)
	.text("I'm another text box");

Will display the second text box immediately after the first one disappears.


Useful Data Types

Ponder instructions require the use of various data types, some of which are re-used from standard modding practice:

  • BlockPos represents an xyz grid position in the world.
    util.grid provides helper methods to quickly instantiate block positions.
    Inspect mode in Ponder UI will display the grid position of selected blocks.

  • Vec3d represents a floating-point xyz position in the world. (Vector3d in 1.16+)
    util.vector provides helper methods to quickly instantiate vectors.

  • Selection represents a collection of positions to target multiple blocks as a group.
    util.select provides helper methods to quickly make a selection. Selections can also be added and subtracted from each other.

  • AxisAlignedBB represents an axis-aligned cuboid with floating-point position and size.

  • ElementLink<T> provides a placeholder for the scene objects created by instructions when the scene is actually played.
    Some instructions require this link to act upon a specific element created by previous instructions.

  • PonderPalette provides a set of specified colours to keep a consistent palette within ponder.
    Text windows will use PonderPalette.WHITE by default.

Clone this wiki locally