
Pycraft: Minecraft engine in Python - danso
https://github.com/traverseda/pycraft
======
Negative1
I cringe when I see code like this: if len(vals) in range(1, 5):

It seems like a harmless enough thing to do but that code is effectively
creating a new array with values [1, 2, 3, 4, 5] and testing if the result of
len() is in that array by iterating over it. This check is happening multiple
times for each draw call every frame.

Sadly I see this kind of stuff in Python all the time and it just adds weight
to the argument that Python is not a performant language. 1 <= len(vals) <= 5
would have been more pythonic and certainly more efficient (and obvious) but I
have to wonder if under the hood it's just doing the same inefficient
operation.

~~~
simonw
Why do you suspect 1 <= len(vals) <= 5 would do something inefficient under
the hood?

You can actually get a very good idea for what Python is doing under the hood
using the dis module:

    
    
        dis.dis(lambda: 1 <= len(vals) <= 5)
          1           0 LOAD_CONST               1 (1)
                      3 LOAD_GLOBAL              0 (len)
                      6 LOAD_GLOBAL              1 (vals)
                      9 CALL_FUNCTION            1
                     12 DUP_TOP             
                     13 ROT_THREE           
                     14 COMPARE_OP               1 (<=)
                     17 JUMP_IF_FALSE_OR_POP    27
                     20 LOAD_CONST               2 (5)
                     23 COMPARE_OP               1 (<=)
                     26 RETURN_VALUE        
                >>   27 ROT_TWO             
                     28 POP_TOP             
                     29 RETURN_VALUE        
    

Compare to:

    
    
        dis.dis(lambda: len(vals) in range(1, 5))
          1           0 LOAD_GLOBAL              0 (len)
                      3 LOAD_GLOBAL              1 (vals)
                      6 CALL_FUNCTION            1
                      9 LOAD_GLOBAL              2 (range)
                     12 LOAD_CONST               1 (1)
                     15 LOAD_CONST               2 (5)
                     18 CALL_FUNCTION            2
                     21 COMPARE_OP               6 (in)
                     24 RETURN_VALUE

~~~
daveguy
It may be a shorter number of bytecodes, but that does _not_ mean it has
better performance.

You have two function calls in the range version and only one in the non-range
version. You are just hiding some of that code in a dynamic function call.
Also, your compare_op consists of two <= in the non-range version and an "in"
compare_op for the range version (which probably hides the element by element
comparison or hash/bloom if it is O(1).

Fewer lines of code does _not_ mean more efficient. Regardless of whether it
is source code or bytecode.

~~~
maxerickson
There's no argument made in the comment you replied to. Certainly not a
strident one in favor of range.

It appears to me they went ahead and posted the bytecode for both because they
had spun up an interpreter to get the bytecode for one.

------
thomaskcr
I've been teaching a class
([http://apprenticeworks.us](http://apprenticeworks.us)) based on the same
original repo it seems like you found. I made a lot of the same changes as you
as well. I ended up abstracting a lot of the "optimization" type code (the
sectors for example) and changed the way the state of the player is kept to
support multiple players in the future.

Not sure if you'd be interested, but I have some content I'd be happy to add
for background type information (i.e. degrees of freedom, calculating
movement, frames of reference, etc). Might make a good starting point for
contributors but not sure if that's the direction you see your documentation
taking.

~~~
traverseda
Just found this on hackernews now. Pull requests are _very_ welcome. I don't
personally have a lot of time to actually _code_ stuff, as I'm busy with
contracts, but if you post on our irc someone might be interested in digging
into your code base and pulling out the useful bits.

------
asimuvPR
I've always wanted to have an MC clone in Python with GUI event hooks to run
scripts. Like pull a lever and an email is sent sort of thing. Will this fork
allow for something like that? I'm not against adding it myself if allowed,
btw.

~~~
shmageggy
It's build on top of pyglet which is built around event-based programming, so
it's already got the ability to do low-level callbacks from key/mouse events
built in [1]. GUI widgets are a separate matter though and would probably
require a separate library to do OpenGL GUI elements on top of this.

[1]
[https://pyglet.readthedocs.org/en/pyglet-1.2-maintenance/pro...](https://pyglet.readthedocs.org/en/pyglet-1.2-maintenance/programming_guide/mouse.html)

~~~
asimuvPR
Reading the docs, thanks!

------
levemi
I like that it uses shaders and modern OpenGL and not fixed functions. It
looks like very good clean OpenGL!

------
sciurus
"Permissive policy on pull requests" makes me fearful for the long-term
maintainability.

~~~
traverseda
Compared to the original. We'll revisit that when we have something that
offers any genuine advantages.

A lot of people have been doing pull requests for unit-tests, documentation,
and continuous integration. So I'm not too worried.

We're setting up a policy for requests, but that policy is living in code.

------
personjerry
Now to write a Python interpreter in Minecraft for the infinite translation
loop...

------
willvarfar
I love python, but I wish this was a web/webgl app. Is there no way to run
this in the browser? :(

