Ambiera Forum

Discussions, Help and Support.

Ambiera Forum > CopperCube > Programming and Scripting
Subtitute node_name with a variable

Registered User
2023-09-02 12:56:45

When coding/scripting, is there a way to inject a variable into a coppercube command/function?

var sourceNode = ccbGetSceneNodeFromName("myNode");
var newscenenode = ccbCloneSceneNode(sourceNode);

If I wanted "sourceNode" to be a variable instead, how would i achieve that please?....


var newscenenode = ccbCloneSceneNode(var sourceNode);

Basically, I'm using mathrandom() to select random scene_node to build a rpocedural city by using "ccbCloneSceneode" - I just don't know how to add the generated random variables to coppercube's clone command.

I could probably use arrays too, just not sure how it would work.

Anyone got any pointers/tip for this please?

Thank you.

Registered User
2023-09-02 13:25:11

you can use array for that for sure..

var possible_nodes=[];

var sourceNode = ccbGetSceneNodeFromName( possible_nodes[ MathRND3 ] );

var newscenenode = ccbCloneSceneNode(sourceNode);

Do not add " " into a input.

you can use if statements for it also

if rndNumber=0 then sNode="house"
if rndNumber=1 then sNode="sleepwalker"
if rndNumber=2 then sNode="cube"

var sourceNode = ccbGetSceneNodeFromName(sNode);

var newscenenode = ccbCloneSceneNode(sourceNode);

2023-09-02 13:34:30


That makes sense.

Thanks for your help again SVEN really appreciate it.

2023-09-02 13:43:43

Hi VP,

the variable would still need to use a specific term, like:

var door=ccbGetSceneNodeFromName("door");

in order for you to be able to use it. Therefor you may be able to declare all these variables "before first drawing", just like that.

However, then you have the problem that in some of the script these variables may be unknown. Like in a special-execute javascript behavior.
Using ccbGetCopperCubeVariable to obtain the value of a variable that way across all scripts, is about as much a hassle as to get the node from the name.
And logically, this must be slow, as it really compares strings.

There is a way, you can use an array. Declare it in "before first drawing", then it can be accessed by all scripts.

nodelist=new Array();

now parse the scene in a "for i" loop and write the node handles to the array, using i as the index.
You can access individual list entries by:


Which is fast, but requires you to know and keep track on the index of the door etc.

If I'm not completely mistaken, I cannot simply declare a variable in "before first drawing" like:
and then have it accessible in all scripts, but I'm not a 100% sure, yet cannot check it right now, as the lightmapper is running.

Either way, arrays are global and allow to store the node meshes only once, rather than to string-compare them repeatedly, as described

2023-09-02 14:00:53

I see Sven was faster, and more on the subject.

2023-09-02 21:56:49

Thank you both! - I've got it working now with billboard place-holders. I just need to add the models and textures to make a city. The I can tweak it a bit more.

Seems to be really fast at the moment - entire city only takes around 10ms to generate (instant upon starting scene or pressing space to randimise all tiles) - but it's only a grid of 10x10 squares to test. It will probably slow down a bit when I add the building,water, vegetation and terrain model geometry and make the grid bigger (eg: 100x100 tiles).

I'll post a link when the 10x10 grid city generator is finished.

Nice one!

2023-09-03 18:49:50

Sounds great, VP, looking forward to seeing this in action.

BTW just had one of them huge Hah! moments. Turns out you CAN absolutely use global variables!

Simply declare in "before first drawing":


now you can access the variable there and also in other scripts, I just tested it in an action script extension, and in a behavior special-execute javascript window.

However do not declare var vp_test=whatever; in the other scripts, as that will create a local variable of the same name. But you can totally do this:
(that's in the "before first drawing")

and then you never have to get the node from the name anymore, but you can simply use the variable door, which represents that node directly.

Now I feel I was stupid :) What went wrong? I thought I tested this years ago ^^.

2023-09-03 19:32:27

Well, I knew something was bad. It's functions. You cannot declare a function in "before first drawing" and then use it everywhere. Like

function mytest()
alert("hello world");

will cause an error ("mytest() is not a function") when called in a special js window, other than the one in which it's declared.

However, I don't understand why variables work, and functions don't. Maybe this is inside a function already, and you cannot declare a function inside an other function. But then I'd expect a more specific error message. Anyway, for a moment I thought the sky is the limit ^^

Registered User
2023-09-03 22:43:13

Thanks Dieter. I tried all day to get a script to work but in the end I went back to non-code for now instead - it works but I really want to update/remake it with a script in the future, I just can't comprehend it at the moment. If I copy/paste the scripts, it just gives syntax error. I'm not clever enough to know what's wrong to fix it but I do generally understand the scripts by looking at them.


Here's the download for the basic city generator so far...
Click on the CItyGen download if you want to test it.

<Press Space To Regenerate City>

It's simply 100 tiles which spawn: water, land or building nodes.

There are 2 variations of each tile for now -

1= Water/Concrete
2= 1 tree/2 trees
3= House/Tower

The variations are currently being triggered by their proximity to the center of the map.

Next to-do is add slightly more variety of building/tree, random placing of a single headquarter/capital building (to access the first-person game), random rotation of all building (Y) axes, simple road/river overlay, dynamically change textures/assets depending on Country-code (grass/sand/concrete/jungle/Urban etc).

*Update - have added rotation for placement variety and have made 88 building models - just need to make a few different textures for each, then I can work on finishing it properly.

Once it's all working well (with different models and textures), I'll try to optimise it and make the city around 4-times bigger with more detail and ambient city-scape sounds. Placing several randomly chosen buildings on each of the hundred tiles is going to be a challenge. I might re-think it and see if I can find an easier solution.

2023-09-04 22:18:05

Looks fantastic! A great basis for big game.

2023-09-08 12:05:39

Thanks Dieter, I'm going to try to make an action for it to make it easier to do. "On Proximity to any node", rather than "On proximity to a specific node".

If I can do that, I'll then try to add a tag system to "on proximity" so I can control "on proximity" events using simple keywords, rather than node-names.

2023-09-08 17:45:07

You mean like handing over a tag string parameter to the action script extension? Sounds doable. Faster would be numbers, instead of tag strings. But that may insignificant for a generator.

I just used the node names as tags, because it was so convenient. I load door.b3d, hit ctrl-C a few times and get door1 to door7, which the action script deals with on click, without any parameters, real set-and-forget. Or I add locked, like door3locked.
Without further settings, the player will have to find key3 to open this door. I simply change the name attribute from door3locked to door3.

But this isn't comparable. Your project is a procedural world generator. I guess what it really boils down is the quality of the building blocks, and how seamless they are put together.

When placing multiple buildings one one square, prevent intersection / overlap.

Maybe by spacing them adequately when planting them one after the other, either on a line or a ring. Or you could even use the physics engine ^^

Then have a random number of the amount of buildings on a specific square. And when you deal with 88 different buildings, you really want to have them (or their node handles) in an array, then simply use a random index, like in Sven's first example, to randomly choose one. However, never use numbers like 4.67 as an index. but round them, like a=Math.floor(a); (else it errors out).

And you may remember my little 2D array tutorial here, that basically declares a Z array for each X array, allowing you to access the contents of a chessboard like:
currentSquare=board[x][z]; that might be useful too.

When it comes to generators, I try to follow the philosophy of "what would be happening" in the sense of: water would flow to the lowest altitudes. Trees would not grow on steep cliffs, nor would grass. However, reed would grow near the water, And so on. Of course, that's a terrain generator. But still. You have to see the history of the place. What happened, that shaped the city. That I think helps to make it more organic and coherent.

2023-09-09 01:02:07

Thanks Deiter, sounds good! I don't really understand coppercube well enough to be able to do that yet. I'm sure arrays are the best approach but I can't get it to work properly; it throws "not defined" syntax errors for the maths functions.

Instead, for now, I'm thinking of adding individual game-actor behaviours to each building. I think then I'll be able to use the "attacks who?" tags to design a system where the buildings and roads interact with each other, using predefined rules for rotation and position.

It imagine it will take a while for me to get it working this way.

Registered User
2023-09-09 08:02:39

When it comes to generators, I try to follow the philosophy of "what would be happening" in the sense of: water would flow to the lowest altitudes. Trees would not grow on steep cliffs, nor would grass. However, reed would grow near the water, And so on. Of course, that's a terrain generator. But still. You have to see the history of the place. What happened, that shaped the city. That I think helps to make it more organic and coherent.

I believe Dieter is talking about wave function collapse algorithm. I also think you can benefit of using it, even though it's a more advanced thing to implement.

You can find well detailed code along here:

2023-09-09 14:02:31

Yes, "wave collapse" is exactly what I'm hoping to do with the "on activate" tags. For me, a tag system will be a lot easier to implement than coding it.

In fact, that's how I got the 10x10 grid example is working - it's testing the tile content based on its distance from the center tile, before deleting multiple models - to leave just a single model per tile.

The advantage of tags is that it can test the neighbouring tiles directly with each other.

The thing that will take most time is creating 9x9 configurations for all the buildings (same procedure, just a lot more rules for a lot more variety). Then I can map their positions back to the 10x10 grid.

The tags will set rules for the placement and rotation of the buildings on individual 9x9 grids. It will be a parallel process (one for each tile) so it "should" be a lot faster than serial collapse procedures.

The video is good, I think he's over complicating it by using code. The function is a lot simpler than that in reality.

Create reply:

Posted by: (you are not logged in)

Enter the missing letter in: "In?ernational" (you are not logged in)




Possible Codes

Feature Code
Link [url] [/url]
Bold [b]bold text[/b]
Image [img][/img]
Quote [quote]quoted text[/quote]
Code [code]source code[/code]



Copyright© Ambiera e.U. all rights reserved.
Privacy Policy | Terms and Conditions | Imprint | Contact