-
Notifications
You must be signed in to change notification settings - Fork 22
languageConfigFile
NPL language configuration file is used by code block in Paracraft.
It usually contains all functions in the left help panel of code block window.
If it is empty, it defaults to standard NPL code block, otherwise it will use the user-defined file in world directory.

Each code block can specify its own language configuration file, by right click the code button.

See below for how to define your own custom language configuration file in your current world directory. Settings are saved to each code block. We usually code custom language implementations in other code blocks as global functions and then instruct your user to code in a special code block.

The language file must be stored in a *.npl file. The content is a table containing all categories of functions
For example, Hello.npl may look like below
--[[
Title: HelloLanguage
Author(s): LiXizhi
Date: 2018/12/13
Desc:
use the lib:
-------------------------------------------------------
-------------------------------------------------------
]]
local MyLanguage = NPL.export();
local categories = {
{name = "Hello", text = "Hello", colour = "#0078d7", },
{name = "Control", text = "Control", colour = "#d83b01", },
};
local all_cmds = {
-----------------------
{
type = "Hello",
message0 = "Hello %1",
arg0 = {
{
name = "text",
type = "input_value",
shadow = { type = "text", value = L"hello!",},
text = L"hello!",
},
},
category = "Hello",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'Hello(%s)',
ToNPL = function(self)
return string.format('Hello("%s")\n', self:getFieldValue('text'));
end,
examples = {{desc = "say hello ", canRun = true, code = [[
say("Hello!")
wait(1)
say("")
]]}},
},
-----------------------
{
type = "Hello2",
message0 = "Hello2 %1",
arg0 = {
{
name = "text",
type = "input_value",
shadow = { type = "text", value = L"hello!",},
text = L"hello!",
},
},
category = "Control",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'say(%s)',
ToNPL = function(self)
return string.format('say("%s")\n', self:getFieldValue('text'));
end,
examples = {{desc = "say hello ", canRun = true, code = [[
say("Hello!")
wait(1)
say("")
]]}},
},
};
function MyLanguage.GetCategoryButtons()
return categories;
end
function MyLanguage.GetAllCmds()
return all_cmds;
endBasically, the file should export a table containing two functions
-
GetCategoryButtons(): which returns a list of all categories -
GetAllCmds(): which returns a list of all commands (functions)
For more information on what each of the command fields is, please refer to stand NPL code block definition files here
Once you have the correct file loaded for a given code block, it will use that file for all help tips in code block window when the user edits it. See below

You can copy and paste these code to create your own language configuration file.
This is suitable for creating a single file application.
--[[
Title: Painter Language
Author(s): LiXizhi
Date: 2018/12/13
Desc:
use the lib:
-------------------------------------------------------
-------------------------------------------------------
]]
local MyLanguage = NPL.export();
local categories = {
{name = "painter", text = "绘图", colour = "#0078d7", },
{name = "canvas", text = "画板", colour = "#ff0000", },
{name = "Control", text = L"控制", colour="#d83b01", },
{name = "Operators", text = L"运算", colour="#569138", },
{name = "Data", text = L"数据", colour="#459197", },
};
local all_cmds = {
-----------------------
{
type = "setPenSpeed",
message0 = "绘图速度 %1",
arg0 = {
{
name = "speed",
type = "input_value",
shadow = { type = "math_number", value = 2,},
text = 2,
},
},
category = "canvas",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'setPenSpeed(%s)',
ToNPL = function(self)
return string.format('setPenSpeed(%s)\n', self:getFieldValue('speed'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "createCanvas",
message0 = "创建绘图板%1x%2",
arg0 = {
{
name = "width",
type = "input_value",
shadow = { type = "math_number", value = 200,},
text = 200,
},
{
name = "height",
type = "input_value",
shadow = { type = "math_number", value = 200,},
text = 200,
},
},
category = "canvas",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'createCanvas(%s, %s)',
ToNPL = function(self)
return string.format('createCanvas(%s, %s)\n', self:getFieldValue('width'), self:getFieldValue('height'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "jumpTo",
message0 = "跳到%1, %2",
arg0 = {
{
name = "x",
type = "input_value",
shadow = { type = "math_number", value = 0,},
text = 0,
},
{
name = "y",
type = "input_value",
shadow = { type = "math_number", value = 0,},
text = 0,
},
},
category = "painter",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'jumpTo(%s, %s)',
ToNPL = function(self)
return string.format('jumpTo(%s, %s)\n', self:getFieldValue('x'), self:getFieldValue('y'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "drawBlock",
message0 = "画点%1, %2",
arg0 = {
{
name = "x",
type = "input_value",
shadow = { type = "math_number", value = 0,},
text = 0,
},
{
name = "y",
type = "input_value",
shadow = { type = "math_number", value = 0,},
text = 0,
},
},
category = "painter",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'drawBlock(%s, %s)',
ToNPL = function(self)
return string.format('drawBlock(%s, %s)\n', self:getFieldValue('x'), self:getFieldValue('y'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "resetPen",
message0 = "重置画笔",
arg0 = {
},
category = "canvas",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'resetPen()',
ToNPL = function(self)
return string.format('resetPen()\n');
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "drawLine",
message0 = "%1 %2格",
arg0 = {
{
name = "style",
type = "field_dropdown",
options = {
{ "向前画", "forward" },
{ "向后画", "backward" },
},
},
{
name = "value",
type = "input_value",
shadow = { type = "math_number", value = 5,},
text = 5,
},
},
category = "painter",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'drawLine("%s", %s)',
ToNPL = function(self)
return string.format('drawLine("%s", %s)\n', self:getFieldValue('style'), self:getFieldValue('value'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "turnPen",
message0 = "%1 %2度",
arg0 = {
{
name = "style",
type = "field_dropdown",
options = {
{ "左转", "left" },
{ "右转", "right" },
},
},
{
name = "value",
type = "input_value",
shadow = { type = "math_number", value = 90,},
text = 90,
},
},
category = "painter",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'turnPen("%s", %s)',
ToNPL = function(self)
return string.format('turnPen("%s", %s)\n', self:getFieldValue('style'), self:getFieldValue('value'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "turnPenTo",
message0 = "旋转到 %1",
arg0 = {
{
name = "value",
type = "input_value",
shadow = { type = "math_number", value = 90,},
text = 90,
},
},
category = "painter",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'turnPenTo(%s)',
ToNPL = function(self)
return string.format('turnPenTo(%s)\n', self:getFieldValue('value'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "setPenColor",
message0 = "画笔颜色 %1",
arg0 = {
{
name = "value",
type = "field_dropdown",
options = {
{ "红", "0xff0000" },
{ "绿", "0x00ff00" },
{ "兰", "0x0000ff" },
{ "黑", "0x000000" },
{ "黄", "0xffff00" },
{ "紫", "0xff00ff" },
{ "随机", "math.random(0, 0xffffff)" },
},
},
},
category = "painter",
helpUrl = "",
canRun = true,
previousStatement = true,
nextStatement = true,
func_description = 'setPenColor(%s)',
ToNPL = function(self)
return string.format('setPenColor(%s)\n', self:getFieldValue('value'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-----------------------
{
type = "repeat",
message0 = L"重复%1次",
message1 = L"%1",
arg0 = {
{
name = "times",
type = "input_value",
shadow = { type = "math_number", value = 4,},
text = 4,
},
},
arg1 = {
{
name = "input",
type = "input_statement",
},
},
category = "painter",
helpUrl = "",
canRun = false,
previousStatement = true,
nextStatement = true,
func_description = 'for i=1, %d do\\n%send',
ToNPL = function(self)
return string.format('for i=1, %d do\n %s\nend\n', self:getFieldValue('times'), self:getFieldAsString('input'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
-------------------
--------------------
-- Operators
{
type = "math_op",
message0 = L"%1 %2 %3",
arg0 = {
{
name = "left",
type = "input_value",
shadow = { type = "math_number", },
},
{
name = "op",
type = "field_dropdown",
options = {
{ "+", "+" },{ "-", "-" },{ "*", "*" },{ "/", "/" },
},
},
{
name = "right",
type = "input_value",
shadow = { type = "math_number", },
},
},
output = {type = "field_number",},
category = "Operators",
helpUrl = "",
canRun = false,
func_description = '((%s) %s (%s))',
ToNPL = function(self)
return string.format('(%s) %s (%s)', self:getFieldAsString('left'), self:getFieldAsString('op'), self:getFieldAsString('right'));
end,
examples = {{desc = L"数字的加减乘除", canRun = true, code = [[
say("1+1=?")
wait(1)
say(1+1)
]]}},
},
{
type = "math_op_compare_number",
message0 = L"%1 %2 %3",
arg0 = {
{
name = "left",
type = "input_value",
shadow = { type = "math_number", },
},
{
name = "op",
type = "field_dropdown",
options = {
{ ">", ">" },{ "<", "<" },{ ">=", ">=" },{ "<=", "<=" },{ "==", "==" },{ "!=", "!=" },
},
},
{
name = "right",
type = "input_value",
shadow = { type = "math_number", },
},
},
output = {type = "field_number",},
category = "Operators",
helpUrl = "",
canRun = false,
func_description = '((%s) %s (%s))',
ToNPL = function(self)
return string.format('(%s) %s (%s)', self:getFieldAsString('left'), self:getFieldAsString('op'), self:getFieldAsString('right'));
end,
examples = {{desc = "", canRun = true, code = [[
if(3>1) then
say("3>1 == true")
end
]]}},
},
{
type = "math_op_compare",
message0 = L"%1 %2 %3",
arg0 = {
{
name = "left",
type = "input_value",
shadow = { type = "text", value = "",},
},
{
name = "op",
type = "field_dropdown",
options = {
{ "==", "==" },{ "!=", "!=" },
},
},
{
name = "right",
type = "input_value",
shadow = { type = "math_number",},
},
},
output = {type = "field_number",},
category = "Operators",
helpUrl = "",
canRun = false,
func_description = '((%s) %s (%s))',
ToNPL = function(self)
return string.format('(%s) %s (%s)', self:getFieldAsString('left'), self:getFieldAsString('op'), self:getFieldAsString('right'));
end,
examples = {{desc = "", canRun = true, code = [[
if("1" == "1") then
say("equal")
end
]]}},
},
{
type = "math_oneop",
message0 = L"%1%2",
arg0 = {
{
name = "name",
type = "field_dropdown",
options = {
{ L"开根号", "sqrt" },
{ "sin", "sin"},
{ "cos", "cos"},
{ L"绝对值", "abs"},
{ "asin", "asin"},
{ "acos", "acos"},
{ L"向上取整", "ceil"},
{ L"向下取整", "floor"},
{ "tab", "tan"},
{ "atan", "atan"},
{ "sin", "exp"},
{ "log10", "log10"},
{ "exp", "exp"},
},
},
{
name = "left",
type = "input_value",
shadow = { type = "math_number", value = 9,},
text = 9,
},
},
output = {type = "field_number",},
category = "Operators",
helpUrl = "",
canRun = false,
func_description = 'math.%s(%s)',
ToNPL = function(self)
return string.format('math.%s(%s)', self:getFieldAsString('name'), self:getFieldAsString('left'));
end,
examples = {{desc = "", canRun = true, code = [[
say("math.sqrt(9)=="..math.sqrt(9), 1)
say("math.cos(1)=="..math.cos(1), 1)
say("math.abs(-1)=="..math.abs(1), 1)
]]}},
},
-- Data
{
type = "getLocalVariable",
message0 = L"变量%1",
arg0 = {
{
name = "var",
type = "field_input",
text = "score",
},
},
output = {type = "null",},
category = "Data",
helpUrl = "",
canRun = false,
func_description = '%s',
ToNPL = function(self)
return self:getFieldAsString('var');
end,
examples = {{desc = "", canRun = true, code = [[
local key = "value"
say(key, 1)
]]}},
},
{
type = "assign",
message0 = L"%1赋值为%2",
arg0 = {
{
name = "left",
type = "input_value",
shadow = { type = "getLocalVariable", value = "score",},
text = "score",
},
{
name = "right",
type = "input_value",
shadow = { type = "math_number", value = 1,},
text = 1,
},
},
category = "Data",
helpUrl = "",
canRun = false,
previousStatement = true,
nextStatement = true,
func_description = '%s = %s',
ToNPL = function(self)
return 'key = "value"\n';
end,
examples = {{desc = "", canRun = true, code = [[
text = "hello"
say(text, 1)
]]}},
},
{
type = "getNumber",
message0 = L"%1",
arg0 = {
{
name = "left",
type = "field_number",
text = "0",
},
},
output = {type = "field_number",},
category = "Data",
helpUrl = "",
canRun = false,
func_description = '%s',
ToNPL = function(self)
return string.format('%s', self:getFieldAsString('left'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
{
type = "newFunction",
message0 = L"新函数(%1)",
message1 = L"%1",
arg0 = {
{
name = "param",
type = "field_input",
text = "param",
},
},
arg1 = {
{
name = "input",
type = "input_statement",
text = "",
},
},
output = {type = "field_number",},
category = "Data",
helpUrl = "",
canRun = false,
func_description = 'function(%s)\\n%send',
ToNPL = function(self)
return string.format('function(%s)\n %s\nend\n', self:getFieldAsString('param'), self:getFieldAsString('input'));
end,
examples = {{desc = "", canRun = true, code = [[
local thinkText = function(text)
say(text.."...")
end
thinkText("Let me think");
]]}},
},
{
type = "callFunction",
message0 = L"调用函数%1(%2)",
arg0 = {
{
name = "name",
type = "field_input",
text = "log",
},
{
name = "param",
type = "input_value",
shadow = { type = "text", value = "param",},
text = "param",
},
},
previousStatement = true,
nextStatement = true,
category = "Data",
helpUrl = "",
canRun = false,
func_description = '%s(%s)',
ToNPL = function(self)
return string.format('%s("%s")\n', self:getFieldAsString('name'), self:getFieldAsString('param'));
end,
examples = {{desc = "", canRun = true, code = [[
local thinkText = function(text)
say(text.."...")
end
thinkText("Let me think");
]]}},
},
{
type = "expression_compare",
message0 = L"%1 %2 %3",
arg0 = {
{
name = "left",
-- TODO: nested shadow blocks are not supported
-- type = "input_value",
-- shadow = { type = "getLocalVariable", value = "status",},
type = "field_input",
text = "status",
},
{
name = "op",
type = "field_dropdown",
options = {
{ "==", "==" },{ "!=", "!=" },
},
},
{
name = "right",
-- TODO: nested shadow blocks are not supported
-- type = "input_value",
-- shadow = { type = "text", value = "start",},
type = "field_input",
text = "\"start\"",
},
},
hide_in_toolbox = true,
output = {type = "field_number",},
category = "Control",
helpUrl = "",
canRun = false,
func_description = '((%s) %s (%s))',
ToNPL = function(self)
return string.format('(%s) %s (%s)', self:getFieldAsString('left'), self:getFieldAsString('op'), self:getFieldAsString('right'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
{
type = "repeat_count",
message0 = L"循环:变量%1从%2到%3",
message1 = L"%1",
arg0 = {
{
name = "var",
type = "field_variable",
variable = "i",
variableTypes = {""},
text = "key",
},
{
name = "start_index",
type = "input_value",
shadow = { type = "math_number", value = 1,},
text = 1,
},
{
name = "end_index",
type = "input_value",
shadow = { type = "math_number", value = 10,},
text = 10,
},
},
arg1 = {
{
name = "input",
type = "input_statement",
},
},
category = "Control",
helpUrl = "",
canRun = false,
previousStatement = true,
nextStatement = true,
func_description = 'for %s=%d, %d do\\n%send',
ToNPL = function(self)
return string.format('for %s=%d, %d do\n %s\nend\n', self:getFieldValue('var'),self:getFieldValue('start_index'),self:getFieldValue('end_index'), self:getFieldAsString('input'));
end,
examples = {{desc = "", canRun = true, code = [[
for i=1, 10, 1 do
moveForward(i)
end
]]}},
},
{
type = "control_if",
message0 = L"如果%1那么",
message1 = L"%1",
arg0 = {
{
name = "expression",
type = "input_value",
},
},
arg1 = {
{
name = "input_true",
type = "input_statement",
text = "",
},
},
category = "Control",
helpUrl = "",
canRun = false,
previousStatement = true,
nextStatement = true,
func_description = 'if(%s) then\\n%send',
ToNPL = function(self)
return string.format('if(%s) then\n %s\nend\n', self:getFieldAsString('expression'), self:getFieldAsString('input_true'));
end,
examples = {{desc = "", canRun = true, code = [[
]]}},
},
};
function MyLanguage.GetCategoryButtons()
return categories;
end
function MyLanguage.GetAllCmds()
return all_cmds;
end