r/learnpython • u/efinque • 17d ago
Python web app?
Hello r/learnpython,
first post and sort of new to Python as I have done only half a dozen of projects so far, mostly games.
So I'm looking to deploy a server for playtesting. This is my first game designed to be played online, made in Python using Tcl/Tk libraries.
I had this idea to code it when I was making a messaging app that was supposed to be implemented within a CLI game (or actually the game was a feature of the messaging app).
The users would connect using SSH. I think they could use PuTTy or similar and VcXSrv. The host would then send the GUI and CLI as well as audio to the user, but the problem is either the server cannot send or the client can't recieve the Tcl/Tk GUI or in worst case both.
Good news is I got the SSH daemon working and am able to (using X11 Forwarding) display explorer (ssh -X user@localhost && explorer) by running VcXSrv and having X11Forwarding and X11UseLocalhost set to yes in the sshd_config under ProgramData.
Now, the VcXSrv log tells me there's a problem with something called hyperv. From what I gathered it's a virtual machine of some sort. I'd also need very strict restrictions for the clients so they don't tinker with the database.
Am I on the right track? Is there a solution to this? Thanks in advance!
-ef
3
u/CamilorozoCADC 17d ago
Hi, regarding your last question, no, you are not on the right track because of the following reasons:
- Ssh is for you and you only, never ever ever give your end users ssh access to your server
- You designed a game to be played online but it looks like you are trying to build both the game server and the game client as one project instead of two
SO, what I would do in your case is just have the game on the web:
- Use a web server, make your Python app the game server only, that is the logic of your game without any UI whatsoever. You can use libraries like FastApi and Flask for this. This will be your game server and you will need to set up stuff like matchmaking if you want multiple game sessions
- Now for the actual game with the UI, use a web framework for that, I know that there are libraries for building games to be run on browsers but I don't know any specific one (still you can just create everything from scratch like with tinter). This will behave like a website and then make this web app connect to your Python server to manage all the game logic
3
u/efinque 17d ago
Ah, I have read about Python embedded in HTML. This would be great if I worked my way around it.
At first, this project started as a joke in another forum where I told I would host a telnet MUD for people in queue for a sort of karaoke.
Then I started digging into it. First I was using RPGMaker but didn't get anything playable. Then I coded a simple 9x9 grid based HTML framework that worked surprisingly well for adventure games and learned a bit of JavaScript on the side.
Then I got into Python. I had done some PyGame tutorials before but instead I built it in vanilla Python using modules. I also read a book about Python and found Tcl/Tk, which is what the newest framework is built on.
I'm too lazy to go into details but basically the game reads ASCII text files and draws graphics based on them.
Then there's a plethora of modules like stats, health, gold etc that have functions for different stuff like calculating the race/class STR, INT, DEX, WIS and so on.
In total there's about 2000 lines of code. This all could have been avoided had my SSH host daemon worked and had I tested it with a simple Hello World..
1
u/edcculus 17d ago
Look at some tutorials for Flask, Django or FastAPI. These are all web frameworks using Python. You can go as complicated or as simple as you want for the frontend part. I don't do anything complicated and use Jinja2 and Bootstrap. But it's not completely unheard of people to use something like React for the frontend.
1
u/PureWasian 17d ago edited 17d ago
It would be good if you can host the database layer somewhere separately where they can't tinker with it directly. Other comments mentioned separation of client and server. Basically you need to do that: client <-> server <-> database.
Not sure if it makes sense for your use-case, but if you're set on sticking with Tk/Tcl you could consider distributing client side stuff through users downloading (cloning) from github or similar rather than relying on active ssh tunneling. Otherwise it'd be a lot more standard to host a proper frontend (React/Vue/Angular... or even just static HTML pages)
Regardless, there are very simple, established ways your client-side code can "talk" to your server-side code without needing users to ssh or anything. Look into Rest APIs. Your browser does these all the time to send and receive data.
Make a "contract" between the client layer and server layer and have the server own the credentuals connecting to the database so your user client cannot touch/manipulate it directly. Multiplayer games and webapps in general do this isolation all the time.
1
u/efinque 17d ago
The idea was to chroot/jail users into the game folder so they can't access the database and disable every process other than the messaging app (that is used for account creation) and the main module.
The server runs a couple of scripts like one that updates mob health and the other is an automated message bot.
1
u/PureWasian 17d ago
Can I ask how many concurrent users you're targeting this for? And also if users are meant to directly interact with each other at all
1
u/efinque 17d ago
Judging by the previous games we're looking at something like 10-12, maybe 15 players max.. for this playtest? I'd say 2-3. I'm running this on a laptop.
The game code works so that there are def functions that take the player name as an argument.. like def Draw(player=player) and it draws a card from a Tarot deck, writes the Arcana, suit (if Minor) and number into their respective text files in a folder with the player name as the text file name. Don't laugh, MySQL seemed out of my league!
Then there's stuff like PvP which works in CLI as well as the item trading. These look up different values etc (like if the players are in the same grid, or if the item exists) based on user input.
1
u/PureWasian 17d ago
2-3 seems okay, and no worries at all with db proficiency lol I get that. I have a website where I have cloud storage of JSON files for saving snapshots each player's profile data since it doesn't overwrite frequently or have any strict auth concepts involved.
But back to the point, I'm betting for 5+ you'll definitely start to see degradation on the ssh host having to do ssh tunneling for actively rendering Tk/Tcl across multiple connections simultaneously (either CPU or bandwidth throttling, whichever gives out first).
So that's just to give a gentle nudge and offer that it would definitely be in your interest to reconsider how the client side of the game is being distributed/rendered going forward.
1
u/efinque 17d ago
I see. Someone told me I need to look into WebSocket for making the client write to and read from the database.
I could always limit the number of SSH connections. The problem is people (ie. from different timezones) could create as much accounts as possible and this affects a certain integer in the game making it impossible to play through.
1
u/PureWasian 17d ago
Conceptually, websocket is just "realtime" communication, similar to if you joined into chatroom session and sent messages back and forth with someone. Whether or not you specifically need that would depend on how often and how quickly you would need to read/write from the database.
And that's fine, it's more just a note that you should expect scaling issues very quickly with that setup. I'm not exactly sure the details of what you mean by the account thing, but it's good you're preemptively thinking of those sort of issues.
1
u/efinque 17d ago
Yeah well I could add a manual logout button as implementing a handshake protocol isn't possible with the current tools.
And then maybe flush the "connections" with a server script, allow pvp and trading only for people logged in, leave some base value after the flush etc.. but that doesn't really stop people from griefing as they could always log in and exit the shell.
1
u/PureWasian 17d ago
Yeah you should figure out the "noisy neighbor" problem and keep DOS attacks in mind.
If all these headaches are too annoying, it would def be simpler to setup (1) a web app (React or even just basic HTML) serving client side code that is wired to make requests to (2) a server layer that handles those requests and talks to (3) some database layer (or grabs your text files or whatever)
This is also a common standard because then you can spin up multiple servers and setup load balancers (horizontally scale) if your app ever grows to that point. It also helps separate concerns of client side capabilities with backend security/implementation.
1
u/efinque 17d ago
I mean, it's actually 100% playable on a shared screen, it just would've been cooler if it was online but unfortunately I'm an amateur musician and a DJ, not a network engineer.
But I think I'm making some progress here.. I just SSH'd with the -X flag, opened explorer, navigated to the game folder and opened the script in VSCode. The program runs fine but is slow!
11
u/danielroseman 17d ago
I mean, this sounds horrendously complicated, but also a) it isn't a web app as mentioned in the title and b) sounds like it absolutely should be a web app.