How to declare properties that have string value

i intend on just using the value. Not for comparison. More like assigning the value to in a gui.set_text(node, value) scenario.

I wanted to be able to pass a value from an external service and display it in a text element

1 Like

Yeah, you have to pass that as a message or perhaps keep the value you received from the external service in a look-up table and pass the index/id/key into that lookup table in factory.create() and look it up in the created object using the provided key.

3 Likes

Ic. Thats interesting. I certainly can use a global variable for this.
Is this a limitation that will be improved on in future iteration?

1 Like

Even better, store the values in a module and require that module. Something like in this example:

https://github.com/britzl/defoldexamples/blob/master/examples/factory_and_properties/factory.script

In the factory.script I add a string value to a lookup table and use a hash as a key. I then pass the key to the created game object and in the init() function of the created game object I lookup the string value again using the provided key.

6 Likes

There are no plans on providing that currently. @Ragnar_Svensson can perhaps explain the thoughts behind the design.

We steer away from strings in the runtime at all times since they are so problematic. A single string has no real impact on anything, but since they are so convenient for us humans they tend to rapidly populate the memory. In the worst case, you can end up with the most problematic of perf issues; when a lot of things take a little time each, summing up to a problem. It takes a really long time to fix issues like that. This is why we deliberately don’t support strings, to guide users towards working with hashes which are free from these issues.
The exception is obviously as you stated, when you want to display information to the player. The information comes from two sources, static (which often becomes localised and fits well in a string library) or dynamic from web services or other players. In the dynamic situation it still makes sense to keep these things in a separate data store and the thing to display stuff has a key into that store (like @britzl’s example). You might want to be able to supply place holder info in the absense of responses, etc.

8 Likes

This looks perfect and cleaner.

I understand what you mean. I’m unsure if these will always cover the scenarios though. Unfortunately this indirection doesn’t provide a smooth flow for a developer to transition to using defold. It seems developer would normally gravitate and expect to be able to do certain things and restricting this by design seems odd and should frankly be handled some fluid way (maybe define a custom string implementation that gives you the benefits of both worlds). But i appreciate the help.

Suppose I’m making a tutorial for my game, placing dozens of “info” signs near various tutorial levels and objects. They all look the same, but display different text when clicked. In Unity/UE4 you would just place the same prefab dozens of times, and then edit the property of each individual info sign, which is a string! Same for other game objects that look alike but display/say different texts, like NPCs with one-liners and unique names. How can I achieve this in Defold without creating a mess, like setting an int instead of a string, and then looking the actual string up from the int?

I’d use a hash as property and use that to lookup a string from a dictionary (table). This is really the way to go, especially if you plan to translate the text in your game.

4 Likes

I’m creating a lot of texts, infos, names, etc in the way guys are describing here :wink: it is very convenient, when you want to change some text or in translating. You can create a Lua module that would store every usage combination like:

M.TOUCH = 1
M[1] = hash("touch")
M.string[M.TOUCH] = "touch detected"

Then you don’t need to remember the correct number, proper string or hash, but only a mnemonic name and use it anywhere.

if action_id == btn[btn.TOUCH] then
    print(btn.string[btn.TOUCH])
end

if k == btn.TOUCH then... end 
for i =1,2 do print(btn.string[i]) end

Or in localisation:

M.string[M.touch].eng = "touch the screen" 
M.string[M.touch].pol = "dotknij ekranu"

I would even make M.eng and M.pol a number to use it like this:

curr_lang = btn.eng
print(btn.string[btn.TOUCH][curr_lang])
9 Likes

This is good to know. I’m using strings all over the place. Looks like I have another “rewrite everything” deal ahead of me.

2 Likes

Unfortunately, the link no longer works. Can you or anybody else provide an explanation of how to do this that won’t suffer from link decay?

Have a look here: https://www.github.com/britzl/defoldexamples/tree/master/examples%2Ffactory_and_properties

Sorry to dredge up an old discussion, but this has me a little puzzled. The string implementation is not applied because of performance? But all strings in Lua are hashed. Even when you concat a string, it is hashed - there are no direct string manipulation ops on just maintaining strings. If people want to run gsubs, or matches, then thats a functional issue, not a resource one.

This leaves me wondering why this feature would be skipped - seems to be a nice-to-have. In my case, being able to have simple get/set props on certain go’s would be very useful without a msg merry-go-round (which is actually far less performant btw - having to wait for update for completion).

Could someone explain this better. I feel like maybe Im missing something obvious. Do strings get sent up the SDK API? Because that would then make a little more sense, but kinda not :slight_smile: … since ‘why’ comes to mind :slight_smile:

To explain my thinking a little. There is care about performance of strings, but much of the SDK uses Lua api calls (vmath a classic example) where if you call alot of vmath functions you will create the same “string” styled issue. If you use a Lua based one, the perf probs go away (I have a lua verlet physics test that does exactly this). And so, I think (personally) it might be a valuable feature to have string properties (I think it makes it also a little more consistent).

End Dave Rant. :slight_smile:

[ additional q ] What would be the appropriate method for “getting” text associated with a game object that has been generated in the game object (not for display btw - for data reasons). How would you attempt this via a message? ( req → resp? )

1 Like

The reasoning comes from place where games do an inordinate amount of string based stuff.
Stuff that isn’t easy to optimize at the end of the project.
Therefore, we try to keep that gate closed unless absolutely necessary (or the situation is well defined and small enough).

There is care about performance of strings, but much of the SDK uses Lua api calls (vmath a classic example) where if you call alot of vmath functions you will create the same “string” styled issue

There are many areas in the engine that could use more care and probably some optimizations. I hope we can get to work on those areas too.

[ additional q ] What would be the appropriate method for “getting” text associated with a game object that has been generated in the game object (not for display btw - for data reasons). How would you attempt this via a message? ( req → resp? )

For text associated with a script, I’d use hash properties, e.g. go.property(“TEXT_ID”, hash(“TEXT_ID_BOSS_NAME”)).
That way I can look up the localisation in another Lua module depending on currently selected language.
E.g. something like this:

local go_text_key = hash("TEXT_ID")
...
local text_key = go.get("#script", go_text_key)
local text = localization.current_language.texts[text_key]
4 Likes

I need the text as original text at the other side of the get (its string based data - think similar to utf8 but not used for textual output). Turning it into a hash obviously isnt ideal :slight_smile:

Also in this example would go_text_key need to be a property? Or is this in a module (like above) ?
I dont mind using modules, but I kind of would like to be able and cut and past the string between objects in the editor - this data is coming from Blender btw, so this is a very very very … edge case :slight_smile:

[ note: ] yes Im doing probably very weird and stupid things to your Defold :slight_smile:

I’m not talking about turning the payload into a hash, but getting the key.
The payload would be stored in plain text in a regular lua module.

Ahh yeah. ok sorry. Thats kinda something I have been playing around with. Dynamically it is kinda ok (quite long winded), but as I said it’d be nicer if you could “cut and paste” the string from one go property to another in the editor. I wonder if I can use a texture resource… might try that out.

While I understand and agree with the reasoning of this, it also has a toll on creating re-usable script components in the sense that the UI/UX exposed to the user has lots of limitations.

For example in all the camera extensions, choosing the projection method is relegated to multiple checkboxes which is not really good from a user perspective and should be handled by a dropdown that return a string.

I think there is room to improve the presentation from the data itself. I would really love to be able to have a property that is a vector4 but is for example presented to the user as a color picker :wink:

Thoughts?