Skip to content
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

Add the ability to read stdin from the console #2322

Closed
ArronGIT opened this issue Feb 20, 2021 · 10 comments · Fixed by godotengine/godot#65751
Closed

Add the ability to read stdin from the console #2322

ArronGIT opened this issue Feb 20, 2021 · 10 comments · Fixed by godotengine/godot#65751
Milestone

Comments

@ArronGIT
Copy link

Describe the project you are working on

like an IDE, a text editor, after editing a file, passes the file address to another program for processing and receiving the result from it

Describe the problem or limitation you are having in your project

there is only writing to the console print (), but no input () reading from the console

Describe the feature / enhancement and how it helps to overcome the problem or limitation

it was not bad to implement reading as in python

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

var text = input ()
var num = int (input())

If this enhancement will not be used often, can it be worked around with a few lines of script?

in the script, I did not find the read from console function, most likely there is an opportunity to do this through native code, but I am not good at this

Is there a reason why this should be core and not an add-on in the asset library?

if there is a tutorial then there is no reason.

@Calinou Calinou closed this as completed Feb 20, 2021
@Calinou Calinou reopened this Feb 20, 2021
@Calinou Calinou changed the title Add the ability to read from the console Add the ability to read stdin from the console Feb 20, 2021
@Calinou Calinou removed the archived label Feb 20, 2021
@Calinou
Copy link
Member

Calinou commented Feb 20, 2021

See also #216.

@YuriSizov
Copy link
Contributor

It's very cool to use Godot for non-gaming apps, but since this is a game engine first and foremost, what would be the use-case for gaming or game development?

@Zireael07
Copy link

MUD engines come to mind immediately, as well as debug/cheat consoles.

@Calinou
Copy link
Member

Calinou commented Feb 20, 2021

Being able to read stdin would be useful for dedicated game servers where you can input commands as an administrator (see Minecraft).

In the meantime, you could make the server read from a text file every so often (every 10-30 seconds, possibly more often if a command was recently input). If the file isn't empty, execute its contents as a command and remove the file's contents (but do not remove the file entirely). With modern text editors reloading files automatically when they change on the filesystem, the user experience won't be so bad (while still not being great).

Another alternative is to use the WebSocketServer class and send command requests using a WebSockets client. Or you can use a REST API by hosting a HTTP server from the game server with a GDScript HTTP server implementation.

@merriam
Copy link

merriam commented Feb 21, 2021

In Python, reading keys from stdin is an infrequently answered question. There are dozens of StackOverflow questions with variations of "how do a read a key in Python" and most are unanswered or have non-working answers. You get dozens of questions that reflect some of the underlying issues about buffering and compatibility.

Limitations are hard to understand. Major differences are reading characters when line buffered versus character buffered versus a piped stream; reading when the originating terminal, a created child window, or other window has focus; reading individual characters and its relationship to line buffering; buffer lengths and refill policies; and interactions between event libraries (like Godot) and stdin. For example, read(1) will often return one key, but Python will force line buffering, which is also forced by the OS, but Godot would probably remove the key preemptively to fire keyboard events, but pushing back into that buffer creates ordering problems.

Handling is specific to minor versions of the operating system. The answers specific to MacOs 10.15 are not the same as MacOS 10.14, and permission requirement changed slightly during MacOS 10.14 updates. On Windows, an extra DLL is required from Microsoft to read the keyboard. It's a drain on energy dealing with keyloggers built in your game engine. Many answers depend on specific operating system settings, with MacOS being particularly, and increasingly, persnickety about reading the keyboard from anything but a newly created window.

I feel that there needs to be a strong user case for this feature.

@sesopenko
Copy link

Reading stdin would be great. Websockets provide a workaround but they're far more complex than simply reading stdin. Management of game servers in an MMO is a good example. If one could send json strings through stdin to give commands to a server instance, it'd be possible to orchestrate game systems across multiple multiplayer servers, all running as sub-processes of a larger system.

@Faless
Copy link

Faless commented Jul 3, 2022

It's very cool to use Godot for non-gaming apps, but since this is a game engine first and foremost, what would be the use-case for gaming or game development?

Just come across this proposal with a decent(?) use case.
Now that we have headless mode, it's pretty easy to create command line tools in GDScript to manage your game backend (in my case, creating/deleting/backing up a database).
Since some of those operations can be destructive (drop database) or costly (starting a backup process) it is pretty common to add at least a confirmation prompt for them.

Right now I'm faking this with a very ugly hack, forcing the script to be run with the local debugger active (--debug) adding a breakpoint right after asking confirmation, and letting the user continue (c) or quit (q) from the debugger.

I think having something like python input() (which blocks execution) could help in this case (and others where you might want to read some information, e.g. entering the DB password, which I now read from an environment variable)

My ugly hack:

extends SceneTree

func _initialize():
	if not EngineDebugger.is_active():
		push_error("Please run the script with the --debug option")
		quit.call_deferred()
		return
	var options = {
		create = true,
		drop = false,
		cascade = false
	}
	print("Creating database at %s with options %s. Press 'c' to continue, 'q' to exit" % [URL, options])
	breakpoint

@Calinou
Copy link
Member

Calinou commented Jul 3, 2022

I think having something like python input() (which blocks execution) could help in this case (and others where you might want to read some information, e.g. entering the DB password, which I now read from an environment variable)

Blocking execution is problematic for dedicated server consoles that can accept commands at any times, so it should be optional.

@Faless
Copy link

Faless commented Jul 3, 2022

Blocking execution is problematic for dedicated server consoles that can accept commands at any times, so it should be optional.

Yeah, the "dedicated server console" is a different use case and honestly I'm not sure it's a good idea to handle both with the same function.

It's also kinda weird to have a console attached to a dedicated server process directly since they are usually spawned as system services.
You'd probably need something like screen or tmux to detach/attach to it, and having dealt with those in the past, I'd rather use a dedicated admin process that communicate with it via TCP/websocket/UNIX socket/etc like most dedicated servers do.

@Faless Faless moved this to In Discussion in Godot Proposal Metaverse Jul 8, 2022
@Faless Faless moved this from In Discussion to Ready for Review in Godot Proposal Metaverse Jul 8, 2022
@akien-mga akien-mga added this to the 4.0 milestone Jul 21, 2022
@akien-mga
Copy link
Member

This seems to already be implemented as OS::get_stdin_string(bool p_block). It would just need to be exposed to bindings via core_bind::OS.

@akien-mga akien-mga moved this from Ready for Review to Ready for Implementation in Godot Proposal Metaverse Jul 21, 2022
Repository owner moved this from Ready for Implementation to Implemented in Godot Proposal Metaverse Oct 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Implemented
Development

Successfully merging a pull request may close this issue.

8 participants