New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formspec replacement #6527

Open
rubenwardy opened this Issue Oct 13, 2017 · 75 comments

Comments

Projects
None yet
@rubenwardy
Member

rubenwardy commented Oct 13, 2017

MuSCo (must have, should have, could have)

Actual GUI libraries / logic

Must have

  • Good layouting
    • Consistent co-ordinates and scale.
    • Adapting containers for varying window size (table, linear, stack)
  • OOP design in C++ to allow extending, and decouple elements.

Should have

  • Should use an existing solution - avoid reinventing the wheel. It's fine to define our own Lua API for it, however.
  • Theming
    • Ability to change borders/backgrounds/etc
    • CSS like syntax?

Server API

Must have

  • Sane format
    • OOP style, which is then converted to JSON?

Should have

  • Auto-validation
    • reject invalid submissions

Could have

  • Server-side formspec to new API converter

CSM API

Could have

  • Define custom elements, with draw(). Draw is only called when required, which may be every draw step.

Other notes

@sapier
As discussion on minetest-dev showed up we first need to define what a possible formspec replacement has to do, a suggestion:

Completely specified
Modifyable (change existing formspecs)
Current formspecs have to be convertable to it
Errors have to be detectable (no typos, no logical errors)
Container support (tabs/ribbons/whatever you wanna add here)
Existing format is preferred
Support for optional parameters (not interpreted by GUI, but explicitly defined)
Pixel based AND relative positioning of elements
API versioning 
How UI elements are drawn
How UI is defined
How user input is linked to UI definition

See sfan5's post for an example API

I'm willing to work on this if we can have a consensus on how it should work.

Related: #1399, #5810 )

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Oct 13, 2017

Member

Using HTML/CSS, QT, or GTK would probably be too much for a game.

I suggest something like tgui or SFGUI as a backing library. We could reflect their API in Lua, and serialize and send to the client using JSON.

Member

rubenwardy commented Oct 13, 2017

Using HTML/CSS, QT, or GTK would probably be too much for a game.

I suggest something like tgui or SFGUI as a backing library. We could reflect their API in Lua, and serialize and send to the client using JSON.

@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

i agree with that, those aren't exactly lightweight GUI's
however wxwidgets might be a possibility as it is automatically cross-platform.
but idk how much it is supported

Contributor

ThomasMonroe314 commented Oct 13, 2017

i agree with that, those aren't exactly lightweight GUI's
however wxwidgets might be a possibility as it is automatically cross-platform.
but idk how much it is supported

@nerzhul

This comment has been minimized.

Show comment
Hide comment
@nerzhul

nerzhul Oct 13, 2017

Member

i have a partially working XML format in a branch: https://gitlab.com/project-demeter/core/tree/form_xml
The only missing patch is catching events from XML to core, other parts are managed and just need more and more components, it's XML with HTML-like attributes)
It's using libxml2 which is portable and very performant, used by many softwares

Member

nerzhul commented Oct 13, 2017

i have a partially working XML format in a branch: https://gitlab.com/project-demeter/core/tree/form_xml
The only missing patch is catching events from XML to core, other parts are managed and just need more and more components, it's XML with HTML-like attributes)
It's using libxml2 which is portable and very performant, used by many softwares

@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

what about this: http://www.clutter-project.org/
it seems to be very lightweight and runs well on Android

Contributor

ThomasMonroe314 commented Oct 13, 2017

what about this: http://www.clutter-project.org/
it seems to be very lightweight and runs well on Android

@weqqr

This comment has been minimized.

Show comment
Hide comment
@weqqr

weqqr Oct 13, 2017

Contributor

nuklear looks good, supports theming and it's very lightweight compared to Qt/GTK.

Contributor

weqqr commented Oct 13, 2017

nuklear looks good, supports theming and it's very lightweight compared to Qt/GTK.

@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

@weqqr that looks like exactly what openarena uses, and its GUIs look pretty nice
but does it support android?

Contributor

ThomasMonroe314 commented Oct 13, 2017

@weqqr that looks like exactly what openarena uses, and its GUIs look pretty nice
but does it support android?

@weqqr

This comment has been minimized.

Show comment
Hide comment
@weqqr

weqqr Oct 13, 2017

Contributor

@ThomasMonroe314 nuklear itself only receives user input and generates a list of shapes to draw, so in theory it can run on everything from a supercomputer to an electric kettle. You need to write a frontend (like this) to make it work with Irrlicht though.

Contributor

weqqr commented Oct 13, 2017

@ThomasMonroe314 nuklear itself only receives user input and generates a list of shapes to draw, so in theory it can run on everything from a supercomputer to an electric kettle. You need to write a frontend (like this) to make it work with Irrlicht though.

@sfan5

This comment has been minimized.

Show comment
Hide comment
@sfan5

sfan5 Oct 13, 2017

Member

Wanting a CSS themeable, extendable (by CSM) GUI using a completely new GUI toolkit is aiming way too high IMO.
It pretty much guarantees that it won't ever be fully implemented and we'll be stuck on formspecs for a longer time.

Also having something like minetest.register_window removes quite a lot of dynamicness from the gui system.

(The rest of this post is just throwing my ideas in here.)

Instead I would fix "just" these issues:

  • coordinate system
  • proper layouting, meaning: containers with children
  • use nested tables to represent these (not exposed to Lua, should have object-oriented API)
  • proper event system: wide variety of events for each element, all optional

This retains the following from formspecs:

  • Toolkit-independent
  • dynamic ("made up on the spot", no pre-registered layouts)
  • events are produced in certain conditions, these can be individually listened for
  • uses Irrlicht GUI (probably)

There is likely no existing solution for this, but that's fine.
Since this is quite hard to put into words, some example code:

local window_name = minetest.get_current_modname() .. ":respawn"
local pad = 50

local function show_respawn_dialog(playername)
	local root = gui.Window:new(window_name, 100 + 2*pad, 200 + 2*pad)
	root:listenForEvent("close")
	
	local stack = gui.Stack:new()
	stack.padding = {pad, pad, pad, pad}
	root:add(stack)

	local button1 = gui.Button:new("Respawn", 100, 100)
	button1.id = "b_respawn" -- must be unique
	button1:listenForEvent("click")
	stack:add(button1)

	if creative.is_enabled_for(playername) then
		local button2 = gui.Button:new("Respawn at same position", 100, 100)
		button2.id = "b_respawn2"
		button2:listenForEvent("click")
		stack:add(button2)
	end
	
	minetest.show_gui_dialog(playername, root)
end

local function respawn_normally(player, state)
	assert(state["b_respawn"].pressed == true) -- just an example for state
end

minetest.register_gui_event(window_name, "b_respawn/click", respawn_normally)
minetest.register_gui_event(window_name, "close", respawn_normally)

minetest.register_gui_event(window_name, "b_respawn2/click", function(player, state)
	-- do something else
	return true
end)

internally/when sent via network it would look like this (no modder would ever see this though):

{
	"type": "window",
	"id": "testmod:respawn",
	"events": {"exit": true},
	"children": [
		{"type": "stack", "children": [
			{"type": "button", "id": "b_respawn", "events": {"click": true}},
			{"type": "button", "id": "b_respawn2", "events": {"click": true}}
		]}
	]
}

To achieve backward compatibility you would then need to:

  • Convert the formspec string to tables (duh)
  • Translate the stupid coordinate system to the new one during conversion
  • Give each element a default set of listened events (e.g. buttons always respond to clicks)
  • Convert the new events to the old system and call minetest.register_on_player_receive_fields callbacks
Member

sfan5 commented Oct 13, 2017

Wanting a CSS themeable, extendable (by CSM) GUI using a completely new GUI toolkit is aiming way too high IMO.
It pretty much guarantees that it won't ever be fully implemented and we'll be stuck on formspecs for a longer time.

Also having something like minetest.register_window removes quite a lot of dynamicness from the gui system.

(The rest of this post is just throwing my ideas in here.)

Instead I would fix "just" these issues:

  • coordinate system
  • proper layouting, meaning: containers with children
  • use nested tables to represent these (not exposed to Lua, should have object-oriented API)
  • proper event system: wide variety of events for each element, all optional

This retains the following from formspecs:

  • Toolkit-independent
  • dynamic ("made up on the spot", no pre-registered layouts)
  • events are produced in certain conditions, these can be individually listened for
  • uses Irrlicht GUI (probably)

There is likely no existing solution for this, but that's fine.
Since this is quite hard to put into words, some example code:

local window_name = minetest.get_current_modname() .. ":respawn"
local pad = 50

local function show_respawn_dialog(playername)
	local root = gui.Window:new(window_name, 100 + 2*pad, 200 + 2*pad)
	root:listenForEvent("close")
	
	local stack = gui.Stack:new()
	stack.padding = {pad, pad, pad, pad}
	root:add(stack)

	local button1 = gui.Button:new("Respawn", 100, 100)
	button1.id = "b_respawn" -- must be unique
	button1:listenForEvent("click")
	stack:add(button1)

	if creative.is_enabled_for(playername) then
		local button2 = gui.Button:new("Respawn at same position", 100, 100)
		button2.id = "b_respawn2"
		button2:listenForEvent("click")
		stack:add(button2)
	end
	
	minetest.show_gui_dialog(playername, root)
end

local function respawn_normally(player, state)
	assert(state["b_respawn"].pressed == true) -- just an example for state
end

minetest.register_gui_event(window_name, "b_respawn/click", respawn_normally)
minetest.register_gui_event(window_name, "close", respawn_normally)

minetest.register_gui_event(window_name, "b_respawn2/click", function(player, state)
	-- do something else
	return true
end)

internally/when sent via network it would look like this (no modder would ever see this though):

{
	"type": "window",
	"id": "testmod:respawn",
	"events": {"exit": true},
	"children": [
		{"type": "stack", "children": [
			{"type": "button", "id": "b_respawn", "events": {"click": true}},
			{"type": "button", "id": "b_respawn2", "events": {"click": true}}
		]}
	]
}

To achieve backward compatibility you would then need to:

  • Convert the formspec string to tables (duh)
  • Translate the stupid coordinate system to the new one during conversion
  • Give each element a default set of listened events (e.g. buttons always respond to clicks)
  • Convert the new events to the old system and call minetest.register_on_player_receive_fields callbacks
@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

nuklear has lua bindings, a thing that i haven't seen anywhere else, and something that is straightforward, simple to use and should be simple to implement

Contributor

ThomasMonroe314 commented Oct 13, 2017

nuklear has lua bindings, a thing that i haven't seen anywhere else, and something that is straightforward, simple to use and should be simple to implement

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Oct 13, 2017

Member

nuklear has lua bindings, a thing that i haven't seen anywhere else, and something that is straightforward, simple to use and should be simple to implement

Doesn't help when we need SSM to be able to make windows/dialogs


@sfan5, all of that sounds good to me. I actually prefer it to mine, so updated first post

It's fine to leave stuff out for an initial implementation, but it needs to be thought about to allow future additions. Yours does however, you could add theming without breaking

Member

rubenwardy commented Oct 13, 2017

nuklear has lua bindings, a thing that i haven't seen anywhere else, and something that is straightforward, simple to use and should be simple to implement

Doesn't help when we need SSM to be able to make windows/dialogs


@sfan5, all of that sounds good to me. I actually prefer it to mine, so updated first post

It's fine to leave stuff out for an initial implementation, but it needs to be thought about to allow future additions. Yours does however, you could add theming without breaking

@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

pardon my ignorance, but what is SSM?

Contributor

ThomasMonroe314 commented Oct 13, 2017

pardon my ignorance, but what is SSM?

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Oct 13, 2017

Member

pardon my ignorance, but what is SSM?

Sorry, server-side mods or server-side modding.

Member

rubenwardy commented Oct 13, 2017

pardon my ignorance, but what is SSM?

Sorry, server-side mods or server-side modding.

@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

ah ok thanks, but why is that a problem? cant it be used for that?

Contributor

ThomasMonroe314 commented Oct 13, 2017

ah ok thanks, but why is that a problem? cant it be used for that?

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Oct 13, 2017

Member

ah ok thanks, but why is that a problem? cant it be used for that?

Their API will likely be directly manipulating elements, where as we need to send commands over the network to the client.


I suggest keeping both the new API and formspecs in parallel whilst developing, then making a server-side formspec to new GUI converter when stable enough

Member

rubenwardy commented Oct 13, 2017

ah ok thanks, but why is that a problem? cant it be used for that?

Their API will likely be directly manipulating elements, where as we need to send commands over the network to the client.


I suggest keeping both the new API and formspecs in parallel whilst developing, then making a server-side formspec to new GUI converter when stable enough

@ThomasMonroe314

This comment has been minimized.

Show comment
Hide comment
@ThomasMonroe314

ThomasMonroe314 Oct 13, 2017

Contributor

hmm true, but as weqqr pointed out, we would need to write a frontend, so couldnt we add some that functionality to the front-end?

Contributor

ThomasMonroe314 commented Oct 13, 2017

hmm true, but as weqqr pointed out, we would need to write a frontend, so couldnt we add some that functionality to the front-end?

@weqqr

This comment has been minimized.

Show comment
Hide comment
@weqqr

weqqr Oct 13, 2017

Contributor

I really like sfan5's idea, but not the API, so here's my concept.

local function say_hello(window_state, player)
	print("Hello, " .. window_state.name.text)
end

local function show_window(player_name)
	local window = minetest.window("mymod:window", function(w) w
		:size(200, 200)
		:field("name", function(f) f
			:default_text("someone")
			:position(50, 50)
		end)
		:container("my_container", function(c) c
			:position(60, 60)
			:padding(10, 10, 10, 10)
			:button("hello", function(b) b
				:text("Say hello!")
				:position(50, 50)
				:dimensions(100, 100)
				-- Callbacks can be set in-place
				:on_press(say_hello)
			end)
		end)
	end)

	minetest.show_window(player_name, window)
end

-- Complex callbacks can be handled outside of the window definition
minetest.register_on_gui_event("mymod:window/my_container/hello", "press", function(window_state, player)
	print("Your name is " .. player:get_player_name())
end)

minetest.register_on_gui_event("mymod:window", "close", function(window_state, player)
	print("Window closed")
end)
Contributor

weqqr commented Oct 13, 2017

I really like sfan5's idea, but not the API, so here's my concept.

local function say_hello(window_state, player)
	print("Hello, " .. window_state.name.text)
end

local function show_window(player_name)
	local window = minetest.window("mymod:window", function(w) w
		:size(200, 200)
		:field("name", function(f) f
			:default_text("someone")
			:position(50, 50)
		end)
		:container("my_container", function(c) c
			:position(60, 60)
			:padding(10, 10, 10, 10)
			:button("hello", function(b) b
				:text("Say hello!")
				:position(50, 50)
				:dimensions(100, 100)
				-- Callbacks can be set in-place
				:on_press(say_hello)
			end)
		end)
	end)

	minetest.show_window(player_name, window)
end

-- Complex callbacks can be handled outside of the window definition
minetest.register_on_gui_event("mymod:window/my_container/hello", "press", function(window_state, player)
	print("Your name is " .. player:get_player_name())
end)

minetest.register_on_gui_event("mymod:window", "close", function(window_state, player)
	print("Window closed")
end)
@paramat

This comment has been minimized.

Show comment
Hide comment
@paramat

paramat Oct 13, 2017

Member

I feel 'themeable' is low priority and should not count against a good, simple, practical solution.
MTs neutral grey boxes are visually fine and no problem.

Member

paramat commented Oct 13, 2017

I feel 'themeable' is low priority and should not count against a good, simple, practical solution.
MTs neutral grey boxes are visually fine and no problem.

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Oct 13, 2017

Member

MTs neutral grey boxes are visually fine and no problem.

MT's current GUI is ugly. The new GUI can be tweaked to look better without breaking things, and margins will be better as you would be able to specify exact margins. Theming is relatively low priority, and should not be in a first implementation - but it should be considered to make sure any first implementation could support it in the future. I think any good consistent and DRY solution would be able to, anyway

Member

rubenwardy commented Oct 13, 2017

MTs neutral grey boxes are visually fine and no problem.

MT's current GUI is ugly. The new GUI can be tweaked to look better without breaking things, and margins will be better as you would be able to specify exact margins. Theming is relatively low priority, and should not be in a first implementation - but it should be considered to make sure any first implementation could support it in the future. I think any good consistent and DRY solution would be able to, anyway

@paramat

This comment has been minimized.

Show comment
Hide comment
@paramat

paramat Oct 13, 2017

Member

Hmm my statement there was too strong, even i like to have colourable boxes instead of only grey / black. Being able to design the background graphic is a good feature to have.

Member

paramat commented Oct 13, 2017

Hmm my statement there was too strong, even i like to have colourable boxes instead of only grey / black. Being able to design the background graphic is a good feature to have.

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Oct 13, 2017

Contributor

@weqqr That jQuery-like syntax is awful IMO.
@sfan5 What’s the problem of needing to register windows before showing them? That would be handy IMO, as long as the registration may be done at any time and not only on server load: you could setup the whole huge multi-tab window layout, all the callbacks, etc., and only set some content right before showing it.
Also, that way nodes could store window name in the meta instead of its full specification, thus easing updates.

Contributor

numberZero commented Oct 13, 2017

@weqqr That jQuery-like syntax is awful IMO.
@sfan5 What’s the problem of needing to register windows before showing them? That would be handy IMO, as long as the registration may be done at any time and not only on server load: you could setup the whole huge multi-tab window layout, all the callbacks, etc., and only set some content right before showing it.
Also, that way nodes could store window name in the meta instead of its full specification, thus easing updates.

@raymoo

This comment has been minimized.

Show comment
Hide comment
@raymoo

raymoo Oct 14, 2017

Contributor

My thoughts (Some of these have been mentioned already in the thread):

  • There should only be a CSM GUI API (maybe with a compatibility layer for old-style formspecs). This would need to wait for servers being able to send client mods.
  • The API should have some way of drawing every frame so that mods can animate GUI components, making it possible for mods to create new interactive GUI elements, like selection wheels, without hardcoding engine code to handle them.
  • Layout should be automatic, i.e. you don't need to manually specify coordinates for everything if you don't want to.
  • The same API could be used for client-mod provided HUD elements.
  • (Optional) I like the idea of imgui's API. I've never actually used it though so it might not be as good as I imagine.
Contributor

raymoo commented Oct 14, 2017

My thoughts (Some of these have been mentioned already in the thread):

  • There should only be a CSM GUI API (maybe with a compatibility layer for old-style formspecs). This would need to wait for servers being able to send client mods.
  • The API should have some way of drawing every frame so that mods can animate GUI components, making it possible for mods to create new interactive GUI elements, like selection wheels, without hardcoding engine code to handle them.
  • Layout should be automatic, i.e. you don't need to manually specify coordinates for everything if you don't want to.
  • The same API could be used for client-mod provided HUD elements.
  • (Optional) I like the idea of imgui's API. I've never actually used it though so it might not be as good as I imagine.
@tobyplowy

This comment has been minimized.

Show comment
Hide comment
@tobyplowy

tobyplowy Oct 14, 2017

Contributor

MTs neutral grey boxes are visually fine and no problem.

Now your really pissing me off

Hmm my statement there was too strong,

Ooook then nevermind

But all jokes aside those "neutral grey boxes" look awful and they have to go they look unprofessional, they are ugly, they make minetest look like test software (the word test in minetest doesn't help with that) and they are NOT CUSTOMIZABLE WITH TEXTUREPACKS!!!!!!

Contributor

tobyplowy commented Oct 14, 2017

MTs neutral grey boxes are visually fine and no problem.

Now your really pissing me off

Hmm my statement there was too strong,

Ooook then nevermind

But all jokes aside those "neutral grey boxes" look awful and they have to go they look unprofessional, they are ugly, they make minetest look like test software (the word test in minetest doesn't help with that) and they are NOT CUSTOMIZABLE WITH TEXTUREPACKS!!!!!!

@dsohler

This comment has been minimized.

Show comment
Hide comment
@dsohler

dsohler Oct 20, 2017

Using HTML/CSS, QT, or GTK would probably be too much for a game.

I'm in with QT and GTK but imagine how awesome it would be having HTML-based dialogs and menus and stuff. Of course not full HTML5 and CSS3, but a base set of HTML syntax (img, input, section, div, and some more) plus some Minetest-specific additions (for the inventories for example) would be friggin awesome!

dsohler commented Oct 20, 2017

Using HTML/CSS, QT, or GTK would probably be too much for a game.

I'm in with QT and GTK but imagine how awesome it would be having HTML-based dialogs and menus and stuff. Of course not full HTML5 and CSS3, but a base set of HTML syntax (img, input, section, div, and some more) plus some Minetest-specific additions (for the inventories for example) would be friggin awesome!

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Oct 20, 2017

Contributor

@dsohler IMO some XML-based language would be way better: it is easier to parse and more flexible. E.g. mods could be able to define their own elements (using XML namespaces... oh yeah, it uses the same namespace:element naming convention as MT does...)

Contributor

numberZero commented Oct 20, 2017

@dsohler IMO some XML-based language would be way better: it is easier to parse and more flexible. E.g. mods could be able to define their own elements (using XML namespaces... oh yeah, it uses the same namespace:element naming convention as MT does...)

@dsohler

This comment has been minimized.

Show comment
Hide comment
@dsohler

dsohler Oct 20, 2017

@numberZero Using pure XML and then parse seems nice even if you limit the possibilities and make it harder to do something. If a dialog is nothing more than a viewport for a simple HTML parser to output the parsed HTML you basically could create websites within dialogs … which might not be uber useful within a game like Minetest but why limit modders? 😄

Modders could even introduce own tags to the markup since HTML5 absolutely allows that and makes it very easy to do so.

dsohler commented Oct 20, 2017

@numberZero Using pure XML and then parse seems nice even if you limit the possibilities and make it harder to do something. If a dialog is nothing more than a viewport for a simple HTML parser to output the parsed HTML you basically could create websites within dialogs … which might not be uber useful within a game like Minetest but why limit modders? 😄

Modders could even introduce own tags to the markup since HTML5 absolutely allows that and makes it very easy to do so.

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Oct 20, 2017

Contributor

@dsohler What do you consider that good in HTML? It’s old, bloated and messy; it is hard to lay out correctly, or even to lay out at all (remember how buggy all the web browsers were...). Also it doesn’t suit the GUI needs well.

Contributor

numberZero commented Oct 20, 2017

@dsohler What do you consider that good in HTML? It’s old, bloated and messy; it is hard to lay out correctly, or even to lay out at all (remember how buggy all the web browsers were...). Also it doesn’t suit the GUI needs well.

@dsohler

This comment has been minimized.

Show comment
Hide comment
@dsohler

dsohler Oct 20, 2017

@numberZero I’m not talking about www-centric HTML 4 and earlier because yes, that sucks. I’m talking about a narrow subset of HTML5 (that would allow most coders and designers to create dialogs because they already know HTML). And yes: HTML is not a layout language at all. Back then it had design elements and those were overused and stupid bullshit. Fortunately nowadays HTML has nothing to do with that nonsense.

But yes: Instead of a HTML subset we could use XML and use a built-in XSLT file. Using a self-made XSLT processor it would even be possible to completely separate dialog definitions from core and have the API only talk through the XSLT processor. Mods could then implement their own syntax depending on whatever the mod author likes and add a XSLT file and send that to the processor and … 💥 But … oh well … that actually might be a little too much 😄

But dialogs should absolutely be defined using some sort of semantic markup language instead an unnecessary complex and unflexible string that’s passed around.

dsohler commented Oct 20, 2017

@numberZero I’m not talking about www-centric HTML 4 and earlier because yes, that sucks. I’m talking about a narrow subset of HTML5 (that would allow most coders and designers to create dialogs because they already know HTML). And yes: HTML is not a layout language at all. Back then it had design elements and those were overused and stupid bullshit. Fortunately nowadays HTML has nothing to do with that nonsense.

But yes: Instead of a HTML subset we could use XML and use a built-in XSLT file. Using a self-made XSLT processor it would even be possible to completely separate dialog definitions from core and have the API only talk through the XSLT processor. Mods could then implement their own syntax depending on whatever the mod author likes and add a XSLT file and send that to the processor and … 💥 But … oh well … that actually might be a little too much 😄

But dialogs should absolutely be defined using some sort of semantic markup language instead an unnecessary complex and unflexible string that’s passed around.

@SmallJoker

This comment has been minimized.

Show comment
Hide comment
@SmallJoker

SmallJoker Oct 20, 2017

Member

@numberZero @dsohler So you imagine a Lua API to build a (dynamic) XML file which is sent to the players? Having HTML sounds nice but the libraries will be very heavy. Every library suggested here already offers more different elements than our formspecs do.
However, Minetest-special elements would still have to be added, like the inventory list.
nuklear (thanks to @weqqr for mentioning) looks very promising. A single header to include, with simple API functions. Even simpler are those from imgui, where the C++ examples almost look like Lua code. For the latter there's also an Irrlicht binding available, which embeds it perfectly into Irrlicht. But with the side effect of being a quite inactive project.

Member

SmallJoker commented Oct 20, 2017

@numberZero @dsohler So you imagine a Lua API to build a (dynamic) XML file which is sent to the players? Having HTML sounds nice but the libraries will be very heavy. Every library suggested here already offers more different elements than our formspecs do.
However, Minetest-special elements would still have to be added, like the inventory list.
nuklear (thanks to @weqqr for mentioning) looks very promising. A single header to include, with simple API functions. Even simpler are those from imgui, where the C++ examples almost look like Lua code. For the latter there's also an Irrlicht binding available, which embeds it perfectly into Irrlicht. But with the side effect of being a quite inactive project.

@dsohler

This comment has been minimized.

Show comment
Hide comment
@dsohler

dsohler Oct 20, 2017

@SmallJoker Yes. Whatever modern format (HTML5, XML, JSON, etc.) it will be is sent to the clients and parsed there using whatever parser is needed to generate the output. HTML would be awesome in combination with CSS and a proper HTML parser on client-side for maximum flexibility, XML would be nice because mod authors could create an own XSLT file and have the parser interpret whatever syntax the mod author prefers and JSON … well … the overhead is virtually nonexistent here.

dsohler commented Oct 20, 2017

@SmallJoker Yes. Whatever modern format (HTML5, XML, JSON, etc.) it will be is sent to the clients and parsed there using whatever parser is needed to generate the output. HTML would be awesome in combination with CSS and a proper HTML parser on client-side for maximum flexibility, XML would be nice because mod authors could create an own XSLT file and have the parser interpret whatever syntax the mod author prefers and JSON … well … the overhead is virtually nonexistent here.

@nerzhul

This comment has been minimized.

Show comment
Hide comment
@nerzhul

nerzhul Oct 22, 2017

Member

@SmallJoker it's why i propose to use libxml2 or irrlicht XML parser (very low level) and create our own DSL

Member

nerzhul commented Oct 22, 2017

@SmallJoker it's why i propose to use libxml2 or irrlicht XML parser (very low level) and create our own DSL

@bvanrosendale

This comment has been minimized.

Show comment
Hide comment
@bvanrosendale

bvanrosendale Oct 25, 2017

Contributor

I agree with what @raymoo said about layout above

Layout should be automatic, i.e. you don't need to manually specify coordinates for everything if you don't want to.

With the current hard-coded layout, you can't handle different DPIs, different font/font sizes/translations being different length. This is the root cause of #6521 and #4607.

I don't see a way to fix those issues (not those specific cases, but the actual base problem) without using a GUI that can change based on the screen size available.

Contributor

bvanrosendale commented Oct 25, 2017

I agree with what @raymoo said about layout above

Layout should be automatic, i.e. you don't need to manually specify coordinates for everything if you don't want to.

With the current hard-coded layout, you can't handle different DPIs, different font/font sizes/translations being different length. This is the root cause of #6521 and #4607.

I don't see a way to fix those issues (not those specific cases, but the actual base problem) without using a GUI that can change based on the screen size available.

@Wuzzy2

This comment has been minimized.

Show comment
Hide comment
@Wuzzy2

Wuzzy2 Nov 27, 2017

Contributor

Please add the following items (from the modder's perspective):

Must have:

  • Complete and proof-read documentation, including, but not limited to:
    • Available widgets and what they do
    • Syntax
    • What happens if user exists / hits Esc?
    • Coordinates
    • How to parse fields in on_receive_fields (for any given widget)
    • Gotchas (if any)
  • Define which events trigger on_receive_fields and be consistent
  • Fix #4482

Should have:

  • Scrollable automatic-line breaking multi-line text: #3807
  • No gotchas, surprises, weird return values, etc.

Could have:

  • Clickable text (like hyperlinks)
  • Allow to check for supported widgets: #4834

General stuff:

  • I don't care much about the syntax
  • Please don't waste time on overly “clever” API designs, formpec syntaxes or other meta bullshit. That's not important; I just want something that works
  • I'm pretty much OK with the suggestions posted so far
  • I don't care if you use a GUI toolkit or do everything by hand if it works at the end
  • I agree that theming should be considered (not implemented!) as early as possible (otherwise it will be painful to add as an afterthought)
  • I'm not opposed to breaking changes if the result is a serious improvement over our current system. I guess the fucked-up coordinate system alone will already force you to break things anyway
Contributor

Wuzzy2 commented Nov 27, 2017

Please add the following items (from the modder's perspective):

Must have:

  • Complete and proof-read documentation, including, but not limited to:
    • Available widgets and what they do
    • Syntax
    • What happens if user exists / hits Esc?
    • Coordinates
    • How to parse fields in on_receive_fields (for any given widget)
    • Gotchas (if any)
  • Define which events trigger on_receive_fields and be consistent
  • Fix #4482

Should have:

  • Scrollable automatic-line breaking multi-line text: #3807
  • No gotchas, surprises, weird return values, etc.

Could have:

  • Clickable text (like hyperlinks)
  • Allow to check for supported widgets: #4834

General stuff:

  • I don't care much about the syntax
  • Please don't waste time on overly “clever” API designs, formpec syntaxes or other meta bullshit. That's not important; I just want something that works
  • I'm pretty much OK with the suggestions posted so far
  • I don't care if you use a GUI toolkit or do everything by hand if it works at the end
  • I agree that theming should be considered (not implemented!) as early as possible (otherwise it will be painful to add as an afterthought)
  • I'm not opposed to breaking changes if the result is a serious improvement over our current system. I guess the fucked-up coordinate system alone will already force you to break things anyway
@sfan5

This comment has been minimized.

Show comment
Hide comment
@sfan5

sfan5 Nov 27, 2017

Member

I'm not opposed to breaking changes if the result is a serious improvement over our current system. I guess the fucked-up coordinate system alone will already force you to break things anyway

It's possible to avoid breaking changes, however not doing so simplifies implementing a new system considerably.
We need to ask ourselves whether breaking every mod that uses formspecs is worth it.

Member

sfan5 commented Nov 27, 2017

I'm not opposed to breaking changes if the result is a serious improvement over our current system. I guess the fucked-up coordinate system alone will already force you to break things anyway

It's possible to avoid breaking changes, however not doing so simplifies implementing a new system considerably.
We need to ask ourselves whether breaking every mod that uses formspecs is worth it.

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Nov 27, 2017

Contributor

I think we don’t need any complex text layout system like HTML/CSS. Some flexibility may be needed to help localization (and to allow using larger fonts), but not that much, that’s GUI and not a web page; RTL may be handled by mirroring the whole form, in a sense. Several simple, well-defined layout patterns would be enough.

And HTML/etc. browser might be added as a special (optional) control, if necessary.

Contributor

numberZero commented Nov 27, 2017

I think we don’t need any complex text layout system like HTML/CSS. Some flexibility may be needed to help localization (and to allow using larger fonts), but not that much, that’s GUI and not a web page; RTL may be handled by mirroring the whole form, in a sense. Several simple, well-defined layout patterns would be enough.

And HTML/etc. browser might be added as a special (optional) control, if necessary.

@Ferk

This comment has been minimized.

Show comment
Hide comment
@Ferk

Ferk Nov 28, 2017

Contributor

Just my opinion, but I don't think there are team resources to handle yet another format. Specially if it has to deal with an entirely new additional parser and has to include an entire conversion and compatibility layer. HTML (both in its SGML and HTML5 variants) is not precisely a simple format, not to mention how crazy it is to render CSS correctly.

I'd say see what is wrong in the current format and improve it. My suggestion was actually meant as well as an improvement on the current format to fix what seems to be the issue. I assume the issue is not simply that it's not xml/json. If the problem is the syntax you can easily use a lua layer and get a syntax checking that's very fitting. If the problem is the inconsistent order and meaning of the parameters, name the parameters with consistent meaning. They actually do make sense, but the thing is that different widgets have different parameters and this makes the interface

Other things like the adapting containers, themes or scrollbars could be also included in the formspec, if they actually were supported by the underlying GUI. I don't believe that the formspec format is really the blocking reason why any of these features were not added before.

If you were to completelly reimplement the GUI in 0.5 with a different layouting system without caring about compatibility, I'd say go for it. But if you actually want to keep compatibility, why not do so improving the current formspec?

Contributor

Ferk commented Nov 28, 2017

Just my opinion, but I don't think there are team resources to handle yet another format. Specially if it has to deal with an entirely new additional parser and has to include an entire conversion and compatibility layer. HTML (both in its SGML and HTML5 variants) is not precisely a simple format, not to mention how crazy it is to render CSS correctly.

I'd say see what is wrong in the current format and improve it. My suggestion was actually meant as well as an improvement on the current format to fix what seems to be the issue. I assume the issue is not simply that it's not xml/json. If the problem is the syntax you can easily use a lua layer and get a syntax checking that's very fitting. If the problem is the inconsistent order and meaning of the parameters, name the parameters with consistent meaning. They actually do make sense, but the thing is that different widgets have different parameters and this makes the interface

Other things like the adapting containers, themes or scrollbars could be also included in the formspec, if they actually were supported by the underlying GUI. I don't believe that the formspec format is really the blocking reason why any of these features were not added before.

If you were to completelly reimplement the GUI in 0.5 with a different layouting system without caring about compatibility, I'd say go for it. But if you actually want to keep compatibility, why not do so improving the current formspec?

@Wuzzy2

This comment has been minimized.

Show comment
Hide comment
@Wuzzy2

Wuzzy2 Nov 28, 2017

Contributor

The formpec format is really the least of our problems and I think it is even counter-productive to waste time by starting from basically 0.

There is nothing inherently wrong with the formspec strings. Quit talking about syntax all the time, this stuff really is not important! All you're going to achieve with this is syntactical sugar.

We haven't even talked about which coordinate system to choose for the new system.
Let's start here.
On first thought, I would go with inventory slots (for one simple reason: it's already used for most widgets), but use it for ALL widgets consistently and not with some weird exceptions and random offsets.

But I'm open to other suggestions.

Contributor

Wuzzy2 commented Nov 28, 2017

The formpec format is really the least of our problems and I think it is even counter-productive to waste time by starting from basically 0.

There is nothing inherently wrong with the formspec strings. Quit talking about syntax all the time, this stuff really is not important! All you're going to achieve with this is syntactical sugar.

We haven't even talked about which coordinate system to choose for the new system.
Let's start here.
On first thought, I would go with inventory slots (for one simple reason: it's already used for most widgets), but use it for ALL widgets consistently and not with some weird exceptions and random offsets.

But I'm open to other suggestions.

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Nov 28, 2017

Member

We haven't even talked about which coordinate system to choose for the new system.

Coordinate systems are bad and don't scale, containers would be better (linear, stack, table, etc)

Why do you all care about compatibility?

Because mods are our biggest asset?

If backwards compat is desired, a converter would be a better approach.

I think the best approach is to just have both simultaneously. They would both derive from GUIModelMenu, so the code wouldn't be too complex, just with some remaining functionality.

Member

rubenwardy commented Nov 28, 2017

We haven't even talked about which coordinate system to choose for the new system.

Coordinate systems are bad and don't scale, containers would be better (linear, stack, table, etc)

Why do you all care about compatibility?

Because mods are our biggest asset?

If backwards compat is desired, a converter would be a better approach.

I think the best approach is to just have both simultaneously. They would both derive from GUIModelMenu, so the code wouldn't be too complex, just with some remaining functionality.

@sfan5

This comment has been minimized.

Show comment
Hide comment
@sfan5

sfan5 Nov 28, 2017

Member

I'd say see what is wrong in the current format and improve it.

I think it is even counter-productive to waste time by starting from basically 0.

Oh yes, why start from scratch and design a good format when you can just tack a few half-broken hacks onto the current format?

Member

sfan5 commented Nov 28, 2017

I'd say see what is wrong in the current format and improve it.

I think it is even counter-productive to waste time by starting from basically 0.

Oh yes, why start from scratch and design a good format when you can just tack a few half-broken hacks onto the current format?

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Nov 28, 2017

Contributor

Wanna stop discussing and just start coding? ;) “Dear ImGui” seems to be the best choice for the backend. It’s lightweight, C++, doesn’t depend on other libraries. It’s not very customizable (e.g. it lacks theming) but should be hackable enough to fix that.

Disclaimer: I haven’t been using any GUI library for a while, so could miss something.

Contributor

numberZero commented Nov 28, 2017

Wanna stop discussing and just start coding? ;) “Dear ImGui” seems to be the best choice for the backend. It’s lightweight, C++, doesn’t depend on other libraries. It’s not very customizable (e.g. it lacks theming) but should be hackable enough to fix that.

Disclaimer: I haven’t been using any GUI library for a while, so could miss something.

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Nov 28, 2017

Member

Imgui is for prototyping, so isn't appropriate. A formspec replacement isn't a priority for 0.5.0 anyway

Member

rubenwardy commented Nov 28, 2017

Imgui is for prototyping, so isn't appropriate. A formspec replacement isn't a priority for 0.5.0 anyway

@Ferk

This comment has been minimized.

Show comment
Hide comment
@Ferk

Ferk Nov 29, 2017

Contributor

why start from scratch and design a good format

Unless you have a lot of time and resources to maintain the compatibility layer, it'll be hard to start from scratch if you need to be backwards compatible and yet change the spec in fundamental ways that would truly not be suitable to support in the old formspec.

If the change required is suitable for being backwards-compatible, you might as well instead improve the old format to make it more extensible (formspecs are just elements with attributes after all).

If the change is truly not suitable and you are ok with the redundancy you can add it as a separate parallel implementation that doesn't need to be converted or related with the other in its interface, like Rubenwardy suggests. But I don't think it's sensible to expect a big fundamental change and yet design a layer of backwards compatibility that has to be maintained.

Contributor

Ferk commented Nov 29, 2017

why start from scratch and design a good format

Unless you have a lot of time and resources to maintain the compatibility layer, it'll be hard to start from scratch if you need to be backwards compatible and yet change the spec in fundamental ways that would truly not be suitable to support in the old formspec.

If the change required is suitable for being backwards-compatible, you might as well instead improve the old format to make it more extensible (formspecs are just elements with attributes after all).

If the change is truly not suitable and you are ok with the redundancy you can add it as a separate parallel implementation that doesn't need to be converted or related with the other in its interface, like Rubenwardy suggests. But I don't think it's sensible to expect a big fundamental change and yet design a layer of backwards compatibility that has to be maintained.

@Wuzzy2

This comment has been minimized.

Show comment
Hide comment
@Wuzzy2

Wuzzy2 Nov 29, 2017

Contributor

Oh yes, why start from scratch and design a good format when you can just tack a few half-broken hacks onto the current format?

Because I don't think the current formspec syntax is broken. After years of modding, I never ever had a problem with the syntax. I don't get why some people claim there are problems.
Feel free to convince me that there is a problem.
But as I said several times earlier, I think the big problems are somewhere else.
So, if the syntax isn't broken, then adding a full-blown API layer with Lua tables and other fancy stuff is really just syntactical sugar.

I couldn't care less if I have to specify the formspecs via a string or via fancy function calls, but I think having a fancy syntax is really the least important thing to discuss about formspecs.

We haven't even talked about which coordinate system to choose for the new system.

Coordinate systems are bad and don't scale, containers would be better (linear, stack, table, etc)

I'm not sure what to think about this. Care to elaborate? I mean, how would I, as a modder, implement this? Let's say, how would the default Minetest Game be specified under your proposed container system?
Do you claim to have a system which does away with all coordinate systems altogether?

About using a GUI toolkit: I honestly don't understand why a GUI toolkit just hasn't been used right from the start. Implementing all widgets by hand is a time-consuming process. We are still lacking very basic widgets like scrollable multi-line text.
Whatever you do, I think the new system definitely needs to provide a healthy set of core widgets.

Contributor

Wuzzy2 commented Nov 29, 2017

Oh yes, why start from scratch and design a good format when you can just tack a few half-broken hacks onto the current format?

Because I don't think the current formspec syntax is broken. After years of modding, I never ever had a problem with the syntax. I don't get why some people claim there are problems.
Feel free to convince me that there is a problem.
But as I said several times earlier, I think the big problems are somewhere else.
So, if the syntax isn't broken, then adding a full-blown API layer with Lua tables and other fancy stuff is really just syntactical sugar.

I couldn't care less if I have to specify the formspecs via a string or via fancy function calls, but I think having a fancy syntax is really the least important thing to discuss about formspecs.

We haven't even talked about which coordinate system to choose for the new system.

Coordinate systems are bad and don't scale, containers would be better (linear, stack, table, etc)

I'm not sure what to think about this. Care to elaborate? I mean, how would I, as a modder, implement this? Let's say, how would the default Minetest Game be specified under your proposed container system?
Do you claim to have a system which does away with all coordinate systems altogether?

About using a GUI toolkit: I honestly don't understand why a GUI toolkit just hasn't been used right from the start. Implementing all widgets by hand is a time-consuming process. We are still lacking very basic widgets like scrollable multi-line text.
Whatever you do, I think the new system definitely needs to provide a healthy set of core widgets.

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Nov 29, 2017

Contributor

Imgui is for prototyping, so isn't appropriate.

@rubenwardy explain please.

Feel free to convince me that there is a problem.

@Wuzzy2 yes there is a problem. There is a great problem. Not that the syntax itself is ugly, but that it forces to use ugly Lua code to generate that ugly formspec string and to regenerate it all the time. That it’s certainly not flexible enough to support e.g. multi-page containers (they are emulated currently using server’s capabilities). That it mixes controls and modifiers (although you might see the same in Borland Delphi/C++ Builder/etc., if you ever used that... Well even there, in a full-featured IDE, that wasn’t that handy).

By the way, can you write a formspec designer? Can that be done in a sane way at all?

Contributor

numberZero commented Nov 29, 2017

Imgui is for prototyping, so isn't appropriate.

@rubenwardy explain please.

Feel free to convince me that there is a problem.

@Wuzzy2 yes there is a problem. There is a great problem. Not that the syntax itself is ugly, but that it forces to use ugly Lua code to generate that ugly formspec string and to regenerate it all the time. That it’s certainly not flexible enough to support e.g. multi-page containers (they are emulated currently using server’s capabilities). That it mixes controls and modifiers (although you might see the same in Borland Delphi/C++ Builder/etc., if you ever used that... Well even there, in a full-featured IDE, that wasn’t that handy).

By the way, can you write a formspec designer? Can that be done in a sane way at all?

@Ferk

This comment has been minimized.

Show comment
Hide comment
@Ferk

Ferk Nov 30, 2017

Contributor

Not that the syntax itself is ugly, but that it forces to use ugly Lua code to generate that ugly formspec string and to regenerate it all the time.

That calls for a change of the system in which the formspec is used, rather than its syntax. You'll still have to do that even if it was in xml, json, lua tables or any other format. It has to do with the formspec being manipulated server side. Deeper changes would be needed if you don't want to regenerate the formspec every time the server wants to change something from it.

it’s certainly not flexible enough to support e.g. multi-page containers

There's already a container widget, defining a start and an end. Is the blocker for a multi-page one really the syntax? or the underlying GUI implementation?

That it mixes controls and modifiers

That's more of an issue of the implementation than of the format. This could happen as well with json or even with XML.

True that changing this could break compatibility (if you actively want to remove them, not just provide alternatives), but not a reason on itself to justify so much work and breakage, it's more of a thing of taste than pragmatism.

By the way, can you write a formspec designer? Can that be done in a sane way at all?

Most elements are just position and size. A designer wouldn't need to parse the formspec, just generate it, so I'd say the part that would be hardest is enforcing the coordinate limitations when placing controls and making sure it all looks like in Minetest. It certainly won't be easy, but under the same constrains a different format wouldn't make it any easier either, the difference would be in the generation of the output string.

I'm guessing you are assuming a new syntax is linked to different constrains. I think that's a bit like starting to build the house from the roof.

First determine what constrains are really wanted, then see if current formspecs can satisfy them in a reasonable way, and if not, then change the syntax.

Imho, there are 2 things that might be a problem in terms of syntax:

  • nesting
  • syntax checking

The nesting, depending on how the current container was done, might be already there, not sure (even if ugly for anyone used to xml / json / curly braces ...it wouldn't be the first language that defines blocks with start and end instructions).

The syntax checking, honestly to me the sanest would be to use not xml, nor json, but lua (since it's what mods are written on, so the syntax checking is for free). If lua is not gonna be used then I don't care too much about the syntax, because it's likely I won't be wanting to constantly copy-paste the strings to a syntax checker, even if they are XML, and I'm afraid if they are external files I can open in an IDE it might start becoming a hassle making changes to them on runtime. Not needing a separate file is also convenient when you have several simple formspecs as opposed to having just a few but complex ones. Thought I guess one could get used to it, I already had to get used to MyBatis at work after all.

Contributor

Ferk commented Nov 30, 2017

Not that the syntax itself is ugly, but that it forces to use ugly Lua code to generate that ugly formspec string and to regenerate it all the time.

That calls for a change of the system in which the formspec is used, rather than its syntax. You'll still have to do that even if it was in xml, json, lua tables or any other format. It has to do with the formspec being manipulated server side. Deeper changes would be needed if you don't want to regenerate the formspec every time the server wants to change something from it.

it’s certainly not flexible enough to support e.g. multi-page containers

There's already a container widget, defining a start and an end. Is the blocker for a multi-page one really the syntax? or the underlying GUI implementation?

That it mixes controls and modifiers

That's more of an issue of the implementation than of the format. This could happen as well with json or even with XML.

True that changing this could break compatibility (if you actively want to remove them, not just provide alternatives), but not a reason on itself to justify so much work and breakage, it's more of a thing of taste than pragmatism.

By the way, can you write a formspec designer? Can that be done in a sane way at all?

Most elements are just position and size. A designer wouldn't need to parse the formspec, just generate it, so I'd say the part that would be hardest is enforcing the coordinate limitations when placing controls and making sure it all looks like in Minetest. It certainly won't be easy, but under the same constrains a different format wouldn't make it any easier either, the difference would be in the generation of the output string.

I'm guessing you are assuming a new syntax is linked to different constrains. I think that's a bit like starting to build the house from the roof.

First determine what constrains are really wanted, then see if current formspecs can satisfy them in a reasonable way, and if not, then change the syntax.

Imho, there are 2 things that might be a problem in terms of syntax:

  • nesting
  • syntax checking

The nesting, depending on how the current container was done, might be already there, not sure (even if ugly for anyone used to xml / json / curly braces ...it wouldn't be the first language that defines blocks with start and end instructions).

The syntax checking, honestly to me the sanest would be to use not xml, nor json, but lua (since it's what mods are written on, so the syntax checking is for free). If lua is not gonna be used then I don't care too much about the syntax, because it's likely I won't be wanting to constantly copy-paste the strings to a syntax checker, even if they are XML, and I'm afraid if they are external files I can open in an IDE it might start becoming a hassle making changes to them on runtime. Not needing a separate file is also convenient when you have several simple formspecs as opposed to having just a few but complex ones. Thought I guess one could get used to it, I already had to get used to MyBatis at work after all.

@Wuzzy2

This comment has been minimized.

Show comment
Hide comment
@Wuzzy2

Wuzzy2 Nov 30, 2017

Contributor

Pretty much what Ferk said. I'm still not convinced the syntax is inherently broken. I'm not opposed to a syntax change, I just think it's not worth the effort.

Contributor

Wuzzy2 commented Nov 30, 2017

Pretty much what Ferk said. I'm still not convinced the syntax is inherently broken. I'm not opposed to a syntax change, I just think it's not worth the effort.

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Nov 30, 2017

Member

The container tag is essentially implemented as a preprocessor. When the formspec is parsed, it adds the offset to all elements between the tags. The container element doesn't exist after then. It wouldn't be appropriate for a multipage widget.

Member

rubenwardy commented Nov 30, 2017

The container tag is essentially implemented as a preprocessor. When the formspec is parsed, it adds the offset to all elements between the tags. The container element doesn't exist after then. It wouldn't be appropriate for a multipage widget.

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero Nov 30, 2017

Contributor

That calls for a change of the system in which the formspec is used, rather than its syntax.

Yes, mostly.

This could happen as well with json or even with XML.

Of course. There are many bad JSON-based formats.

I think that's a bit like starting to build the house from the roof.

I don’t mean we need to develop the syntax first. I just mean we don’t need, and should not (IMO) stick to the current syntax in any way while developing the new system.

Most elements are just position and size. A designer wouldn't need to parse the formspec, just generate it

Many controls are dynamic, so the designer would have to output formspec generator and not the formspec itself. Well, okay, it’s certainly possible to output Lua code that creates a formspec with given data. It actually resembles somehow the way many UI designers work. But in these other designers that is either for convenience (as in Delphi, where the generated code is fully optional and only GUI description is used to actually construct it) or because the language (C++) lacks something important (references to classes). Lua does support everything necessary. Only formspec API doesn’t.

Contributor

numberZero commented Nov 30, 2017

That calls for a change of the system in which the formspec is used, rather than its syntax.

Yes, mostly.

This could happen as well with json or even with XML.

Of course. There are many bad JSON-based formats.

I think that's a bit like starting to build the house from the roof.

I don’t mean we need to develop the syntax first. I just mean we don’t need, and should not (IMO) stick to the current syntax in any way while developing the new system.

Most elements are just position and size. A designer wouldn't need to parse the formspec, just generate it

Many controls are dynamic, so the designer would have to output formspec generator and not the formspec itself. Well, okay, it’s certainly possible to output Lua code that creates a formspec with given data. It actually resembles somehow the way many UI designers work. But in these other designers that is either for convenience (as in Delphi, where the generated code is fully optional and only GUI description is used to actually construct it) or because the language (C++) lacks something important (references to classes). Lua does support everything necessary. Only formspec API doesn’t.

@Wuzzy2

This comment has been minimized.

Show comment
Hide comment
@Wuzzy2

Wuzzy2 Jan 4, 2018

Contributor

Let's use this as a tracker for all problems / bugs / shortcomings of the current formspec API as well. It would be best that if formspecs are being redone, everything should be fixed at once.

@rubenwardy, can you please update your 1st post (also consider previous posts for input)?

Contributor

Wuzzy2 commented Jan 4, 2018

Let's use this as a tracker for all problems / bugs / shortcomings of the current formspec API as well. It would be best that if formspecs are being redone, everything should be fixed at once.

@rubenwardy, can you please update your 1st post (also consider previous posts for input)?

@QwertyCoolMT

This comment has been minimized.

Show comment
Hide comment
@QwertyCoolMT

QwertyCoolMT Feb 5, 2018

What's the status on this? who will make a call on architecture for this and set milestones?
How can i contribute to moving this forward? Is someone already working on a solution based on this discussion?

QwertyCoolMT commented Feb 5, 2018

What's the status on this? who will make a call on architecture for this and set milestones?
How can i contribute to moving this forward? Is someone already working on a solution based on this discussion?

@raymoo

This comment has been minimized.

Show comment
Hide comment
@raymoo

raymoo Feb 5, 2018

Contributor

I think, as usual for these kinds of big things, the best way to move it forward would be to PR a good foundation. I don't know if anyone is working on it, but I would guess probably not.

With such features, usually the person making the initial PR architects the rest of the system, subject to feedback from MT devs and other users.

Contributor

raymoo commented Feb 5, 2018

I think, as usual for these kinds of big things, the best way to move it forward would be to PR a good foundation. I don't know if anyone is working on it, but I would guess probably not.

With such features, usually the person making the initial PR architects the rest of the system, subject to feedback from MT devs and other users.

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy Feb 6, 2018

Member

@numberZero

Dear ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ debug tools (as opposed to UI for the average end-user)

from their read me

Member

rubenwardy commented Feb 6, 2018

@numberZero

Dear ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ debug tools (as opposed to UI for the average end-user)

from their read me

@Ferk

This comment has been minimized.

Show comment
Hide comment
@Ferk

Ferk Feb 9, 2018

Contributor

The container tag is essentially implemented as a preprocessor. When the formspec is parsed, it adds the offset to all elements between the tags. The container element doesn't exist after then. It wouldn't be appropriate for a multipage widget.

Even if it's implemented as a preprocessor, it is still possible to expand on that to implement a paging system.

Example:

  • Before pre-processing:
container[pos=1,1;id=pets]
  page[]
     image[pos=0,0;size=1,1;texture=cats.png]
  page_end[]
  page[]
     image[pos=0,0;size=1,1;texture=dogs1.png]
     image[pos=0,1;size=2,2;texture=dogs2.png]
  page_end[]
  page[id=whatever]
     image[pos=0,0;size=1,1;texture=nyan1.png]
  page_end[]
container_end[]
pager_button[pos=0,0;size=1,1,label=cats;activate=pets,1]
pager_button[pos=1,0;size=1,1,label=dogs;activate=pets,2]
pager_button[pos=2,0;size=1,1,label=huh?;activate=pets,whatever]

After pre-processing:

image[pos=1,1;size=1,1;texture=cats.png;page=pets,1]
image[pos=1,1;size=1,1;texture=dogs1.png;page=pets,2]
image[pos=1,2;size=2,2;texture=dogs2.png;page=pets,2]
image[pos=1,1;size=1,1;texture=nyan1.png;page=pets,whatever]
pager_button[pos=0,0;size=1,1,label=cats;activate=pets,1]
pager_button[pos=1,0;size=1,1,label=dogs;activate=pets,2]
pager_button[pos=2,0;size=1,1,label=huh?;activate=pets,whatever]

Then, client side, hide any formspec element that has a "page" field different than the first found in each section of the same "page" set of values.

When the user clicks one of the "pager_button", check (client-side) the value of the "activate" field and make it be the current page, unhiding/showing all items marked with that page and hiding the rest. Just as a client-side visual effect, without really sending any packets to the server.

You can even chain this to have several layers of pagination.

I'm not saying this is the best way to implement it, just giving an example that shows it's not syntax what's blocking this.
If reimplementing the entire formspec system, adding new dependencies, stitching them to the engine and trying to maintain a compatibility layer is faster, easier and more maintainable than improving the current formspec system, then awesome, do that instead.

Contributor

Ferk commented Feb 9, 2018

The container tag is essentially implemented as a preprocessor. When the formspec is parsed, it adds the offset to all elements between the tags. The container element doesn't exist after then. It wouldn't be appropriate for a multipage widget.

Even if it's implemented as a preprocessor, it is still possible to expand on that to implement a paging system.

Example:

  • Before pre-processing:
container[pos=1,1;id=pets]
  page[]
     image[pos=0,0;size=1,1;texture=cats.png]
  page_end[]
  page[]
     image[pos=0,0;size=1,1;texture=dogs1.png]
     image[pos=0,1;size=2,2;texture=dogs2.png]
  page_end[]
  page[id=whatever]
     image[pos=0,0;size=1,1;texture=nyan1.png]
  page_end[]
container_end[]
pager_button[pos=0,0;size=1,1,label=cats;activate=pets,1]
pager_button[pos=1,0;size=1,1,label=dogs;activate=pets,2]
pager_button[pos=2,0;size=1,1,label=huh?;activate=pets,whatever]

After pre-processing:

image[pos=1,1;size=1,1;texture=cats.png;page=pets,1]
image[pos=1,1;size=1,1;texture=dogs1.png;page=pets,2]
image[pos=1,2;size=2,2;texture=dogs2.png;page=pets,2]
image[pos=1,1;size=1,1;texture=nyan1.png;page=pets,whatever]
pager_button[pos=0,0;size=1,1,label=cats;activate=pets,1]
pager_button[pos=1,0;size=1,1,label=dogs;activate=pets,2]
pager_button[pos=2,0;size=1,1,label=huh?;activate=pets,whatever]

Then, client side, hide any formspec element that has a "page" field different than the first found in each section of the same "page" set of values.

When the user clicks one of the "pager_button", check (client-side) the value of the "activate" field and make it be the current page, unhiding/showing all items marked with that page and hiding the rest. Just as a client-side visual effect, without really sending any packets to the server.

You can even chain this to have several layers of pagination.

I'm not saying this is the best way to implement it, just giving an example that shows it's not syntax what's blocking this.
If reimplementing the entire formspec system, adding new dependencies, stitching them to the engine and trying to maintain a compatibility layer is faster, easier and more maintainable than improving the current formspec system, then awesome, do that instead.

@v-rob

This comment has been minimized.

Show comment
Hide comment
@v-rob

v-rob Feb 13, 2018

Formspecs need theming. With the current level of theming, I can't make formspecs look very good. Personally, I think that image elements are the best answer to this. They're likely easier than colorizing or making custom gradients for the buttons. Here's what I think they should include:

Note: I'm using images of Windows XP stuff for my examples because I have them on hand for no good reason.

  1. Normal element image. For buttons, this would be the normal image of the button.
    Ex: image -- Normal button

  2. Image when mouse is hovering over the element.
    Ex: image -- Highlighted button

  3. Image when the button is being pressed.
    Ex: image -- Pressed button

  4. If the element is something like a field, then it needs a background image. The image would overlay the field.
    Ex: image -- Field background

These image elements should apply to all elements possible: Dropdowns, checkboxes, textlists, etc.

Unfortunately, this can lead itself to some elements having many images. Take, for instance, scrollbars. Scrollbars have a button for up, a button for down, a button for the actual scrollbar, and the background behind the bar. The buttons all need hovering and pressed images besides the normal images. That ends up with 10 images for just a scrollbar. I don't see a way to fix this problem, though.
Ex: image -- Top button, bottom button, bar, and background.

Also, assuming an element has an image, then the element should be transparent as to not show any grey gradient should the image be partly transparent.

EDIT: Well, a possible solution to the problem stated above is tilesheets, like the ones used for nodes with animated textures. First is the normal, below it is the hover, and on the bottom is the pressed.

v-rob commented Feb 13, 2018

Formspecs need theming. With the current level of theming, I can't make formspecs look very good. Personally, I think that image elements are the best answer to this. They're likely easier than colorizing or making custom gradients for the buttons. Here's what I think they should include:

Note: I'm using images of Windows XP stuff for my examples because I have them on hand for no good reason.

  1. Normal element image. For buttons, this would be the normal image of the button.
    Ex: image -- Normal button

  2. Image when mouse is hovering over the element.
    Ex: image -- Highlighted button

  3. Image when the button is being pressed.
    Ex: image -- Pressed button

  4. If the element is something like a field, then it needs a background image. The image would overlay the field.
    Ex: image -- Field background

These image elements should apply to all elements possible: Dropdowns, checkboxes, textlists, etc.

Unfortunately, this can lead itself to some elements having many images. Take, for instance, scrollbars. Scrollbars have a button for up, a button for down, a button for the actual scrollbar, and the background behind the bar. The buttons all need hovering and pressed images besides the normal images. That ends up with 10 images for just a scrollbar. I don't see a way to fix this problem, though.
Ex: image -- Top button, bottom button, bar, and background.

Also, assuming an element has an image, then the element should be transparent as to not show any grey gradient should the image be partly transparent.

EDIT: Well, a possible solution to the problem stated above is tilesheets, like the ones used for nodes with animated textures. First is the normal, below it is the hover, and on the bottom is the pressed.

@Wuzzy2

This comment has been minimized.

Show comment
Hide comment
@Wuzzy2

Wuzzy2 Feb 14, 2018

Contributor

I'm not sure if it is a good idea to require an image for every widget.

At least make it optional? Quick and easy colorization of widgets is also important. With baked-in images, that's not so simple.

Contributor

Wuzzy2 commented Feb 14, 2018

I'm not sure if it is a good idea to require an image for every widget.

At least make it optional? Quick and easy colorization of widgets is also important. With baked-in images, that's not so simple.

@v-rob

This comment has been minimized.

Show comment
Hide comment
@v-rob

v-rob Feb 15, 2018

The easy way to make an image button act like a normal button is leave the image part of it blank or set it to blank.png. I think making duplicates would be unneccesary.

v-rob commented Feb 15, 2018

The easy way to make an image button act like a normal button is leave the image part of it blank or set it to blank.png. I think making duplicates would be unneccesary.

@Calinou

This comment has been minimized.

Show comment
Hide comment
@Calinou

Calinou Feb 15, 2018

Member

It's better to go with vector-based stuff rather than bitmaps, since those support scaling and hiDPI out of the box.

Member

Calinou commented Feb 15, 2018

It's better to go with vector-based stuff rather than bitmaps, since those support scaling and hiDPI out of the box.

@nerzhul nerzhul added this to Feature requests in Minetest 5.0.0 Mar 24, 2018

@v-rob

This comment has been minimized.

Show comment
Hide comment
@v-rob

v-rob May 9, 2018

I recently was experimenting with other programming languages than Lua and some of the GUI's that come with them, and it really showed me to the problems with the current formspec layout. Of the things I tried, this is what I think would be best:

This is how I think the layout should be for registering a formspec:

-- This registers the initial window

minetest.register_window("mod:random_formspec", {
     size = {x = 5, y = 4},
     location = {x = -1, y = -2},
     anchor = {x = 0.5, y = 0.5}
})

-- Add a label

minetest.register_label("mod:label", {
     window = "mod:random_formspec",
     pos = {x = 0.5, y = 1.5},
     image = "text_bg.png",
     text = "This is an example formspec."
})

-- Add a button

minetest.register_button("mod:ok_button", {
     window = "mod:random_formspec",
     pos = {x = 2, y = 3},
     image = "button.png",
     hover_image = "button_hover.png",
     pressed_image = "button_pressed.png",
     text = "Ok",
     func = function(player)
          minetest.close_formspec(player:get_player_name, "mod:random_formspec")
     end
})

minetest.register_window(formspec_name, formspec_definition):
Makes a formspec window and defines the size, location, and anchor.

minetest.register_*(element_name, ) Where * is any formspec element:
Defines the specified element and adds it to the specified window.

To open a formspec, use minetest.show_formspec in the node/entity on_rightclick function.

Also, there should be bindings, like on_enter, on_exit(both for when the mouse hover/stops hovering over an element) on_rightclick, on_rightclick_release, on_leftclick, on_leftclick_release, etc. For these bindings, there need to be a way to tell if another binding is happening at the same time.

Anyway, these are my thoughts on the format of formspecs.

v-rob commented May 9, 2018

I recently was experimenting with other programming languages than Lua and some of the GUI's that come with them, and it really showed me to the problems with the current formspec layout. Of the things I tried, this is what I think would be best:

This is how I think the layout should be for registering a formspec:

-- This registers the initial window

minetest.register_window("mod:random_formspec", {
     size = {x = 5, y = 4},
     location = {x = -1, y = -2},
     anchor = {x = 0.5, y = 0.5}
})

-- Add a label

minetest.register_label("mod:label", {
     window = "mod:random_formspec",
     pos = {x = 0.5, y = 1.5},
     image = "text_bg.png",
     text = "This is an example formspec."
})

-- Add a button

minetest.register_button("mod:ok_button", {
     window = "mod:random_formspec",
     pos = {x = 2, y = 3},
     image = "button.png",
     hover_image = "button_hover.png",
     pressed_image = "button_pressed.png",
     text = "Ok",
     func = function(player)
          minetest.close_formspec(player:get_player_name, "mod:random_formspec")
     end
})

minetest.register_window(formspec_name, formspec_definition):
Makes a formspec window and defines the size, location, and anchor.

minetest.register_*(element_name, ) Where * is any formspec element:
Defines the specified element and adds it to the specified window.

To open a formspec, use minetest.show_formspec in the node/entity on_rightclick function.

Also, there should be bindings, like on_enter, on_exit(both for when the mouse hover/stops hovering over an element) on_rightclick, on_rightclick_release, on_leftclick, on_leftclick_release, etc. For these bindings, there need to be a way to tell if another binding is happening at the same time.

Anyway, these are my thoughts on the format of formspecs.

@TMcSquared

This comment has been minimized.

Show comment
Hide comment
@TMcSquared

TMcSquared May 10, 2018

I was poking around and found a neat GUI library that is:

  • themeable
  • works with Irrlicht
  • should be fairly easy to implement into the modding API
  • can be scripted using Lua
  • cross platform

TMcSquared commented May 10, 2018

I was poking around and found a neat GUI library that is:

  • themeable
  • works with Irrlicht
  • should be fairly easy to implement into the modding API
  • can be scripted using Lua
  • cross platform
@nerzhul

This comment has been minimized.

Show comment
Hide comment
@nerzhul

nerzhul May 10, 2018

Member

i like cegui and i like the products listed on the site. It seems to be mature, but it's a new dep.

Member

nerzhul commented May 10, 2018

i like cegui and i like the products listed on the site. It seems to be mature, but it's a new dep.

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy May 10, 2018

Member

A new dep is perfectly fine for something as important as a GUI system

Member

rubenwardy commented May 10, 2018

A new dep is perfectly fine for something as important as a GUI system

@sfan5

This comment has been minimized.

Show comment
Hide comment
@sfan5

sfan5 May 10, 2018

Member

While "can be scripted using Lua" is nice, it's not what we need.
We need a GUI library that can work "over" the network, since formspecs are shown on the client but the code that handles formspecs runs on the server.

Just a reminder, since this is not the first time someone has suggested a GUI library because it has Lua bindings.

Member

sfan5 commented May 10, 2018

While "can be scripted using Lua" is nice, it's not what we need.
We need a GUI library that can work "over" the network, since formspecs are shown on the client but the code that handles formspecs runs on the server.

Just a reminder, since this is not the first time someone has suggested a GUI library because it has Lua bindings.

@nerzhul

This comment has been minimized.

Show comment
Hide comment
@nerzhul

nerzhul May 10, 2018

Member

@sfan5 i don't think GUI library over network exists somewhere. What i note here it's cegui permits to drop many shitty irrlicht old and crappy code on formspecs, and we can create a new formspec protocol for this new UI systems in parallel and drop formspecs at a point. (or keep the compat but the formspec format is... anoying)

Member

nerzhul commented May 10, 2018

@sfan5 i don't think GUI library over network exists somewhere. What i note here it's cegui permits to drop many shitty irrlicht old and crappy code on formspecs, and we can create a new formspec protocol for this new UI systems in parallel and drop formspecs at a point. (or keep the compat but the formspec format is... anoying)

@sfan5

This comment has been minimized.

Show comment
Hide comment
@sfan5

sfan5 May 10, 2018

Member

A new GUI library can be used when writing a replacement, yes.
It's just doesn't solve the problem this issue is about: a replacement for Formspecs

(That doesn't mean it doesn't belong here, GUI libraries are still useful to know.)

Member

sfan5 commented May 10, 2018

A new GUI library can be used when writing a replacement, yes.
It's just doesn't solve the problem this issue is about: a replacement for Formspecs

(That doesn't mean it doesn't belong here, GUI libraries are still useful to know.)

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy May 10, 2018

Member

The only useful part of the Lua binding is if it has the ability to make custom elements using it already. Otherwise it's not a benefit of the library for us

Member

rubenwardy commented May 10, 2018

The only useful part of the Lua binding is if it has the ability to make custom elements using it already. Otherwise it's not a benefit of the library for us

@nerzhul

This comment has been minimized.

Show comment
Hide comment
@nerzhul

nerzhul May 10, 2018

Member

formspecs are bound to irrlicht, we can make formspecs cegui aware, and it can be nice :)

Member

nerzhul commented May 10, 2018

formspecs are bound to irrlicht, we can make formspecs cegui aware, and it can be nice :)

@rubenwardy

This comment has been minimized.

Show comment
Hide comment
@rubenwardy

rubenwardy May 10, 2018

Member

No, formspecs need to be killed completely.

Member

rubenwardy commented May 10, 2018

No, formspecs need to be killed completely.

@TMcSquared

This comment has been minimized.

Show comment
Hide comment
@TMcSquared

TMcSquared May 10, 2018

The only useful part of the Lua binding is if it has the ability to make custom elements using it already. Otherwise it's not a benefit of the library for us

I believe the Lua might be only for animating the GUI, not sure on that though. But for the record, that is very cool nonetheless.

TMcSquared commented May 10, 2018

The only useful part of the Lua binding is if it has the ability to make custom elements using it already. Otherwise it's not a benefit of the library for us

I believe the Lua might be only for animating the GUI, not sure on that though. But for the record, that is very cool nonetheless.

@rubenwardy rubenwardy removed this from Feature requests in Minetest 5.0.0 May 10, 2018

@numberZero

This comment has been minimized.

Show comment
Hide comment
@numberZero

numberZero May 11, 2018

Contributor
Contributor

numberZero commented May 11, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment