Simple Minecraft Clone in 580 lines of Python
github.com
github.com
I'd image something like :
def setDefaultBlockColor(color): # recall that this is a function that takes in a variable called 'color' as its argument, write the code that will set the current game files configuration file to either 'red', 'blue' or 'green' (p.s. DONT FORGET TO INDENT YOUR CODE!)
Just writing this function and seeing it work once you load up the game is enough to hook almost anyone that has the potential to enjoy programming but just doesn't know it yet.
Where would games be if we didn't have abstraction?
And then here's the other nice lesson: students can learn that they don't need to know everything before they start making cool and useful stuff. The confidence that comes from knowing that is just as important (more so?) as being able to implement pyglet from scratch if necessary. The former is a skill used daily, whereas the latter -- well, consider how often in your engineering career you casually rely on the work of others to power your creation. Has anyone ever required you to write a WSGI implementation, or a framework?
That's been my experience, at least.
I remember writing this:
10 PRINT "LESSNONYMOUS"
20 GOTO 10
Seeing actual things happen was awesome. Now we have 3D games, seeing your name over and over wont enthrall, so being able to mod and extend a basic Minecraft world would be an incredible gateway.
The way to hook people is exactly like you say. Make a small change, see a huge difference. Suddenly ... YOU HAVE THE POWER!!!
10 PRINT "LESSNONYMOUS";
20 GOTO 10
Probably a jerk move in retrospect, but how can you work in a computer store and not play around with the computers?!
20 GOTO 10
There was an awful lot happening behind my very first program too. And that was the available level of abstraction. Why start kids coding something so simple when they can mess with something so powerful?
(emphasis mine :-))
That's the first thing I thought. I teach kids to do creative/interesting things with computers. It's hard to get them writing code[0] (it's not a classroom--they come voluntarily and explore what technology topics they like), one of the older (14) kids started out doing that, however, because he wanted to write Minecraft mods. Those are written in Java, in an Eclipse environment working on a decompiled (and only partially annotated) version of the Minecraft .jar. That was not how I envisioned a gentle introduction to computer-programming :) But he was persistent, and got it to work. This only goes to show what's really important: not if the language is simple, complex, elegant, whether the subject matter is easy to grasp, no. It's just a matter of whether the thing they need to learn is on the path towards a goal they really really want to achieve[1].
But yes, Minecraft is a huge thing among these kids. Others are cobbling together multi-player servers from scrap computers.
While in a sense, brooksbp (sibling comment) is right, there's a LOT going on in these 580 lines of code (I haven't looked at it yet, but I can imagine), 580 lines is not that much either. And if it's something they can run, edit, run, mess around with, see why it broke, edit, run, etc, that's enough to get started. They don't need to understand the whole thing right away. In fact even something as simple (and hardly programming) as changing the colour or textures is awesome because it teaches them that whatever's going on behind those graphics is yours and yours to control (unlike, say, the TV or their aunt's iPhone).
That 14 year-old kid is currently experimenting with Unity, trying to make an actual game. Unfortunately, I haven't had time to get acquainted with that environment myself, so I can only give him general advice. I'm way more comfortable with Python (especially a mere 580 lines of it :P) so who knows.
[0] Which still mystifies me, I was writing my first lines of BASIC at the age of 9, without help from my parents or anyone except library books and magazines. That probably makes me an outlier, but enough children pass through here that I'd expect to see at least maybe one or two. I guess it's different because back then that machine (an Amstrad PCW) wouldn't do anything interesting except word-processing unless I coded it myself.
[1] That was actually a big lesson for me :) I kind of knew it to be the case, but witnessing the process really nailed it down for me.
Thankfully we do other things. I was able to use the example of when he learned to fly model airplanes to show why he had to push through the stuff that's just not fun to be able to reach for the good stuff. I reminded him of the work we had to do for him to be able to fly and land solo before he could start on fun aerobatics.
This is why I would suggest simply converting something like this to a tutorial might not guarantee engagement. You need to really think through the "fun and interesting" factor both during and after the course. Not easy.
Actually you should just write it in the project's README.md :)
If, for some reason you don't want to link the code here, I put my email in my profile info.
Unfortunately there is very little momentum in the project. Last year an alpha version was released after a gap of two years. I truly hope that pyglet gets the popularity it deserves.
How do people do this? How do their minds work?
This one really gets me as well:
Talk to me about "shouldn't" when we start breaking the Shannon-limit or other hard information-theoretical limits :-P
IMHO the game actually shows how powerful Python + Pyglet (OpenGL actually) are.
Wanna get your mind blown even harder? Check some 4kb demos[1]... and that's binary size! No JVM/Python runtime supporting it.
[1] http://www.youtube.com/results?search_query=4kb+demo&pag...
It's comparatively very big (179KB), but impressive how they were able to squeeze so much stuff there: video http://www.youtube.com/watch?v=wqu_IpkOYBg, official repository: http://j.mp/11ETcY0.
If you want to dig deeper, Farbrausch published most of their material and tools last year including the source code for fr-041. Search for farbrausch on GitHub. But I must say, it's pretty hardcore.
(DirectX + 4kb) vs. (OpenGL + Python + Pyglet + 500LOC)
=
4kb vs. (Python + Pyglet + 500LOC)
Long are gone the days when you could manage the framebuffer yourself :) Specially if you want to run the demo in modern OSes.[1] http://en.wikipedia.org/wiki/.kkrieger [2] http://www.youtube.com/watch?v=2NBG-sKFaB0
It's in Farbrausch's GitHub with many more demos/demotools https://github.com/farbrausch/fr_public
Edit: It would be intresting to see demos like this (4KB / 64KB) for WebGL. Does something like this exist already ?
Code a lot. Write games a lot.
This produces slower results, better code. The other trade off is I'm not working from direct memory or skill, so co-workers have less respect for me, even if "my" solution is better than theirs.
This makes me functional years ahead of my experience, but belies a true understanding of the concepts. As I methodically catch up with myself over time, this is less true.
I could never imagine myself writing 50,000 lines, I'm way too lazy for that. Fifty-thousand lines? You could write a universe in that, with a high-level language like Python (or in assembly, a smallish planet).
Semi-kidding aside, it's part laziness and part DRY-principle. I hate writing code twice, even if it's two chunks with similar functionality. If they are so similar (in an abstract way), there's probably a reason for that, and I try to capture that reason into my code by unraveling the similar parts from the specific parts. That usually makes it smaller.
Can you imagine what happens if those 50K lines (comments/white-space aside) all implement nearly unique functionality? Those 64k demos linked upthread are what happens. I'm going to guess those are 100K-250K lines C++ [1], maybe? But then, a prize-winning 64k probably does a little bit more than a basic partial Minecraft engine :-P
Since you're asking "how do their minds work?", maybe I can get a little bit obsessive over this optimizing (wouldn't call it OCD--that would trivialize the disorder), but I do really get a slight "mind itch" if I notice code with duplicate functionality.
[0] Sometimes it doesn't. But often there's other advantages, too. If that's not the case either (or I'm on a deadline), I grit my teeth and write the duplicate code, but I try to make it really obvious that it is duplicate. That way at least it'll compress well :P
[1] Not even the 4K demos use pure assembly any more, compiler tricks and exe packers have become amazing in the past decade since I stopped making them. Not counting the external procedural/generative design tools/Werkzeuge, btw.
For example the scala compiler + standard library:
find src -name "*.scala" | xargs cat | wc -l = 244,601 git log --format="%an" | sort | uniq | wc -l = 149
That is, I would write something in the first, most-obvious way that occurred to me. Then, recognizing patterns, I would refactor it down to something smaller. Usually this repeated a few times, until the 100ish lines of code I wrote turned into 10 or 20.
Python gives a programmer a lot of help in reducing redundant code. It makes C#/Java/etc. feel really tedious with all of the boilerplate code you end up writing.
tl;dr: DRY
There are many features notch promised when the project first started that where never acted upon, and there's definitely still demand for those.
Got this error though. Any ideas?
OSError: dlopen(/System/Library/Frameworks/QuickTime.framework/QuickTime, 6): no suitable image found. Did find: /System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture /System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture
"arch -i386 python main.py" solve the problem for me.
slunk's suggestion:
`arch -i386 python main.py`
got me halfway there
You also have to run it with python 2.6 like so:
`arch -i386 /usr/bin/python2.6 main.py`
If you only have pyglet for 2.7, you will have to install it for 2.6. Installing packages in python for 2.6 will require pip-2.6 which you get like this:
`sudo easy_install-2.6 pip`
then
`pip-2.6 install pyglet`
Walla!
sudo pip-2.6 install pyglet
After that it worked perfectly. Thanks!
arch -i386 /System/Library/Frameworks/Python.framework/Resources/Python.app/Contents/MacOS/Python main.py
Someone should update Pyglet... Why does it need QuickTime?
1. 80% of the bang takes 20% of the time
2. Writing games is 99% fine tuning and game play
3. It's just a rendering exercise, certainly not a "clone"
FYI: The above is "the internet" in three lines! :-)
[rant mode off]
To prove a point, I wrote a minecraft clone in about 60 lines of code (10x less than the Python version). It cuts a few more corners (no textures, no gravity), but has the basics of world generation, rendering, and most importantly, adding and removing blocks in front of the crosshairs to build (see the little arch I made in the middle):
http://i.imgur.com/ZZWFkXn.jpg
It's written in Lobster in about 1.5hrs, which is quite similar in features to Python + pyglet. Yes it uses a few high level calls like simplex() and camera_FPS_view(), but these have been part of the Lobster standard library for a while, so I believe that's fair. All code I created for this demo are in that screenshot.
I started with python. I've had lots of problems with it, but I'm far stronger in python than anything else, so have been in a sense stuck on it despite separate attempts over the last twelve months to get to momentum in C, C++ and racket.
During the recent 7-day roguelike challenge I found myself still stuck on my old python codebase, now creating DSLs in order to define entities and relationship opportunities between them (e.g. water -> planted_seed = sapling). I found I was able to significantly reduce code size, it's cleaner, and it's far sturdier. That was the point where I realised I needed to drop everything and make the jump to scheme, which I've been doing since.
This derailed my 7-day roguelike effort a couple of weeks ago, but it's progress.
OT, but another benefit I've found is that it's trivial to write zero-dependency, multiplatform code in racket. "raco exe main.rkt".
Whereas getting that done with with python is fiddly. With the previous game I released, I spent more time trying to get exes for the major platforms than I did on everything else combined.
SimPy looks interesting, it would definitely be a more "pure" approach than scripting RePast. http://simpy.sourceforge.net/
I tried making a Settlers game in Python/PyGame and so far all I have been able to do is generate the board: https://gist.github.com/sareon/5268205 - I've been told I am not properly discretizing the difference between the drawing of the game and the logic of the game which is going to hinder the development of the game.
I have a BSc and an MSc in CS - focusing on NLP and Machine Learning, so I have an idea how to program, just not how to program games like the Minecraft clone or my own Settlers game. I've tried looking for tutorials and resources online and I've followed the InventWithPython which showed me how to make a simple game similar to how I started making my own. Clearly it was inefficient for a larger game.
What are some good resources out there that can help me learn how to make games such as the Minecraft clone or even how to make my own settlers game actually be a useable game?
Could performance be significantly improved by doing a re-write in Lua, for example? (Probably not... it's probably something in Pyglet itself...)
(FWIW, it's choppy compared to Minecraft, which is obviously much more complex and has a greater rendering distance.)
Also, keeping angles in degrees means you have to convert to radians on every iteration. It is easy to get rid of that. That will be a tiny, tiny speed up, but if you want to get top speed, you will eventually have to make many of those.
Almost every such improvement in speed will come at the cost of code readability and maintainability.
So is this something that can be "fixed" without diving into Pyglet?
If you want the utmost speed, you get it where you can get it the easiest. I bet the other code also can be sped up.
I would expect that the major improvements would be in main.py, though. That Pyglet library would have to be really bad to screw up what main.py does.
elif symbol == key.SPACE:
if self.dy == 0:
self.dy = 0.500 # jump speedself.dy = 0.050 # jump speed
Jump higher for more fun...
Not the jump thing. But the whole class of things there is something you don't like and can more or less instantly find it, tweak it and see changes. No hours of learning, searching through code, waiting on compilers. Just experiment -> fun -> back to experiment.
http://www.amle.org/Publications/RMLEOnline/Articles/Vol29No...
"participants limited TV, computer and video games, music, and telephone time to 30 min per day; in the time made free thereby, they were to read, sit quietly, write in their journals, meet with friends, and so on"
Calling that "boredom", says more about whoever wrote the title "Why Kids Need To Be Bored" than it says about kids' performance and boredom.
Then, the result of this study seems to be: out of 3 participants, 1 showed improvement, the other 2 dropped out. No data on 2 out of 3 test subjects, really, statistically proves nothing at all. It could go either way, or completely different. And it's bad science to not clearly point this out in the abstract. There's no shame in a failed experiment, but there is a lot of shame in pretending that it shows a trend that you didn't actually measure.
I'd be very surprised if research points out that more boring study material leads to improved results. Actually, with N=1 I won't be surprised no matter what.
poxel rendering like in the python scribble is trivial, there many much more interesting problems to solve, like managing the geometry. If anyone is truly interested they should begin here: http://0fps.wordpress.com/2012/07/07/meshing-minecraft-part-...
building penises out of dirt right now.
I find this comment a bit distracting, and in poor taste. Everybody knows real minecraft users build castles. building castles in the sky.Just grab Pyglet trunk and install it, and run main.py with pypy instead of with CPython.
* You need Python2 virtualenv,
* You need to install `pyglet` in it,
* Start it with `bin/python main.py`;
This proves Python's ability to be RAD.