For some months now I’ve been working on a game project I’ve half jokingly entitled “Intimidation” because that’s what I thought when I first started. :smiley:
Here is a temporary site I put together today: (Some screenshots are on the “Update” page.)
I suppose it is closest to an RTS, though not a pure one. A bad habit of mine is to include stuff from other kinds of games I like, and that’s what I’m doing here.

EDIT: One thing the site doesn’t mention: For dozens and dozens of units that I’m planning on, sorting through a bunch of collisions would be slow. So I’ve been improvising by using a radius “bumper” around a unit. It will stay in any terrain it can traverse, and I’m getting close to making it recognize bumping into a unit. So far it hasn’t given me any perceptible performance hit (though I haven’t tested with lots of units), so I’m pretty happy with it.

I threw together a very very quick video showing a bit of the Intimidation Project. Not sure if anyone wanted to look?

It regularly runs at 55fps, but the resource hungry screen capture program took off 20fps or so. A bit more info on the site.

both links dont work for me…

works fine for me

Hey bigfoot :wink:
May I ask why did you concentrate about carbage collector stuff ?
Python is suppose to do everything for us… Normally…

now they work again for me, too.

The garbage collection would be about the cyclic references combined with finalizer methods.

tallmystcarpet: I like to know everything and have control over a bunch of stuff. And also, I just didn’t understand how to delete stuff properly.

castironpi: I hate to display my ignorance, but I have no clue what you just said.

bigfoot, that’s just about all i know about it. anything beyond that is nearly impossible to concentrate on, at least for me.

tell you what. we needed one of these over in comp-lang-python too, so.

>>> class Blank:
...     def __del__( self ):
...             print 'in __del__'
>>> a= Blank( )
>>> del a
in __del__
>>> b= Blank( )
>>> del b
in __del__
>>> a= Blank( )
>>> b= Blank( )
>>> a.b= b
>>> b.a= a
>>> del a
>>> del b
>>> import gc
>>> gc.garbage
>>> gc.collect( )
>>> gc.garbage
[<__main__.Blank instance at 0x00A99E18>, <__main__.Blank instance at 0x00A99DF0>]
>>> gc.garbage[ 0 ].__dict__
{'b': <__main__.Blank instance at 0x00A99DF0>}

there are two key factors.

  • cyclic reference
  • has del method

otherwise there’s a consistent way to collect unreachable objects. (explanation deferred.)

Docs: … gc.garbage

Secondary: … ct.del


Thanks for that. I didn’t entirely understand, but I’m studying it anyway. Though if I did understand at least partly, then my code has no cyclic references. I believe I eliminated all of them some time ago, where A references B which references C which references A.

Yes, that’s my understanding as well.

The only other thing I remember from the docs, is that you can control when and how often the garbage collector runs, including forcing it with a call to gc.collect.

I always need them in my code, so good for you.

I remember saying someone suggesting a “playbook of subroutines” for the player’s own units. I think it was you castironpi? I’ve kept it in mind, and just how much easier (maybe too much), and perhaps more fun, it would make things for players. I can’t say I’ve actually done it, but I’ve tried to keep the code open to allow it being implemented later.

A couple of good strategies for workarounds they mention is the use of WeakReferences, from the ‘weakref’ module IIRC. I know you said you eliminated your cyclic references and I’m adding this anyway. We also have the WeakKeyDictionary and WeakValueDictionary. Support for weak references is not mandatory in 3rd-party objects, so participating locations only.

Reference to a weakref object fails once the object has been collected, if not earlier when its ref. count goes to zero, rather than keeping it alive. The code gets more complicated: (Untested.)

obj.meth( )


temp= obj( )
if temp is not None:
   temp.meth( )

The change is pervasive. But we are freed from cyclic references; ‘obj’ does not count as a reference to the original object. I haven’t seen this performed, but we could conceivably provide a uniform behavior if the reference is gone.

weakcall( obj, 'meth', arg1, arg2, kwarg= arg3 )

If obj is a member of a collection, we can just silently exclude it. The only provision for this currently is to hack-up a WeakKeyDic into a list; otherwise we will build or wait for WeakLists and WeakSets and so forth.

If obj is an attribute or variable then we will need to abort or have backup behavior. Remember Python’s Zen though:

Different packages offer different strategies for handling errors. ‘numpy’ will raise or drop an exception as you wish. The Python std. lib. has different functions for raising or dropping exceptions.

weakcall( obj, 'meth', arg1, arg2, kwarg= arg3, onerr= DROP )

By now we tread on ‘meth’'s signature, though, so we may need:

weakcall( obj, 'meth', onerr= DROP )( arg1, arg2, kwarg= arg3 )

Or we can pass the args and kwargs as a tuple and dict:

weakcall( obj, 'meth', onerr= DROP, args= ( arg1, arg2 ), kwas= dict( kwarg= arg3 ) )

We have our pick since we’re designing the ‘weakcall’ function ourselves. Advanced definitions could accept a dedicated object in the ‘onerr’ method, that defines a custom error-handling policy.

The only thing we can’t offload into ‘weakcall’ would be an assignment statement, and thanks to ‘setattr’ only strictly with present namespace variables. One day we will edit namespaces directly, as well as get an officially endorsed pointer to presently executing code, so we can just insinuate our assignment statement directly. 'Til then we just have hacks with which to make do for assigning out of a weakref to a variable.

Yes that was me, IIRC in your “I want feedback” thread. What does it have to do with weak references?

Nothing at all. Just saying that much much later on if I have time, I’ll play around with it.

I don’t know if you caught the suggestion I made. You can sort of do the thing I’m suggesting on the movie I posted last night, of the proc. gen. city scene.

While the scene is playing, you can do:

-->print Globals.atten
Point3(0.003, 0.003, 0.003)
-->Globals.atten= Point3( 0.001, 0.001, 0.001 )

on the console and then all new lights have the new attenuation rate. It just uses ‘raw_input’, a ‘Queue.Queue’, and a separate thread.

I just discovered that WeakSet is included in Python 2.7. … ef.WeakSet

Although it didn’t appear in the What’s New doc.

No, I didn’t catch the suggestion. I’m still going over what you wrote, thinking, and just sorting all the info out in my brain. Might be a while on that.

This post of mine shows a big change. This change has actually been in the planning stages for two weeks, and actually changed this past week. Yeah, I took someone’s advice from the other thread again.

I know it’s a tiny difference in Geometry Class, but visually it’s huge! Thanks for sharing and keep up the good work.