Notifications
Clear all

To all SSC Station occupants

Thank you for the donations over the past year (2024), it is much appreciated. I am still trying to figure out how to migrate the forums to another community software (probably phpbb) but in the meantime I have updated the forum software to the latest version. SSC has been around a while so their is some very long time members here still using the site, thanks for making SSC home and sorry I haven't been as vocal as I should be in the forums I will try to improve my posting frequency.

Thank you again to all of the members that do take the time to donate a little, it helps keep this station functioning on the outer reaches of space.

-D1-

UncleBob's annoying API questions

Page 2 / 3
 robn
(@robn)
Noble Member
robn wrote:
Github. I have a terrible memory - I may not remember this thread in the morning. If its in the issue tracker then it can't be ignored 🙂

Yep, that's an admin power. We'll take care of that. Cheers 🙂

ReplyQuote
Posted : October 30, 2011 12:36
(@unclebob)
Estimable Member

Ok, another problem just poped up. Probably just some misconception of mine.

I'm trying to code the Info-broker for my bounty hunts, and I want them to be consistent. There's one broker per system, and he should always be the same (look the same, same name).

I thought this should be easiest by just taking the seed of the first body in a system, as that should be consistent. However, for some reason, my brokers are always different. Here's what I tried to do:

Code:
local makeInfoBroker = function (station)

local mBodies = Game.system:GetBodyPaths()
BrokerRand = Engine.rand:New(mBodies[1]:GetSystemBody().seed)

local Broker = {
Gender = BrokerRand:Integer(1) == 1,
Name = NameGen.FullName(Gender, BrokerRand),
faceseed = BrokerRand:Integer(),
flavour = BrokerRand:Integer(1,#broker_flavours),
careful = BrokerRand:Integer(1, 10),
knowledge = BrokerRand:Number(0.1, 0.9) * Game.system.population,
}

GlobalBroker = Broker
BrokerAdd = string.interp(broker_flavours[Broker.flavour].adtext, {
name = GlobalBroker.Name,
})

local ref = station:AddAdvert(BrokerAdd, OnBrokerChat)

end

ReplyQuote
Topic starter Posted : November 17, 2011 11:15
(@brianetta)
Prominent Member

Why not use a character sheet?

Documentation of the API

An intro into their use

These are available in the nightlies and in master. I wrote the system, so feel free to throw questions my way!

ReplyQuote
Posted : November 17, 2011 12:24
(@unclebob)
Estimable Member

i did take a look at that, actually. Problem is, if i'm going to have one broker per system, it doesn't look like an option, there's too many. I could have fewer of course, but then i'd have to define spheres of influence...

ReplyQuote
Topic starter Posted : November 17, 2011 13:11
(@brianetta)
Prominent Member
UncleBob wrote:
i did take a look at that, actually. Problem is, if i'm going to have one broker per system, it doesn't look like an option, there's too many. I could have fewer of course, but then i'd have to define spheres of influence...

Too big? No. They're actually not any bigger than the table you're using. All the extra features and unused defaults are dynamically called from the original Character class object. How about this small modification?

Code:
local makeInfoBroker = function (station)

local mBodies = Game.system:GetBodyPaths()
BrokerRand = Engine.rand:New(mBodies[1]:GetSystemBody().seed)

local Broker = Character.New({
female = BrokerRand:Integer(1) == 1,
name = NameGen.FullName(Gender, BrokerRand),
faceseed = BrokerRand:Integer(),
flavour = BrokerRand:Integer(1,#broker_flavours),
careful = BrokerRand:Integer(4, 64),
knowledge = BrokerRand:Number(0.1, 0.9) * Game.system.population,
})

GlobalBroker = Broker
BrokerAdd = string.interp(broker_flavours[Broker.flavour].adtext, {
name = GlobalBroker.Name,
})

local ref = station:AddAdvert(BrokerAdd, OnBrokerChat)

end

All I did was turn your table into a Character. You can treat it exactly like any other table. The changes I made were Gender=>female and Name=>name (which lets you throw this table at ChatForm.SetFace() directly) and changed the range of careful so that you can do Broker:TestRoll('careful') whenever you need to do a carefulness test.

Play with it. Get the Lua console up and try things like this:

Code:
B1=Character.New({careful=25})
B2=Character.New({careful=40})
print(B1:TestRoll('careful'),' ',B2:TestRoll('careful'))

That last line, you can repeat lots of times using up and return. You should see that B1 ("Broker 1") generally fails his careful test a lot more frequently than B2. You'll see a lot of this:

FALSE TRUE

...with occasional other results scattered through.

ReplyQuote
Posted : November 17, 2011 13:34
(@brianetta)
Prominent Member

Of course, we set the default "careful" there rather naively, but that was just because I can see that you wanted to use your predictable random generator. It'll work, but you're more likely to see extremes of carefulness and uncarefulness. Better would be to rip off the code in the DiceRoll() function in Characters.lua:

Code:
DiceRoll = function ()
return ( -- 4xD16, range is 4..64 averaging 34)
Engine.rand:Integer(1,16)
+ Engine.rand:Integer(1,16)
+ Engine.rand:Integer(1,16)
+ Engine.rand:Integer(1,16)
)
end

and replace the four calls to Engine.rand with your BrokerRand. This will weight the results toward the centre, making TestRoll() give much saner results.

ReplyQuote
Posted : November 17, 2011 13:42
(@unclebob)
Estimable Member

thanks,

The reason why I thought that the sheets were not usefull for my purposes was not because I thought they were too big, but because I was under the impression that they have to be stored somewhere in the savegame once created. I take it that was a misconception?

Anyways, I'm leaving on a two weeks work trip today, so I'll have to get back to this afterwards...

ReplyQuote
Topic starter Posted : November 17, 2011 22:08
(@brianetta)
Prominent Member
UncleBob wrote:
The reason why I thought that the sheets were not usefull for my purposes was not because I thought they were too big, but because I was under the impression that they have to be stored somewhere in the savegame once created. I take it that was a misconception?

Like any table, they can be saved, but they do not have to be. Your strategy of predictably re-creating them as needed is sound. One of the big benefits of using a character sheet is that you could, at some point, put a new broker into the bulletin board of a station, and release the old one into the persistent pool to be used by some other script that you wrote. Perhaps he might become an assassination target? The possibilities are endless.

ReplyQuote
Posted : November 18, 2011 00:47
(@unclebob)
Estimable Member

Ok, I'll switch to using your character sheets, then. After I get back, that is...

ReplyQuote
Topic starter Posted : November 18, 2011 02:10
(@unclebob)
Estimable Member

I'm back from my trip, and back with the same old problem it seems. I downloaded Alpha 17 and changed my code to use the new character sheets. Only bare bones currently because first I have to get the thing to work propperly.

Code still looks very similar:

Code:
local makeInfoBroker = function (station)

local mBodies = Game.system:GetBodyPaths()
BrokerRand = Engine.rand:New(mBodies[1]:GetSystemBody().seed)

local Broker = Character.New({
female = BrokerRand:Integer(1) == 1,
name = NameGen.FullName(female, BrokerRand),
seed = BrokerRand:Integer(),
})

GlobalBroker = Broker
BrokerAdd = string.interp(broker_flavours[1].adtext, {
name = GlobalBroker.name,
})

local ref = station:AddAdvert(BrokerAdd, OnBrokerChat)

end

Code:
local OnBrokerChat = function (form, ref, option)

form:Clear()

if option == -1 then
form:Close()
return
end

if option == 0 then
form:SetFace({ female = GlobalBroker.female, seed = GlobalBroker.seed, name = GlobalBroker.name })
local introtext = string.interp(broker_flavours[1].introtext[Engine.rand:Integer(1,#broker_flavours[1].introtext)], {
name = GlobalBroker.name
})
form:SetMessage(introtext)
end

end

There are two problems: First, the character isn't consistent. It is different every time I start a game, so I'm doing something wrong when getting the seed from the first systembody, because that should be constant. Or I'm doing something wrong when using the seed?

The other problem is that the name isn't even consistent within the same add! The introtext shown on the BB shows another name than the individual has when the add opens, even the gender isn't neccesarily the same. This smells like somehow, the character doesn't even get stored in GlobalBroker, although GlobalBroker is defined as a local right in the first few lines of the file, before any functions are declared. I don't get what's going on here...

ReplyQuote
Topic starter Posted : December 10, 2011 06:54
(@brianetta)
Prominent Member

This is your problem:

Code:
local mBodies = Game.system:GetBodyPaths()
BrokerRand = Engine.rand:New(mBodies[1]:GetSystemBody().seed)

Engine.rand is an instantiated Rand. Use Rand instead, and use a full stop instead of a colon - you were passing Engine.rand's ID (probably junk) to the New() method instead of your seed.

Try this instead:

Code:
local mBodies = Game.system:GetBodyPaths()
BrokerRand = Rand.New(mBodies[1]:GetSystemBody().seed)

Also, does it need to be that seed? Isn't Space.GetBody(1).seed also perfectly predictable?:

Code:
BrokerRand = Rand.New(Space.GetBody(1).seed)

Also, you're sort of abusing the Character for SetFace in the second bit of code that you pasted. This:

Code:
form:SetFace({ female = GlobalBroker.female, seed = GlobalBroker.seed, name = GlobalBroker.name })

can be written very simply like this:

Code:
form:SetFace(GlobalBroker)

The Character sheet already contains all the right fields for SetFace. Your code was really just making extra work for Lua.

ReplyQuote
Posted : December 11, 2011 15:36
(@unclebob)
Estimable Member
Quote:
Engine.rand is an instantiated Rand. Use Rand instead, and use a full stop instead of a colon - you were passing Engine.rand's ID (probably junk) to the New() method instead of your seed.

ArglBargl!

Give me a pedantic language with clear type and method declarations any day! I just don't yet get the mysterious ways in which LUA moves... 😕

Quote:
Also, does it need to be that seed? Isn't Space.GetBody(1).seed also perfectly predictable?:

Well, now that I know of it, it looks like it should be, yes! 😀

Quote:
The Character sheet already contains all the right fields for SetFace. Your code was really just making extra work for Lua.

Making extra work is the specialty of any n00b... 😉 I didn't know that SetFace can receive a character object as a parameter, it's not yet updated in the API docs.

Thanks a lot for your help, this should get me a bit further.

ReplyQuote
Topic starter Posted : December 12, 2011 01:37
(@brianetta)
Prominent Member
UncleBob wrote:
I didn't know that SetFace can receive a character object as a parameter, it's not yet updated in the API docs.

It's in the Character doc. The Character object is basically just a Lua table (with applied phlebotinum).

ReplyQuote
Posted : December 12, 2011 02:04
(@unclebob)
Estimable Member

Say... can it be that the face generator screws up gender every once in a while? Now that the thing works, I have a certain Dan Carpenter as Infobroker of the Sol-system, and he looks more female than Micheal Jackson at his worst... I guess men in his position can allow for a little extravagancia, but it's a bit... disturbing. Then again, it IS the 33rd century...

ReplyQuote
Topic starter Posted : December 12, 2011 12:15
(@brianetta)
Prominent Member
UncleBob wrote:
Say... can it be that the face generator screws up gender every once in a while? Now that the thing works, I have a certain Dan Carpenter as Infobroker of the Sol-system, and he looks more female than Micheal Jackson at his worst... I guess men in his position can allow for a little extravagancia, but it's a bit... disturbing. Then again, it IS the 33rd century...

No, that's you again, I'm afraid...

Code:
local Broker = Character.New({
female = BrokerRand:Integer(1) == 1,
name = NameGen.FullName(female, BrokerRand),
seed = BrokerRand:Integer(),
})

In this snippet of yours, you use female as an argument to NameGen.FullName; trouble is, this is all within a table def, so the definition of female that you've used isn't in scope. You need to define female outside of that table definition as a (very local) variable, then use it to define both Broker's "female" and as the argument to Broker's name gen.

Code:
local tempbrokerfemale = BrokerRand:Integer(1) == 1,
local Broker = Character.New({
female = tempbrokerfemale,
name = NameGen.FullName(tempbrokerfemale, BrokerRand),
seed = BrokerRand:Integer(),
})
ReplyQuote
Posted : December 12, 2011 13:35
(@unclebob)
Estimable Member
Quote:
In this snippet of yours, you use female as an argument to NameGen.FullName; trouble is, this is all within a table def, so the definition of female that you've used isn't in scope.

Aaargh!

The brackets! mind the brackets! Lest you forget that you're initializing an object and not assigning variables in a function!

Now I'll repeat that a hundred times, and maybe I'll even remember it 😕

aaaand the official Information Broker for the Sol system, the spider in the web, the fly on your wall, the ears you can't see, is: Rosie Carpenter. Seriously, Rosie?? sometimes I hate procedural generators and their complete lack of dramatic flair... 😆

ReplyQuote
Topic starter Posted : December 12, 2011 23:18
(@brianetta)
Prominent Member

Admit it, that's inspired. You'd never suspect Rosie.

ReplyQuote
Posted : December 13, 2011 00:14
(@unclebob)
Estimable Member

Just a question to make sure: When I save a character, do the additional attributes I added to the table get saved with it?

And another question, what values can I expect from a systems lawlessnes? 0 to 1?

ReplyQuote
Topic starter Posted : December 28, 2011 06:10
(@brianetta)
Prominent Member
UncleBob wrote:
Just a question to make sure: When I save a character, do the additional attributes I added to the table get saved with it?

Yes.

Quote:
And another question, what values can I expect from a systems lawlessnes? 0 to 1?

Erm... it's a "fixed," whatever that actually is. Expect a fairly large range of numbers.

ReplyQuote
Posted : December 28, 2011 14:51
 robn
(@robn)
Noble Member
Quote:
Quote:
And another question, what values can I expect from a systems lawlessnes? 0 to 1?

Erm... it's a "fixed," whatever that actually is. Expect a fairly large range of numbers.

Actually its a fractional number in the range 0-1, where (theoretically) 1 is raging hordes and 0 is a serene garden. Right now only pirate spawns really care about it. Its another of those political things that will change in time.

[Edit 7 Jan: I got 0 and 1 the wrong way around.]

ReplyQuote
Posted : December 28, 2011 21:40
(@unclebob)
Estimable Member
Quote:

Yes.

Great!

Quote:
Actually its a fractional number in the range 0-1, where (theoretically) 0 is raging hordes and 1 is a serene garden.

A serene garden where you get a deadly injection if you ruin a bed of flowers at the wrong time, I assume... 😆

So a high value in lawlessness actually means more lawfull... 😕 thanks for pointing that out.

I'll use it for making my InfoBrokers potentially less lawful in lawless systems, and also for making quaries hide out in more lawless systems.

ReplyQuote
Topic starter Posted : December 28, 2011 22:50
(@ollobrain)
Honorable Member

hidden pirate bases AI or player owned in lawful systems ? major hubs in the middle of nowhere

ReplyQuote
Posted : January 6, 2012 02:16
(@unclebob)
Estimable Member
Quote:
hidden pirate bases AI or player owned in lawful systems ? major hubs in the middle of nowhere

I can't quite catch your meaning. My only concern currently is to make information sellers more prone to selling ilegal information in lawless systems, as well as making hunted fugitives flee to more lawless systems. And later on probably give a better chance of getting an illegal bounty contract in a lawless system, but I have to get the basics first before extending too much...

Anyways, I played around a bit, and noticed that Sol has a lawlessness value of 0.13. Which is a lot lower than I expected, is it really still that bad on and around earth in the 33rd century?

ReplyQuote
Topic starter Posted : January 6, 2012 09:39
(@ziusudra)
Trusted Member

Hmm, the trade ships and pirates modules have always used the lawlessness value as though 1 is maximum lawlessness and 0 is minimum. See TradeShips:239 and Pirates:15. For trade ships a higher value reduces the number of trade ships. For pirates a higher value increases the odds of spawning a pirate.

See also Polit.cpp:135 where a high lawlessness value reduces the fine amount.

Looking at Polit.cpp:52-78, a value of 1 is maximum lawlessness and 0 is minimum. NO_CENTRAL_GOVERNANCE has a base value of 1, VIOLENT_ANARCHY has a base value of 0.9, and EARTH_FEDERATION_DEMOCRACY has a base value of 0.15.

So, it's the opposite of what robn said: 1 is raging hordes and 0 is a serene garden. A high lawlessness value really does mean more lawless.

ReplyQuote
Posted : January 6, 2012 10:56
 robn
(@robn)
Noble Member
Ziusudra wrote:
So, it's the opposite of what robn said: 1 is raging hordes and 0 is a serene garden. A high lawlessness value really does mean more lawless.

The joy of double negatives. lawlessness was always a stupid name for it. I borrowed it as-is from tomm's code, so blame him 😉

ReplyQuote
Posted : January 6, 2012 11:40
Page 2 / 3