Then, what would be the point of this?:
Geoff the Medio wrote: ↑Fri May 29, 2020 3:26 pmyesIf I read you correctly you would expect the following to work/be usable in stringtables?
MACRO_OUTER
'''[[MACRO_SPACE]]'''
MACRO_SPACE
''' '''
Moderator: Oberlus
Geoff the Medio wrote: ↑Fri May 29, 2020 3:26 pmyesIf I read you correctly you would expect the following to work/be usable in stringtables?
MACRO_OUTER
'''[[MACRO_SPACE]]'''
MACRO_SPACE
''' '''
The thing I asked geoff about was if macros get expanded recursively. Does not give access to game rule values or multipliers though.
What about to write configuration in python and parse it with ast module?Ophiuchus wrote: ↑Sat May 30, 2020 5:09 pm The thing I asked geoff about was if macros get expanded recursively. Does not give access to game rule values or multipliers though.
I did a web survey to find a language which supports what we need to bring FOCS, stringtables, backend and AI together.
I found a lot of configuration languages like TOML, YAML etc which improve on JSON and reduce boilerplate by providing some merging/reuse of definitions. This is nice for but does not solve the issues at hand and for many things we can use macros on an outer layer. Also those often have good support for dates/timezones and units (like s,kg,MB) which are important for system configuration but we do not really need.
YAML supports references (anchors) not sure if that is helpful.
Most others like HOCON and CUE are rather single-tool/platform (JVM and go).
The closest languages (configuration languages with arithmetics support) I found are CUE/HCL/GCL/jsonnet.
CUE and HCL are single-tool (both go-based). GCL (by google) is not public at all. That there is not much tool support might be due to the reason that these are not so minimal anymore, some are even turing-complete, so it is harder to implement support in multiple platforms.
jsonnet is a superset of JSON (many are familiar with that), written in C++ (second implementation in go), has bindings for C,python,and C++ (this would fit the bill). can also be crosscompiled to js, also some bindings for six other languages by third partys. I am not sure the template approach it follows is a way to go. Also it does not provide validation. It addresses the usual JSON suspects (multiline strings, comments, allow dangling commas,...) . It allows for arithmetics. It also has a lot of stuff we do not really need.
CUE lang configuration use case has some comparisons with jsonnet, GCL and HCL (if you scroll down to "Comparisons") and also hightlights the CUE benefits.
I imagine this could work, first macro expansion, then running the jsonnet interpreter priming with game rule values, then processing content definitions, feeding that to the FOCS parser and for human player also process stringtables. Dumping to filesystem seems like the wrong thing to do so just keep this in memory and fetch stringtables from there. Interpreter needs to be run on game start, on opening encyclopedia on start screen (with defaults for the game values), or when switching stringtables.
Probably more sensible to split simple-arithmetic-properties to its own definition files usable from stringtables and AI (should make AIDependencies mostly obsolete). and still to split calculated values from current FOCS and a way to use the resulting values in macro expansion.
Anyway jsonnet is much too huge for inclusion (60MB or sth).
Need to think about this a bit more.
What do you propose exactly? Also would this be usable from c++? You can answer that in the original python thread Potential replacement of FOCS with Python.
I don't really understand the point of this suggestion or the various other scripting or serialization formats that have been suggested in the same context. What is the potential benefit, in terms of accessing data in different places, of rewriting FOCS content in another format (ignoring any other benefits, like easy of writing scripts or availability of tools to do so)? If a building type is scripted in FOCS or Python or JSON or YAML or whatever else, or some combination, how does that make it easier to access from a stringtable entry? Is it also suggested to write stringtables and AI in YAML somehow, and if so, why?
Code: Select all
ENC_GALAXY_SETUP_SETTINGS
'''Seed: %1%
Number of Systems: %2%
Shape: %3%
Age: %4%
Starlanes: %5%
Planets: %6%
Specials: %7%
Monsters: %8%
Natives: %9%
AI Max Aggression: %10%
Game UID: %11%
'''
+1Geoff the Medio wrote: ↑Mon Jun 01, 2020 10:28 pmI don't really understand the point of this suggestion or the various other scripting or serialization formats that have been suggested in the same context. What is the potential benefit, in terms of accessing data in different places, of rewriting FOCS content in another format (ignoring any other benefits, like easy of writing scripts or availability of tools to do so)? If a building type is scripted in FOCS or Python or JSON or YAML or whatever else, or some combination, how does that make it easier to access from a stringtable entry? Is it also suggested to write stringtables and AI in YAML somehow, and if so, why?
Yes, that would work for stringtables in most cases I guess. For looking up properties like hull structure etc we may be missing the right context (but that is extended use cases anyway). But in order to have a single source of truth for maintenance in many cases it will still be necessary to have macros - which is fine for stringtables as we do macro expansion there. But in that cases it wont work for AI (currently).Geoff the Medio wrote: ↑Mon Jun 01, 2020 10:28 pm What seems to be missing is a way to lazy evaluate FOCS expressions within stringtable entries, when those stringtable entries are displayed.
Code: Select all
Named name = "REINFORCED_HULL_BONUS" value = [[SHIP_STRUCTURE_FACTOR]] * 5
Code: Select all
The reinforced hull tech adds [[Value REINFORCED_HULL_BONUS]] to maximum structure of each empire ship
Code: Select all
fo.getNamedValue("REINFORCED_HULL_BONUS")
Code: Select all
fo.setStringtableValue("REINFORCED_HULL_BONUS", calculated_bonus)
Discussion from there:
Agreed, having a naming facility in contexts where macro mechanism/names and ValueRef evaluation are available is unnessecary.geoffthemedio wrote: "Naming" FOCS ValueRef expressions or higher-level things (like effectsgroups) was considered, but is unnecessary. The macro mechanism accomplishes the same thing, but much more flexibly.
Yes, true. For marking a valueref (like the one in the PR) there is still a nesting toking in FOCS necessary. Probably could do the hard work in the parser.geoffthemedio wrote: Aside from that, there's no need for a "named valueref" to be a type of valueref. There would just need to be a list of valuerefs with names associated.
There's not much difference in the parser, I think... Whether or not there is a "Named" ValueRef derived class, you'd need to parse a list of (or perhaps randomly scattered) name+ValueRef expression pairs, and then put them into some container, indexed by the name.
Invariances probably aren't enough; I think you'd need to restrict to constant-valued expressions with no gamestate dependence. A count of how many ships exist in the universe is invariant to source, target, localcandidate, and rootcandidate, but will not work properly if evaluated just once, especially if the just once is before a game is being played. And they probably need to have no dependence on other parsed content either, as it might otherwise depend on what scripted content has been loaded, which can potentially change on the client after execution starts. These issues could be avoided if you store the ValueRefs, not their results, and Eval() them when needed. They need to be parsed and constructed to be evaluated anyway, so I don't think storing the actual ValueRef, rather than its Eval() result is much more difficult / complicated. And constant ValueRefs already cache their result, so you caching the result externally doesn't really optimize or otherwise have much benefit...Also note for the scope of this issue I try to look up a value and not a (lazy) valueRef, so the idea would be to check for invariance (else log a warning), then eval the value ValueRef and register the resulting value. It might be that looking up the ValueRef instead makes more sense but i did not ponder lifetime issues yet.
LinkText does substitute the names of objects, like ships or systems, which is quite similar to the functionality you want.Both [Eval [[FOCS-VALUEREF]] ] and [Value VALUE-NAME] are different from the facilities we have.
In UI/LinkText links are created, but content does not get substituted.
GG code is probably too low level. It doesn't know anything about ValueRefs or the gamestate or scripted content or similar.In GG/Font italics and similar tags are processed.
Images in pedia articles are handled by GG/RichText.I did not find the image part yet.
In LinkText would make sense, perhaps as a LinkDecorator. Doesn't need to actually be a clickable link or to have any special decoration / colouration, so I'm not sure if there would be quirks or problems with using that mechanism for value substitutions, but it can probably do something similar and that should then work in sitreps and pedia text.Not sure what to do. Should I add it to the LinkText? Maybe hook it to the CUILinkTextMultiEdit via multi inheritance similar to the TextLinker?
Ophiuchus wrote: ↑Thu Jun 18, 2020 12:49 pm Who/Anybody can support me on the python API/bridging? I access the registered value refs via GetValueRef(name) (defined in ValueRefs.cpp). The returned untyped valueref has a StringResult() method. Probably exposing this via a GetStringResult(name) function would make sense - maybe that is all python needs. Or maybe rather a GetNumericalResult(name) function as we want to use this (e.g. effective bonus of reinforced hull tech) in computations.
I need some help on the UI. So anybody in for testing (no technical experience required)? I could build a snap if that helps.
Yes, for the UI