Nepeo's Forum Posts

  • Had a quick look at the code and it doesn't look like we've written an JS interface for the video plugin yet. You could create a eventsheet function that sets the src for the video and then call that from JS with the src?

  • A minimal replication on the issue tracker would be appreciated, as it hasn't been reported yet.

    Generally it's not that useful posting crash reports on the release notes. If the problem is common then posting a brief description of it with a link to an issue on the bug tracker can be useful to point other users our reponses. That way they can find the status of the issue and find out when it's resolved.

  • Have you looked at the Instant hit laser example?

  • Thanks for the confirmation stratosapo

  • Hey I've published a new version of the Google play dependency to the build server, which should resolve this problem. If you could take a look and make sure it's working for you that would be appreciated.

  • The log which the export shows isn't a crash, it's the build log from the server. Most of the information on it isn't created by our code but by the tool we use. When there is a failure it generally only shows the step that failed and not the reason.

    Most of the log is noise, except for the line

    Task :app:transformDexArchiveWithExternalLibsDexMergerForRelease FAILED

    transformDexArchiveWithExternalLibsDexMergerForRelease is the step responsible for merging compiled DEX files together, for some reason it failed but it doesn't tell us why. By building the project myself in Android studio I can inspect the reason for this step failing.

  • We had some server issues over the last 30 minutes or so while I was updating. Should be stable now, but let me know if your experiencing any new problems.

    "Bug reports" are more than a crash log. Sometimes it's possible to draw a conclusion from a log message, but often we need to know the situation in which it occurs. Depending on the error that can be a combination of the system information, the project and a particular sequence of operations.

  • Shubi the log doesn't contain the information as to why it's failing, and this isn't happening with every build. In fact I haven't seen it in my test builds, hence why I'm asking for a bug to be filed with a reproduction.

    A lot of people tend to assume that because it's happening to them it must be happening to everyone, but it's generally a specific circumstance that causes a bug, and we have a lot of ground to cover.

  • If you are experiencing an issue with the build service or construct you should check our issue tracker and file a bug if one hasn't already been filed for your issue. While we have received support emails and forum posts have been created for this issue no body has filed a bug yet or sent us a reproduction. Without a reproduction we cannot investigate the problem.

  • RageByte the basic issue is that the data your trying to read/write isn't text. It contains text, but reading and writing the non-text parts as text is wrong. Most file formats use explicit offset and length values to separate the components of the data, so unless the text was exactly the same length as the piece you were replacing it would make any surrounding offsets and lengths incorrect.

    If you want to modify JPEG data you will have to read the data according to the JPEG specification. This is perfectly possible with the BinaryData plugin, but it's going to be hard work. I've written encoders and decoders for several file formats in the past and most took several days of research and coding to implement. If you know even a little JavaScript it will be a lot easier for you to find a library to do this for you.

  • Hey CreativeMind

    I haven't personally used Google Play app signing but I understand how to process works.

    Google's official advice for debugging Google Play Games is to create 2 OAuth Client IDs for your application. One for debugging and one for release. You can create and modify OAuth Client IDs for your application at https://console.developers.google.com/apis/credentials. More details can be found under section 3C on this page https://developers.google.com/games/services/console/enabling.

    Both client IDs should be set to Android and have use your project ID for the package ID value ( typically something like com.mycompany.mygame ). Your debugging client ID should have the SHA1 signature of whatever certificate you use to sign the application ( can be your upload key if you like ). Your release client ID should have the SHA1 signature of the Google certificate that is used by "Google Play app signing". According to this page documenting how app signing works:

    The MD5, SHA-1 and SHA-256 fingerprints of the upload and app signing certificates can be found on the app signing page of the Play Console

    From what I've read it's not possible to have 1 client ID that can be used for both local builds and release builds if your using Google app signing. The reason being only 1 signature can be trusted per client ID, and your local builds will always be signed by a different certificate to the release ones. You cannot download the private part of the app signing key used by Google, as that would invalidate the security of it.

  • I came across this article on how the galaxy is generated in the original "Elite" game a few weeks ago, I haven't read through the details of the algorithm but it doesn't look too hard. Might be useful

    blog.rabidgremlin.com/2015/01/14/procedural-content-generation-creating-a-universe

  • Note this excludes form controls like buttons and text inputs, because these are HTML elements that "float" above the main display canvas and aren't actually part of the canvas, so are excluded[...]

    I technically took that from the game recorder documentation, but the same is true for canvas snapshot.

    Depending on the browser you can use the game recorder plugin to create a video of the user screen, which includes the canvas as well as floating elements.

  • I don't think we ever published a tutorial on how to use the plugin. It's quite similar to the JavaScript DataView class but I couldn't find any good tutorials on that either.

    When we first released it I did start writing a blog post about it, but got sidelined by other work. When I returned to it I wasn't completely happy with what I'd written. Too much fluff, not enough stuff. No one was asking for it at the time so I put it to the side and left it.

    I'll post the incomplete draft here in case it helps anyone, if people are interested then I might take another look at it. Unfortunately it's not finished, or particularly edited. It's also missing most of the practical examples on how to use the plugin, but it does explain what it is and how it works.

    A fresh Byte - introduction to bits, bytes and binary

    A byte is a number, composed of 8 "bits".

    Right... so what is a "bit"?

    A bit is a single binary digit. A binary digit can be either 1 or 0 ( true or false ).

    If it helps you can imagine a "bit" as a coin. Placed it on a table. The coin can be "heads" or "tails" depending on which side is up. Now place a second coin on the table. The first coin has 2 possible orientations, if you consider that the second coin also has 2 possible orientations as well you can see that in combination you will have 4 possible orientations. If your struggling it might help if you actually get some coins out and count the number of combinations! Add a third coin, and it will become 8 possible orientations. This gives us a neat pattern, for each coin we add we double the number of orientations we can have. So if we were to use a calculator we can calculate how many possible combinations you can get using the sum "2 ^ n" ("n" being the number of coins). Now our "byte" is made up of 8 coins ( bits ) so there exists 2x2x2x2x2x2x2x2 combinations. That 256 combinations, or values! If you have 2 bytes ( or 16 coins ) as individual bytes they can represent 256 values, or 512 values together. But if you make them into a single pile of coins they can represent 2 ^ 16 values ( 65,536 ). That is WAAAY more!

    Storing data as bytes

    Now while messing around with coins is all well and good, I haven't said why we need to know why we need to know about bytes and bits. For various reasons ( which I won't go into ) all computers are binary. This means at the most basic level modern computers only really deal with bits and bytes. So everything you deal with; numbers, text, images and sound have to be stored as as long lists of ones and zero's.

    To convert a value to binary we "encode" it in a suitable format. Clever people have come up with ways to store different types of data in a binary form, and we are using these algorithms to encode the data.

    Whole numbers ( "integers" or "ints" ) are the easiest, we can convert a decimal value into a binary value easily. This value is then chopped up into 8 bit chunks that can be put into bytes. That doesn't tell you if the number is positive or negative, so there's a second format called "signed integers" where one bit indicates if the number is positive or negative. The standard sizes for integers are:

    8 bit unsigned integer (0 to 255)

    16 bit unsigned integer (0 to 65,535)

    32 bit unsigned integer (0 to 4,294,967,295)

    8 bit signed integer (-128 to 127)

    16 bit signed integer (-32,768 to 32767)

    32 bit signed integer (-2147483648 to 2147483647)

    Fractional numbers are more complicated. The format we use is called "floating point numbers" or "floats". As frational numbers have an effectively infinite number of combinations we instead hold an estimate of the value. The numbers of bytes that you use for the number determines how accurate that estimate is. When adding together lots of floats you get a small cumulative error, due to the fact the numbers are estimates. The plugin supports 2 sizes of float, and there is no unsigned variant.

    32 bit float

    64 bit float

    Text encoding was originally quite simple when it was first conceived ( back when telegrams were still a thing ), but has become much more complicated over the years. Typically each character is assigned a number which is used to map between letter and number ( like 97 for a lowercase "a" ). Then we can store a character as a number. It becomes more complicated if you include other languages and emoji ( which the old methods did not ). You need a lot more numbers to map all those characters ( 137,929 are currently supported by the unicode standard ). To hold a number that could be any character would require at least 3 bytes. Given that standard English text can fit in less than a byte per character thats a lot of wasted memory. To get around this modern encodings break up that value into multiple chunks, then each chunk includes a little bit of extra information about how many blocks the letter needs as well as part of the characters ID. This way an encoded character only uses the number of bytes it needs. The BinaryData plugin supports the UTF-8 character encoding, which can be between 1 and 4 bytes per character. However, there is a downside to these clever encoding techniques. Without going over every letter in your piece of text you don't know how many letters your bytes hold, or how many bytes you need to hold a piece of text. This also makes it hard to pick an individual letter from a random place out of a chunk of bytes.

    For more complex types of data, like images and sound, they are constructed out of the types above. A basic form of an image is to have 3 numbers per pixel (red, green, blue), with each number stored as an 8 bit ( or sometimes 16 ) unsigned integer. Audio is even more complicated, it has multiple sets of data for each speaker ( channels ). Each channel stores measurements of air pressure at a given frequency as a low precision floating point number. A typical frequency is 44,000 times per second so 1 second of stereo audio would be 88,000 bytes ( that A LOT of data ) and a 4 minute song is 22MB. You might be wondering why the songs on your PC aren't 22MB, and that's because audio, images and videos are generally compressed before they are stored. Compression is cool, and complicated... So we won't cover that. But I will say that media nearly always has to be uncompressed to be used.

    What is the BinaryData plugin

    The BinaryData plugin is quite simple really, it's a container for bytes. Through it's actions and expressions you can read and modify those bytes. Most of the time you won't be using the plugin by itself, but as a container for moving data from one place to another. At the moment we have expanded the NWjs, localstorage, websocket and AJAX plugins to allow them to interface with BinaryData.

    The AJAX plugin in particular is very useful, as it allows you to fetch files straight into the BinaryData plugin. By using another plugin like the drawing canvas which exposes data as base64 or blob urls, you can "fetch" that data via the AJAX plugin in BinaryData. In the case of blob URLs this is usually very efficient, with very little overhead. Encoding and decoding base64 generally involves multiple copies of your data, so has more overhead.

    Once you have that data you can pass it to another plugin, or you can modify it using the inbuilt methods. When reading and writing to the BinaryData plugin the tricky part is that you have to know what type of data is where. As the values are encoded you can read them out as whatever you like, but it might not make much sense. Reading a number as a piece of text will give you some weird letters for instance. You can even put copy the contents of one BinaryData plugin into another, which allows you to compose more complex data formats. It's possible to read complex file types or even create your own format for your game using these tools (Interchange File Format is a good starting place for this)

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Mmm yes if you were using the behaviour like that then it's a breaking change. That feels like a bit of a hack to me, it's taking advantage of an edge case not using intended behaviour.

    There's a load of ways that come to mind that are based on expected behaviour would still work.

    - Change the collision tags so that LOS ignores the monster when it's "invisible".

    - Remove the monster class from the custom obstacle list ( custom mode only, and doesn't work for a single instance ).

    - Add an instance variable to the monster to say if it's invisible, and filter the results of LOS to Monster against this.

    - Pin a "invisibility cloak" ( a solid that's larger than the monster ) to the monster, so that the ray hits that instead ( might interfere with movement behaviours, but collision tags can probably solve this ).

    Just tried the 3rd one in the example project and it's super easy. Are many people relying on "Has LOS to ObjectClass" returned false if ObjectClass was an obstacle?