Jump to content

Yemachu

Administrator

Yemachu last won the day on September 14

Yemachu had the most liked content!

Community Reputation

49 Valued

3 Followers

User Groups

About Yemachu


  • User Group: Administrator


  • Member ID: 135


  • Title: Card maker maker


  • Post Count: 48


  • Post Ratio: 0.03


  • Total Rep: 49


  • Member Of The Days Won: 7


  • Joined: 01/12/2019


  • Been With Us For: 1416 Days


  • Last Activity:


  • Currently:


  • Age: 29


Clubs

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Yemachu

    LV 13?

    This card maker hasn't supported Level/Rank 13. Maybe another card maker supported the option? There is however an offical card that shows Rank 13 (Number iC1000: Numerounius Numeronia). At the time the code was written, there weren't any official cards with that showed such a Rank. Other obligations take up most of my time, so the card maker doesn't sse as much development as it would require.
  2. Been playing around with an AI that turns a "rough" sketch into something better looking.  Progression.png

    Picture shows the initial sketch and a few iterations.

    1. Show previous comments  2 more
    2. Yemachu

      Yemachu

      Try to use colored areas rather than an outline. A more descriptive prompt might also help. Do you want a realistic dragon, or rather a cartoon one?

      Quote

      Professional digital painting of a cute, chubby dragon with small wings.

      Dragon generations.png

    3. LordCowCow

      LordCowCow

      Yeah I mostly just threw some old art I tried to do on DS Pictochat cause it's basically only time I ever tried to art lol

      But that's pretty great

    4. Yemachu

      Yemachu

      You don't even have to limit yourself to paintings/drawings; You can also turn it into a picture of a plushy.

      Quote

      High quality photo of a cute, chubby, sitting dragon plushy with small wings

      Dragon plushy.png

  3. Eurovision song contest 2022 has started.

    1. UltimateIRS

      UltimateIRS

      nobody cares

    2. LordCowCow
    3. Yemachu

      Yemachu

      "Give that wolf a banana, before it eats my grandma". Interesting song text… though with the various songs in their native language there might be some other weird ones that fly completely under the radar.

  4. Recently came across a site that uses AI to generate images of new "Pokémon".

    https://nokemon.eloie.tech/

    1. Cibryll

      Cibryll

      Kinda makes me wonder if there's something like that for Yu-Gi-Oh!

    2. Yemachu

      Yemachu

      Given there is quite some variation in art styles between different cards (i.e. "Burning Abyss" vs "Live Twin"), I reckon you could just look for AI that generates images.

      • Dall-E generates images based on a prompt, but it requires a subscription. It does provide a 3 month trial period, with a free credit taht is worth about $18.
      • Artbreeder lets you select a few images and have it generate another one based on it, or tweak some parameters (such as age) to create a different image. An account is required, and any image you generate (upload?, not entirely sure; be careful wih copyrighted works) can be used by anyone.

      With some other, more specialized options out there (focussing on creating paintings for example).

      Also once ran into an AI that turns text to speech using famous voices (FakeYou.com), such as: Spongebob, Yami Yugi, Obama, etc. You could recognize the voices, but there was little control over which parts to emphasize.

  5. The "A Hero Rises" banner is live. Despite the banner not having increased odds, the results have been amazing for me so far: Lewyn, Hatari Azura, Thórr, Amelia, Saber, Cyl Eliwood, Cyl Micaiah, Thórr; and that within 16 summons. Currently only missing Byleth from the featured units. Amelia, Saber, Micaiah, and Thórr have been merged. Lewyn will donate "Special spiral" to a unit I have yet to decide on (currently between Riev and Yuri), Eliwood and Azura are my first copies of them and will stick around for collection purposes.
  6. "Vital Astra" is apparently inheritable to infantry sword/lance/axe users. So we now have a inheritable speed scaling special that even grants damage reduction as an additional effect. I wasn't expecting that to be the case when I saw the trailer.
  7. New Pokémon games have been announced, scheduled to release at the end of this year. Seems to be inspired by Spain. Note from cow: When more info comes out make sure to spoiler warning/spoiler tag things
  8. Caeda is the next legendary hero. Seems like she provides stats in addition to being able to be paired up.
  9. Voted for Dagr and Azura, forgot to vote on the remaining days. From the top 8, I only have Edelgard and Corrin. I'm hoping another unit than those wins (for collection purposes), though I wouldn't mind a spare Corrin.
  10. Out of the units I voted for, only Lyon reached the top 20 in their respective division. As for the winners, I wonder how they will handle the next Choose Your Legends now that female Byleth has reached the top two. Usually different iterations of a unit are no longer votable after one of their versions has won. Given their votes are tallied separately, I suppose male Byleth still could have a chance. Though it didn't stop them from booting Flame emperor after Gatekeeper and Marianne won. It could get especially awkward if both versions of Robin/Kris/Corrin would win next round, in the case where male Byleth is dropped. Time will tell.
  11. It is that time of year again where quite a few people celebrate some event or another; often involving either receiving presents, or given them out. Did you get (others) anything? Presents I have received this year include: Dragon shaped slippers A board game Chocolate Some undergarments
  12. Yemachu

    Card maker Devlog

    It has been more than a month since the previous blog post, despite feeling like it was posted last week. Time sure flies. Last time the topic was about component librarie; they certainly help with getting a uniform look-and-feel for any application. But having an application that has a consistent design isn't particularly useful if none of the controls (such as buttons, sliders, and so on) do anything. This brings us to the topic of this post: managing state and reacting to changes. In TypeScript there are a few "primitives" which can be used to model your state. string: Represents text. A card's name or effect could be represented this way. Doesn't inherently represent any number: A numeric value. A card's level could be represented this way, as well as the horizontal and vertical position at which an image should be drawn Object: Group of "primitives" that can be accessed under a specific name. Useful for having closely related data together, such as all properties of a single card, the width and height of a rectangle, X and Y component of a coordinate, and so on. Array: List of things in a specific order. Typically similarly typed content is put in an array (such as all different cards in the project). A relatively simple representation of a card could be as follows: { "name": "Dark Magician", "template": "NORMAL", "attribute": "DARK", "level": 7, "ATK": "2500", "DEF": "2100", "type": ["Spellcaster"], "effect": "The ultimate wizard in terms of attack and defense.", } A few of the standard traits of a Yu-Gi-Oh! cards have been represented in that block of text. Modifying those properties from code is easy enenough; simply reassign one of the values. const card = { /* All of the above properites */ } const nameEditor = document.getElementById("nameEditor"); nameEditor.addEventListener("change", function(evt){ card.name = evt.currentTarget.value; }); If one were to type some text in the "nameEditor" textfield, it would update the card's name. But is the rest of the application aware of the change that has been made? The above code does not notify that the name property has been changed, so other code that might have something to do with that property (such as the renderer that creates an image from it) might not act on the change. True, the code could constantly be rerun so the lastest values are used, but this can be a bit pointless if nothing has been changed. It is however not entirely without merit; games tend to work this way. An alternative is to invoke a function notifying others that changes have been made. This could be a tad repetive, and is easy to forget if the code is not structured in a way that forces you to do so. Irrespective of how other parts of the code are notified about changes in the state, it needs to somehow figure out what has changed and how to respond to that, or it could start from scratch working from the new state. The former is rather finicky and error prone, the latter leads to a lot of extra work. React (detailed in the previous post) takes an approach somewhere in between. Rather than making changes in place, you create a new immutable object that represents the state and notify the application about that new object. The immutable nature allows you to reuse components from the previous state; they will not be changing after all. This makes figuring out what elements need to be updated a whole lot easier: is this part of the state the same as the previous time? Yes: leave everything as is. No: Start from "scratch" (nested components might not need to be updated however). var card = { name: "Dark Magician", level: 7 }; // Create a new object ({}), copy all properties from the previous state to it (card), // and overwrite any of them with the newly specified values (level: 7). card = Object.assign({}, card, { level: 8 }); // Output: { name: "Dark Magician", level: 8 } Assigning a new value has become a tad more unwieldy, but we have created a completely new object, rahter than having changed something in place. The above might not work correctly with deeply nested properties, but there are utilites for that available, such as Immer.js. Leaving the issues of responding to updates aside for a bit, there is another thing with the state that needs to be addressed: maintaining integrity. In the above example a new value gets created where the level is overwritten. In this case it is an acceptable level, but in the more general case there might need to be checks in place making sure it falls between zero and twelve (inclusive)… or make that thirteen since "Number iC1000: Numeronious Numeronia" exists. Placing the logic in the event handler could work, but could become clunky if multiple sources were to work on same value. This could happen when a slider with a text field both control the value. Extracting the logic into its own function could help. function UpdateLevel(card, level) { if (0 <= level && level <= 13) { return Object.assign({}, card, { level }); } return card; // Invalid level; leave it unchanged? } // Somewhere in an event handler setState(UpdateLevel(card, evt.target.value)); In this case it is only one value that needs to be updated, but what if some more things were related? Say… changing the name should also update the effect so any references to the card's "old" name now reference its new name. This could of course be added to the function that updates the name: function UpdateName(card, newName) { const newEffect = card.effect.replaceAll(card.name, newName); return Object.assign({}, card, { name: newName, effect: newEffect }); } That works… but what about the pendulum effect? It can simply be added. It is however a solution that does not scale well. In the actual game various cards refer to other cards by name (i.e. Fusion Materials). Having the "UpdateName" function run over all cards in the project to update any effects that refers to its old name quickly becomes unwieldy. It would be more convenient if we could tell the state that we intend to update the name of a particular card, and have related state figure out for itself if it needs to update as well. This, to my knowledge is kind of the idea behind Flux/Redux. import { createAction, createReducer, combineReducers } from "@reduxjs/toolkit"; const rename = createAction("card/rename", function(card, newName) { // When every instance is informed about a name change, it might be a good // idea to add a field indicating the intended target to prevent all cards // from taking on the same new name. Hence "id". return { payload: newName, meta: { id: card.id, oldName: card.name} }; }); const name = createReducer("Einzelgänger", function(builder) { builder.addMatcher(rename.match, function(state, action) { return action.payload; }) }); const effect = createReducer("You can only control 1 \"Einzelgänger\".", function(builder) { builder.addMatcher(rename.match, function(state, action) { // Not a great implementation, but it should suffice for a demonstation. return state.replaceAll(action.meta.oldName, action.payload); }); }); const card = combineReducers({ name, effect, // … }); In order to rename a card you would then dispatch the "rename" action from your event handler. dispatch(rename(card, evt.target.value)); The state then decides how it should respond to that action, without the event handler needing to worry about any of the other details about how the state should be changed. Isn't that wonderful? Another advantage of using this method of working with state is that you can test everything in isolation before integrating it with other code to make sure individual parts work correctly. Something worth noting, is that this example might be a bit convoluted. It is probably a better idea to have a special syntax where any references get resolved upon rendering the card. This to avoid all letters 'M' getting replaced with "Mokey Mokey" when typing that name after writing its effect first, or affecting other cards with the same name. That should be enough for this post. Not sure which topic to address next, but there are enough topics to cover. Till next time!
  13. Just finished playing the main story of "Bug Fables". I found it to be quite an enjoyable game. If you are a fan of the old Paper Mario games, you'll probably also like this game.

    The theme has been implemented quite nicely (though the texturing has some room for improvement).

×
×
  • Create New...