crft

Crapht Box - The Fantasy Physics Sandbox!

View on GitHub

Homepage

Welcome to Crapht Box

Crapht Box is a Fantasy Physics Sandbox, inspired by the Fantasy Console genre. It brings a simulated world with a number of disks and tools, and leaves you to play, program and share creations.

Table of content

HOME

Part I. Fundamental

Operations

Application:

Home:

Crafting:

Capturing

Screenshot

Press F6 to take a screenshot, it prompts to save to your local storage.

GIF

Press F7 to record frames for GIF, press F8 to stop GIF recording, it prompts to save to your local storage.

Specifications

You can bind the gamepad buttons to keyboard or a gamepad device. The Left, Right, Up, Down, A, B are respectively binded to the A, D, W, S, J, K by default, you can change it in the Option tab.

Disk structure

A typical disk comes with the following files under “${disk}/content”:

File Note Editing
“info.json” Meta data of this disk External text editors
“dictionary.json” Localization data External text editors
“storyboard.json” Storyboard data, including speech, dialog text, element indicator, etc. External text editors
“toolbox.json” Availability data of the tools External text editors
“scene.json” Scene data, including map path, instantiated elements and prefabs Built-in map/level/element editors
“map.map” Map file Open “scene.json” with built-in map editor
“disk.wren” Disk-wise utilities N/A
“main.wren” Main source file Built-in code editor, or external text editors
“main.palette” Palette file N/A
“sticker.png” Disk sticker Built-in capturing, or external image editors

The meta data file “info.json” contains a number of fields that describe basic aspects of a disk. You might want to change some of it after creating a new disk. It can be loaded by Load.diskInfo() with module “disk”. E.g.

{
	"lang": 16,                  // 16 for Wren, 20 for Lua.
	"usage": 0,                  // Reserved, always set to 0 for now.
	"ugcid": 0,                  // 0 for common disk, otherwise with the Workshop ID of this disk.
	"uid": "00000000-0000-0000-0000-000000000000", // Reserved.
	"sticker": "sticker.png",    // The sticker image.
	"title": {                   // The display title in different languages.
		"english": "Noname",
		"chinese": "未命名"
	},
	"description": "",           // The description on the Workshop web page.
	"author": "Anonymous",       // Your name here.
	"version": "1.0",            // The version number.
	"genre": "ANY",              // Reserved.
	"email": "",                 // Reserved.
	"url": "",                   // Reserved.
	"creation": 0,               // Reserved.
	"controls": [ ],             // Reserved.
	"entries": {                 // The entry file path.
		"main": "main.wren",
		"editor": ""
	},
	"bundle": {                  // The bundle name in different languages.
		"english": "Noname",
		"chinese": "未命名"
	},
	"priority": 100,             // A integer which controls display orders of disks.
	"locked": false              // You have to pass previous levels before unlocking
	                             // this one with `true`, or ready to play with `false`.
}

The “dictionary.json” contains text information for runtime lookup. It can be loaded by the Dictionary class in module “dictionary”. E.g.

{
	"english": {
		"greeting": "Ahoy!",

		"stars": "Missions",
		"stars/goal/tips": "Reach the goal",
		"stars/defeat/tips": "Defeat the enemies",
		"stars/time/tips": "Complete in 90s"
	},
	"chinese": {
		"greeting": "嗨!",

		"stars": "任务",
		"stars/goal/tips": "到达目标点",
		"stars/defeat/tips": "打败敌人",
		"stars/time/tips": "在 90 秒内通关"
	}
}

The “storyboard.json” can be loaded by the Storyboard class in module “disk”. E.g.

{
	"storyboard": {
		"load": [
			{
				"type": "chat",
				"text": "greeting"
			},
			{
				"type": "say",
				"text": "ahoy."
			}
		]
	}
}

The “toolbox.json” can be loaded by Load.toolAvailability(...) with module “disk”. E.g.

{
	"availability": [
		{
			"category": "*",
			"name": "*",
			"value": true
		}
	]
}

The “scene.json” can be loaded by Load.sceneGraph(...) with module “disk”. E.g.

{
	"map": "map.map",
	"toolbox": [
	],
	"prefab": [
		{
			"type": "create",
			"category": "prefab",
			"name": "goal_text",
			"position": [
				42.5, 2.5
			],
			"rotation": [
				0, 1
			],
			"tag": "goal"
		}
	]
}

HOME

Part II. Crafting

There are four element categories in the crafting toolbox.

Physics elements

The physics category contains regular rigid bodies in a few shapes. It is the simplest structure in Crapht Box that does not conduct anything in a circuit, but it does work as framework in the physical scene. See physics elements for items. See tooltips in application for details.

Sensor elements

The sensor category contains gamepad input, mouse/touch input, in-scene interactable sensors, etc. Sensor can be used as signal source in a circuit. See sensor elements for items. See tooltips in application for details.

Chip elements

The chip category contains signal producers, conductors, mappers, consumers, etc. Chip can be used as signal source, intermediate node or output reactor in a circuit. See chip elements for items. See tooltips in application for details.

Dynamics elements

The dynamics category contains power sources, weapons, etc. Dynamics can be used as output reactor in a circuit. See dynamics elements for items. See tooltips in application for details.

HOME

Part III. Programming

Physics engine

Crapht Box uses the Box2D engine for physics simulation.

Syntax

Wren

Disk in Crapht Box is mainly programmed in the Wren programming language.

Lua

Experimental: It is also possible to program in the Lua programming language, using the B95 compiler implemented in Wren.

Importing

import "compiler/lua" for Lua

Class Lua

Key of options Value Note
"constructor" "new", "ctor" Always use "ctor" in Crapht Box

E.g.

import "b95" for Lua

var lua = Lua.new()
var code = lua.compile("print(22 / 7)")
System.print(code.toString)

Subscribe to the “Lua Loader” (ID: 1984358157) for details.

Directories

All data and editable disks are stored in a library directory on local storage. The root path of ${Documents} is:

Lookup priorities for import:

Priority Directory Note
1 Built-in For Meta, Random
2 ${disk}/content/” ${disk} is the current running one
3 ${app}/shell/content/”  
4 Falls to reading/writing solvers  

Reading/writing solvers for IO accessing:

Prefix Directory Note
“app://” ”./” The current working directory
“disk://” ${disk}/” ${disk} is the current running one
“doc://” ${Documents}/”  
- - Can be relative or absolute path

Coordinates

Crapht Box implements two kinds of coordinate systems. The first one starts from the top-left corner for graphics primitives, GUI overlays, etc. and the second one starts from the bottom-left corner for in-scene objects.

Screen space:

World space:

Besides, there’s another local space which is similar to the world space, but the axises rotate along with an element itself.

Basic

Basic module

Crapht Box runs on top of a BASIC system. This module contains wrappers to communicate to it.

Importing

import "basic" for Basic, Terminal, Resource

Class Basic

The tones are indicated by letters A through G. Accidentals are indicated with a + or # (for sharp) or - (for flat) immediately after the note letter. See this example:

Basic.play("C C# C C#", 0, 0, false)

Whitespaces are ignored inside the string expression. There are also codes that set the duration, octave and tempo. They are all case-insensitive. play executes the commands or notes the order in which they appear in the string. Any indicators that change the properties are effective for the notes following that indicator.

Ln     Sets the duration (length) of the notes. The variable n does not indicate an actual duration
       amount but rather a note type; L1 - whole note, L2 - half note, L4 - quarter note, etc.
       (L8, L16, L32, L64, ...). By default, n = 4.
       For triplets and quintets, use L3, L6, L12, ... and L5, L10, L20, ... series respectively.
       The shorthand notation of length is also provided for a note. E.g. "L4 CDE L8 FG L4 AB"
       can be shortened to "L4 CDE F8G8 AB". F and G play as eighth notes while others play as quarter notes.
On     Sets the current octave. Valid values for n are 0 through 6. An octave begins with C and ends with B.
       Remember that C- is equivalent to B. 
< >    Changes the current octave respectively down or up one level.
Nn     Plays a specified note in the seven-octave range. Valid values are from 0 to 84. (0 is a pause).
       Cannot use with sharp and flat. Cannot use with the shorthand notation neither.
MN     Stand for Music Normal. Note duration is 7/8ths of the length indicated by Ln. It is the default mode.
ML     Stand for Music Legato. Note duration is full length of that indicated by Ln.
MS     Stand for Music Staccato. Note duration is 3/4ths of the length indicated by Ln.
Pn     Causes a silence (pause) for the length of note indicated (same as Ln). 
Tn     Sets the number of "L4"s per minute (tempo). Valid values are from 32 to 255. The default value is T120. 
.      When placed after a note, it causes the duration of the note to be 3/2 of the set duration.
       This is how to get "dotted" notes. "L4 C#." would play C sharp as a dotted quarter note.
       It can be used for a pause as well.

Class Terminal

Class Resource

Standard

Collection module

Importing

import "collection" for Stack, Mapper

Class Stack

Stack is a kind of LIFO data structure.

Class Mapper

Coroutine module

Importing

import "coroutine" for Coroutine

Class Coroutine

Coroutine can suspend their execution and allows re-entry at multiple entry points. This Coroutine dispatcher accepts and manages Wren Fiber and updates them at a specific time point, just acts similar to the Unity3D’s.

Datetime module

Importing

import "datetime" for DateTime

Class DateTime

Image module

Importing

import "image" for Image

Class Image

IO module

Importing

import "io" for Path, File, FileInfo, DirectoryInfo

Class Path

Class File

Class FileInfo

Class DirectoryInfo

JSON module

Importing

import "json" for Json

Class Json

Keycode module

Importing

import "keycode" for KeyCode

Class KeyCode

This class contains constants for mouse, gamepad and keyboard keys, the names quite tell what they are.

See “${app}/shell/content/keycode.wren” for more.

OS module

Importing

import "os" for Os

Class Os

Random module

Importing

import "random" for Random

Class Random

See Random for details.

Web module

Importing

import "web" for Web

Class Web

Common

Common module

Importing

import "common" for Direction, Component, Group, Vec2, Vec3, Vec4, Rect, Rot, Color, Handle

Class Direction

Class Component

Class Group

Class Vec2

Class Vec3

Class Vec4

Class Rect

Class Rot

Class Color

Class Handle

Elements

Physics module

Importing

import "physics" for WorldParam, World, Shape, Fixture, Body, JointParam, Joint

Class WorldParam

Use the following constants to get/set properties with Handle.get/Handle.set of a World.

Class World

Class Shape

Class Fixture

Class Body

Class JointParam

Use the following constants to get/set properties with Handle.get/Handle.set of a Joint.

Class Joint

Particles module

Importing

import "particles" for Particle, ParticleSystem, ParticleGroupParam, ParticleGroup, ParticleEmitter

Class Particle

Class ParticleSystem

Class ParticleGroupParam

Use the following constants to get/set properties with Handle.get/Handle.set of a ParticleGroup.

Class ParticleGroup

Class ParticleEmitter

Electronics module

Importing

import "electronics" for CircuitParam, Circuit, ChipParam, Chip

Class CircuitParam

Blank.

Class Circuit

Blank.

Class ChipParam

Use the following constants to get/set properties with Handle.get/Handle.set of a Chip.

Class Chip

Sensor module

Importing

import "sensor" for Sensor

Class Sensor

Dynamics module

Importing

import "dynamics" for Power, DynamicsParam, Dynamics

Class Power

Blank.

Class DynamicsParam

Use the following constants to get/set properties with Handle.get/Handle.set of a Dynamics.

Class Dynamics

AI module

Importing

import "ai" for Behaviour, AiParam, Ai

Class Behaviour

Class AiParam

Use the following constants to get/set properties with Handle.get/Handle.set of an Ai.

Class Ai

Alchemy module

Importing

import "alchemy" for Nature

Class Nature

Camera, boxes and history

Camera module

Importing

import "camera" for Camera

Class Camera

This class controls the behaviour of the main camera in-scene.

Minimap module

Importing

import "minimap" for Minimap

Class Minimap

This class controls the behaviour of the top-right minimap in-scene.

Toolbox module

Importing

import "toolbox" for Toolbox

Class Toolbox

This class controls the behaviour of the right side toolbox in-scene.

Sandbox module

Importing

import "sandbox" for AskParam, Sandbox

Class AskParam

Class Sandbox

This class controls the behaviour of the main scene itself.

History module

Importing

import "history" for History

Class History

This class controls the behaviour of the history stack in-scene.

GUI

GUI module

Importing

import "gui" for Alignment, PackingStyle, CheckBox, ComboBox, IntegerField, RealField, Tab, Scroll, Block, MessageBoxButtons, DialogResult, Gui

Class Alignment

Class PackingStyle

Class CheckBox

Class ComboBox

Class IntegerField

Class RealField

Class Tab

Class Scroll

Class Block

Class MessageBoxButtons

Class DialogResult

Class Gui

Crapht Box implements an immediate mode for common GUI layouts, which draws and performs immediately when you call the corresponding functions, then return necessary states. It also implements a retained mode for block boxes, dialogs, etc. which returns a Block object, check the values on it for detail states.

Layout module

The “layout” module is a wrapper above the GUI primitives. It offers a data-driven way to organize layouts and behaviours under the immediate mode.

Importing

import "layout" for Container, Panel, Flow, Grid, Layout

Class Container

Class Panel

Class Flow

Class Grid

Class Layout

Localization

Localization module

Importing

import "localization" for Language, Localization

Class Language

Class Localization

Dictionary module

Importing

import "dictionary" for Dictionary

Class Dictionary

This class stores text information with specific ID for different languages.

Utilities

Star module

Importing

import "star" for Star

Class Star

This class stores a number of customizable missions for each disk. The Star class is just a data structure excluding any GUI layout.

Prefab module

Importing

import "prefab" for Prefab

Class Prefab

Application

Application module

Importing

import "application" for Application

Class Application

Program

Program module

Importing

import "program" for Program

Class Program

In-disk

Disk module

This module is experimental.

Importing

import "disk" for Convert, Operate, Load, Storyboard, Stopwatch

Class Convert

Class Operate

Class Load

Class Storyboard

Class Stopwatch

HOME

Part IV. Editors

Crapht Box offers built-in editors to edit entry source code, map, level and element.

Switch to the Workshop tab, then click the explore button to browse the directory of your disk:

Code editor

Switch to the Workshop tab, then click the edit button to edit your main source code:

Notice that you cannot edit readonly disks.

The built-in code editor loads the entry source code of the selected disk. To edit other assets, navigate to the directory of a specific disk on your local storage, then use proper external text or image editors to open it.

Map editor

Switch to the Packs tab, then load the Editor/Map Editor disk. See in-disk help for details.

This editor is for static graphics layers, e.g. background, sky, terrain. In the usual case it saves to the “${disk}/content/map.map” and “${disk}/content/scene.json” file.

Level editor

Switch to the Packs tab, then load the Editor/Level Editor disk. See in-disk help for details.

This editor is for static environments, e.g. goal, credit, wall. In the usual case it saves to the “${disk}/content/scene.json” file.

Element editor

Switch to the Packs tab, then load the Editor/Element Editor disk. See in-disk help for details.

This editor is for placing regular elements. In the usual case it saves to the “${disk}/content/scene.json” file.

HOME

Part V. Sharing

Switch to the Workshop tab on the main screen to use the following operations.

Workshop

You can share your creative disks with the Steam community via Workshop, subscribe to play others’ games and programs, and discuss or comment on any submitted disk.

Submitting

To submit a new disk to Workshop, select it, then click Push.

Use an external text editor to modify the “info.json” meta file before pushing as you need. Don’t forget to close any external editors that are opening the source disk you are going to push or pull.

It’s recommended to pick a proper disk and bundle name, apply a good looking sticker, and write necessary introduction and notes to help others to get better acquainted with your submission before pushing. You can edit submitted information in browser after that, including changing the description, changing the visibility, updating the sticker images and videos, etc.

Notice that Crapht Box only uploads the disk itself, which excludes any persistence files.

You need to agree to the Steam Workshop’s terms of service for submitting.

Subscribing

Use a web browser to explore the Crapht Box Workshop on Steam to make subscriptions:

All subscribed disks are automatically downloaded for mounting.

Unsubscribing

Click Unsubscribe on an already subscribed disk in browser or application to stop following it.

Pushing

When you want to push modifications of a submitted disk, select the disk, then click Push.

Pulling

All subscribed disks are supposed to be updated automatically when Crapht Box boots up, but in case you’d like to check updates manually, just click Pull.

Forking

Click Fork to clone a selected disk.

Archiving

Exporter and importer

Click Export... for exporting.

Click Import... for importing.

Exported disk is archived in standard zip package.

HOME