XHXIAIEIN's Forum Posts

  • C3 for vanilla JSON ACE is poor, so I'll opt to use Javascript to help me with this.

    Note that to keep the function simple, the parameter passed in here is the array containing those items, not the outer JSON object.

    JSON.GetAsCompactString("leaderboard")
    

    Export asJSON to the Function, Convert the jsonString to json object and process it via Javascript. Finally, convert the json object back to a string and return it.

    // [...]
    const arrayData = JSON.parse(localVars.jsonString);
    
    // Sort Function
    const sortArray = (arr, key, asc = true) =>
     [...arr].sort((a, b) => asc ? a[key] - b[key] : b[key] - a[key]);
    
    // Sort
    const sortedData = sortArray(arrayData, 'score', false);
    
    // return String
    runtime.setReturnValue(JSON.stringify(sortedData));
    

    Function Clipboard. Need 'JSON' Object

    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-start-of-layout","objectClass":"System"}],"actions":[{"id":"parse","objectClass":"JSON","parameters":{"data":"Functions.sortArray(JSON.GetAsCompactString(\"leaderboard\"))"}}]},{"functionName":"sortArray","functionDescription":"","functionCategory":"","functionReturnType":"string","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"jsonString","type":"string","initialValue":"","comment":""}],"eventType":"function-block","conditions":[],"actions":[{"type":"script","language":"javascript","script":["// [...]","const arrayData = JSON.parse(localVars.jsonString);","","// Sort Function","const sortArray = (arr, key, asc = true) =>"," [...arr].sort((a, b) => asc ? a[key] - b[key] : b[key] - a[key]);","","// Sort","const sortedData = sortArray(arrayData, 'score', false);","","// return String","runtime.setReturnValue(JSON.stringify(sortedData));"]}]}]}
    
  • Update:

    I solved this by using the sub-layer mask trick. Thank you Skymen for help

    blend-mask-layer.c3p

  • You can use the qarp() system expression

    qarp(startX, midX, endX, t)
    qarp(startY, midY, endY, t)
    

    Here's a more complex example

    file.c3p

  • How can I blend two mask effects and keep their intersection?

    ask-file.c3p

    Maybe what I want is the XOR blend mode?

    Tagged:

  • I just found that when I opened the C3 editor in iOS Safari, I couldn't drag the event block in the event table. It seemed to lack relevant interaction methods. I looked through the documentation and didn't find any relevant gesture instructions. do I missing some steps? Ashley

    Tagged:

  • You can use SVG in HTML Elements to made this curved text input.

    Here is an example: Curved_Text_Input.c3p

    Update in 05/2026:

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • > normally a text adventure will be translated to many languages and right now it doesn't allow to be edited outside construct, reconstructing one by one by hand each dialogue is tedious on big storylines.

    You definitely shouldn't make a flowchart per language. Just have one flowchart for all languages, and instead of putting the actual text in the flowchart, just put the key to look up in the Internationalization object.

    Is that what you wanted the save/load JSON feature for? If so you shouldn't need it after all, as using one flowchart for all languages is a better solution.

    I tried a solution, first generate the md5 hash value for the original language, and then generate the JSON file. Other languages ​​also create their own JSON files and use the corresponding hash as the key.

    example: Flowchart_with_Multi-language.c3p

    You only need to maintain a Array/spreadsheet/CSV file:

    en-US, pt-BR, zh-CN
    Home, Início, 主页
    About, Sobre, 关于我们
    

    you can directly use English with the flowchart, and display the text by using a function.

    Functions.Translate("Home")
    Functions.Translate(FlowchartController.OutputValue("Text"))
    

    Then use the tool to automatically generate the JSON file.

    ---

    The working principle of it is that it will generate a Hash for your original language and correspond it with other languages.

    When you search for a language through the Functions, it will first generate a Hash for the original language, and then look for the corresponding Key in the JSON. For the Hash algorithm, the `hashFnv1a64` algorithm is used here, which is very fast and has very small collisions. It is also synchronized and has very little impact on performance.

    This way, you no longer need to use an ID like `home.title` to refer to it.

    en-US.json

    {
     "hash1": "Home",
     "hash2": "About"
    }
    

    pt-BR.json

    {
     "hash1": "Início",
     "hash2": "Sobre"
    }
    
  • You do not have permission to view this post

  • Just provide another idea.

    You can use a delimiter to separate it.

    like: Layout-1, Layout-20

    Then use tokenat expression to get out the number.

    tokenat(LayoutName, 1, "-")
    

    For example:

    tokenat("Layout-5", 1, "-") // 5
    tokenat("Layout 5", 1, " ") // you can also use spaces as delimiters.
    
  • Step1: Add a Array Object

    {
     "books": []
    }
    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-start-of-layout","objectClass":"System"}],"actions":[{"id":"set-array","objectClass":"JSON","parameters":{"path":"\"books\"","size":"0"}}]}]}

    -----------------------

    Step2: Add a dictionary Object in the Array

    {
    	"books": [
    		{}
    	]
    }
    
    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-start-of-layout","objectClass":"System"}],"actions":[{"id":"set-array","objectClass":"JSON","parameters":{"path":"\"books\"","size":"0"}},{"id":"push-value","objectClass":"JSON","parameters":{"where":"back","path":"\"books\"","value":"0"}},{"type":"comment","text":"add an object/dictionary: {}"},{"id":"set-object","objectClass":"JSON","parameters":{"path":"\"books.\" & 0"}}]}]}

    Here we need to explain,

    The simplest explanation is that you can think of JSON as an enhanced version of Dictionary and Array, which can use the superset object of dictionary {"key": value} and array [0,1,2..] at the same time.

    But when you need to use them, you need to declare whether the path is a dictionary or an array. Therefore, you need to use Set Array and Set Object action to change their types.

    -----------------------

    Step3: Add a Key in the dictionary

    {
    	"books": [
    		{
    			"title": "Everyday Italian"
    		}
    	]
    }
    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-start-of-layout","objectClass":"System"}],"actions":[{"id":"set-array","objectClass":"JSON","parameters":{"path":"\"books\"","size":"0"}},{"type":"comment","text":"add a book"},{"id":"push-value","objectClass":"JSON","parameters":{"where":"back","path":"\"books\"","value":"0"}},{"id":"set-object","objectClass":"JSON","parameters":{"path":"\"books.\" & 0"}},{"type":"comment","text":"[b]Set Path[/b] can make the JSON object to enter this path, so that you can use \".title\" to reference the [u]relative path[/u].\n\nIf you don't do this, you need to use an [u]absolute path[/u]: \"books.0.title\""},{"id":"set-path","objectClass":"JSON","parameters":{"path":"\"books.\" & loopindex"}},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".title\"","value":"\"Everyday Italian\""}}]}]}

    -----------------------

    Step4: Add a More Key

    {
    	"books": [
    		{
    			"title": "Everyday Italian",
    			"authors": ["Giada De Laurentiis"],
    			"year": 2005,
    			"price": "30.00"
    		}
    	]
    }
    

    Note that because authors is an array, you need to use Set Array to change its type.

    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-start-of-layout","objectClass":"System"}],"actions":[{"id":"set-array","objectClass":"JSON","parameters":{"path":"\"books\"","size":"0"}},{"type":"comment","text":"add a book"},{"id":"push-value","objectClass":"JSON","parameters":{"where":"back","path":"\"books\"","value":"0"}},{"id":"set-object","objectClass":"JSON","parameters":{"path":"\"books.\" & 0"}},{"id":"set-path","objectClass":"JSON","parameters":{"path":"\"books.\" & loopindex"}},{"type":"comment","text":"info"},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".title\"","value":"\"Everyday Italian\""}},{"id":"set-array","objectClass":"JSON","parameters":{"path":"\".authors\"","size":"0"}},{"id":"push-value","objectClass":"JSON","parameters":{"where":"back","path":"\".authors\"","value":"\"Giada De Laurentiis\""}},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".year\"","value":"2005"}},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".price\"","value":"\"30.00\""}}]}]}

    -----------------------

    Step5: Using Array Object Data

    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-start-of-layout","objectClass":"System"}],"actions":[{"id":"request-project-file","objectClass":"AJAX","parameters":{"tag":"\"\"","file":"books.json"}},{"id":"wait-for-previous-actions","objectClass":"System"},{"id":"load","objectClass":"Array","parameters":{"json":"AJAX.LastData"}},{"id":"signal","objectClass":"System","parameters":{"tag":"\"json\""}}]},{"eventType":"block","conditions":[{"id":"on-signal","objectClass":"System","parameters":{"tag":"\"json\""}}],"actions":[{"id":"set-array","objectClass":"JSON","parameters":{"path":"\"books\"","size":"0"}}],"children":[{"eventType":"block","conditions":[{"id":"for","objectClass":"System","parameters":{"name":"\"book\"","start-index":"0","end-index":"Array.Height-1"}}],"actions":[{"type":"comment","text":"add a book"},{"id":"push-value","objectClass":"JSON","parameters":{"where":"back","path":"\"books\"","value":"0"}},{"id":"set-object","objectClass":"JSON","parameters":{"path":"\"books.\" & loopindex"}},{"id":"set-path","objectClass":"JSON","parameters":{"path":"\"books.\" & loopindex"}}],"children":[{"eventType":"block","conditions":[{"id":"for","objectClass":"System","parameters":{"name":"\"info\"","start-index":"0","end-index":"Array.Width-1"}}],"actions":[{"type":"comment","text":"info"},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".title\"","value":"Array.At(0, loopindex(\"book\"))"}},{"id":"set-array","objectClass":"JSON","parameters":{"path":"\".authors\"","size":"0"}},{"id":"split-string","objectClass":"bookAuthors","parameters":{"string":"Array.At(1, loopindex(\"book\"))","separator":"\",\"","type":"string"}},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".year\"","value":"Array.At(2, loopindex(\"book\"))"}},{"id":"set-value","objectClass":"JSON","parameters":{"path":"\".price\"","value":"Array.At(3, loopindex(\"book\"))"}}],"children":[{"eventType":"block","conditions":[{"id":"for-each-element","objectClass":"bookAuthors","parameters":{"axes":"x"}}],"actions":[{"id":"push-value","objectClass":"JSON","parameters":{"where":"back","path":"\".authors\"","value":"trim(bookAuthors.CurValue)"}}]}]}]}]}]}

    -----------------------

    Finally, share a little tip.

    When I use JSON, I usually put a Text Input object in the scene and set its Type property to Textarea. Then set Text to JSON.ToBeautifiedString. This way you can easily inspect the contents of the JSON object

    {"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"every-tick","objectClass":"System"}],"actions":[{"id":"set-text","objectClass":"TextInput","parameters":{"text":"JSON.ToBeautifiedString"}}]}]}
    
  • The mentioned "Hot Update" likely refers to "In-app updates", which are currently very common in large-scale mobile games. Mainstream commercial game engines also provide some mature solutions for this.

    If the content you want to update consists of data files like JSON configurations, remote images, or similar resources, you could directly use AJAX to request these resources from a server and replace the corresponding objects in the runtime.

    But for larger updates, such as event tables, scenes, etc. it is not currently possible in Construct.

    In-app updates also implies risks as it can bypass the platform"s review process and directly publish application updates. Therefore, the Apple Store explicitly prohibits using this method to update games(App Review Guidelines).

    Meanwhile, Google Play offers an In-app updates solution, which might be the closest legitimate approach.

  • You can put Tween actions in Function and check Asynchronous. and use "wait for previous actions" to ensure that the previous tween animation is completed.

    Here is an old example

  • You do not have permission to view this post