Contribution ideas - more GAME samples!

Most of the code is grouped by function now. Although far from done. I’ve purposely ‘over refactored’ to get all the logic grouped so I can better clean it up tomorrow. But some structure is starting to come out of the noise.

Here’s the new main class:

from direct.showbase.ShowBase import ShowBase

import random
import os
import math

from ralph_helpers import ui, input, physics, scene, camera

class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # Set the background color to black
        self.win.setClearColor((0, 0, 0, 1)) 

        self.scene      = scene.RalphScene(self)        
        self.ui         = ui.RalphUI()
        self.input      = input.RalphInput(self)        
        self.cameraMgr  = camera.RalphCameraMgr(self)
        self.physics    = physics.RalphPhysics(self)

        taskMgr.add(self.move, "moveTask")

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

        self.input.update(dt)      
        self.physics.update(render)
        self.cameraMgr.update()

        return task.cont

demo = RoamingRalphDemo()
demo.run()

Sample runs as is written (although work not done):

It’s an interesting process that you have! I am curious to see how it turns out in the end. :slight_smile:

(And won’t comment on it in its current state, since it’s work-in-progress; there’s little point in comment when I don’t know what’s temporary and what’s intended to stay!)

[edit] Actually, one or two things, if I may: The commit-notes on one of the folders indicate that a CollisionSphere and CollisionHandlerPusher have been used, but I don’t seem to be finding them browsing the source. Now, I am tired right now, but I’ll confess that I’m also finding the structure a little counter to my personal intuition. So am I just looking in the wrong place/missing it, or has it not been added yet?

[edit 2] But see my second edit in a later post, below, which addresses that confusion.

I am a different person by nature, I will comment: this looks like an example of how not to do it.

I don’t think that it’s inherently bad, just as I don’t think that the functional style is bad. Different paradigms will work for different people.

This is my style when I started programming, from the point of view of code reuse, it’s just a dead end.

Bear in mind that they did say that they’d “over refactored” as part of their process–let’s see what the code looks like when it’s done.

[edit] On this forum, we often have bears in mind. :stuck_out_tongue_winking_eye:

[edit 2] Ah, regarding my confusion above about a changelog that mentions CollisionHandlerPusher, I’ve just noticed that said changelog is not part of the new changes, and is in fact much older. I still find it curious that there’s indication that the collision-approach was changed while the code seems to indicate otherwise, but that’s not relevant to this new set of changes. My apologies!

@Thaumaturge is absolutely right here!!

Interesting side note - I could put the split-out classes back into the main module and there would be an equivalent sample to before, but still have code that is cleanly organized by function. I still feel even there it is infinitely easier to understand than the original, even though its still incomplete.

But I’m not doing that yet - why? There is still a lot of cleanup needed. Going back to coding principles from above -

Single-Use: Now that the logic is split into multiple components, most components are closer to single use. There is one grave violation here, in that the modules all rely on Ralph’s scene graph layout. This isn’t necessary - most only need a single node (like Ralph himself) as a reference, so next on my list is to remove this dependancy.

Open-closed: Every component violates this right now. I can’t for example configure the ‘input’ logic for a different set of keys. Or physics for a different scene layout. Changes are needed here to fix this clearly.

Loose coupling - we’re definitely not there. Ralph needs all these modules to function, if I removed any of them the sample would break, and I can’t swap any module out for another easily. Conversely all modules rely on the main application class to have a specific scene graph layout, this is also too tight of coupling.

Lots to clean up yet :slight_smile:

Don’t sound so surprised, I’m posting on a forum as I go specifically so that the thought process is a community effort, feel free to recommend other approaches, I promise that I’ll listen!! Note most of the things being done here were discussed in prior posts, I feel the work is in-line with what we had agreed to.

Panda samples should be representative of what the Panda community feels is right, please give any ideas you might have!!

One question I do have - is in how to handle N-number of nodes in a scene that have movement and collision. N could be several or several million - depending on the size of the scene. Does Panda have any mechanics for organizing the collision logic here? I normally always have to use octrees, quadtrees, or precomputed physics zones to optimize this for real time use. Has this been worked out in Panda yet? I’d like to add a sample that shows multiple moving bodies - so trying to think this ahead.

Thanks,

-Sal

Hmm… In all fairness, I think that I recall one person agreeing with you, and others in whole or in part disagreeing. ^^;

I’m not sure of several million–having that many individual nodes would likely overtax the system if you don’t start doing some fairly fancy stuff, both on the collision side and the rendering side, I think.

Having several, however, is fairly feasible at the least.

I’m not sure of Panda’s internal handling, but I imagine that it has some degree of broad-phasing. In addition, it provides bitmask-based collision filtering, and an “active-object”/“static-object” dichotomy to reduce the number of collision-sources.

The outcome is that for most games, the dev needn’t worry too much about octrees and the like, I suspect. The main things tend to be to limit the number of “active” objects present at any given time, and to use bitmasks to limit what interacts with what.

For a simple implementation of this, let me suggest taking a look at the final game built up by my “Beginner’s Tutorial”–that should show one approach to handling collision using the internal collision system. You should find the full code here:

Regarding the “active object” vs. “static object” split, I recommend looking at this page, starting with the second paragraph:
https://docs.panda3d.org/1.10/python/programming/collision-detection/collision-traversers

For high-performance physics with a greater number of elements, it may be better to use Bullet.

Update, just pushed a fix, world collision works again, and strangely enough the sticking bug disappeared still. Something about not using the app-local cTrav fixed it.

There was a lot of debate for sure! But I think I responded to each point with a solution until consensus - if you find I missed any let me know! Definitely not my intention!!

This is awesome stuff, thank you =)

Heh, honestly, the thread is large enough that I doubt that I would find either consensus or dissent–indeed, I just looked back now to that effect. ^^;

I’m thinking mainly of the SOLID thing; as I recall, I agreed with the “L”, but not with the rest–but in all fairness didn’t pursue the matter much.

As to Ralph specifically, I’m standing by seeing how the code turns out in the end. As last I saw it, I wasn’t a fan of the style (as I mentioned), but there’s no point in commenting either way on something that is explicitly intended to be reworked!

It’s my pleasure. :slight_smile:

Right - we agreed to not follow it literally. It was only useful as some guidelines to help improve code ‘only’ where applicable. I haven’t deviated from that, I promise =) But if I appear to have violated this let me know for sure. I’ll reconsider.

For sure! Ends might justify means here. That being said, you’re really helping the end product be a much better one, thanks for all the support! (And being so open minded to new ideas!!)

In all fairness, I’m pretty tired right now, so my thoughts may be off-track!

[edit] Thinking about it, I don’t think that we had consensus on the exact coding style–but I also don’t think that it was directly discussed, and thus that there was also no dissent. However, again, I might be mistaken!

Per SOLID I was referring to this discussion:

After which you’re correct, there wasn’t any dissent. I assumed we wrapped on it. But happy to consider any additional code design ideas at all.

I just awoke, my morning here - so I’m likely to be at this a while. Feel free to rest up! We need our local Thamaturgist healthy! :slight_smile:

1 Like

Mmm… Perhaps it would have been better that we had discussed it more!

But in all fairness, I’m not sure that I saw SOLID leading to quite this code-style–but conversely and again, since this is a work in progress, I don’t really know what style is is leading to.

Thank you! :slight_smile:

It’s still early-ish here, so it’s a while before I sleep, but it is a day of rest for me nevertheless. :slight_smile:

We are in a better place now for perspective, I did jump into some Panda sample code to work with it more seriously (previous were cursory reviews).

I really did struggle with Ralph. Honestly - and I’m not a junior programmer, I promise. Now after a little code cleanup I feel a million times more productive. Thinking of this as an experiment, a new user working with a Panda sample of a ‘slight’ bit more complexity than your standard ‘Hello World’. I’m happy to be the guinea pig here =)

After applying some of the very basic concepts of best practices to the sample, it’s like night and day for me in terms of ease of use, understandably.

It’s just something we should consider in the design of slightly-more-complex samples like Ralph (which is my goal with this thread, hopefully to create several of these!!)

If I’m following you correctly, then I do agree in principle! Roaming Ralph was not a great sample, I fear. (Why, oh why did it use that “stop and reset position on ray-hit” method of obstacle collision?! T-T)

Having samples that are clear for new devs seems like a very good idea!

Just to check, are you saying that your reworking of the code is in its final form? (At least in general terms, if not fully bug-free and polished.)

No not close to done yet with the re-vamp. But I’ll definitely be super transparent through the process so it moves in the direction we feel appropriate. (No need for surprises) I can multitask - if folks would like to recommend ideas for the path forward, I’ll listen, for sure.

(If I just wanted to do things my way, I wouldn’t be on this forum, lol!)

Ah, fair enough!

Looking at the code… I’m waaay too tired to review properly now, I’m afraid! So my own comments will perhaps wait until either I get a second wind later, or another day, perhaps tomorrow! ^^;

[edit] One thing that interests me is that it feels almost like a functional style of programming, but implemented using classes.

No problem at all, you’ve already contributed a significant amount!!

For what it’s worth, things are going to change in the code /drastically/ as time goes on, so its OK to wait to see a more indicative structure of any final form.

I could also document/outline all the future plans here - but I figured folks probably just prefer to see code for discussion, too much computer-science theory can make folks a bit weary-eyed, so I’m taking the ‘code as an example’ approach, if that makes sense.

1 Like

I think that that makes good sense, indeed!