Jump to content

judda

Administrators
  • Posts

    354
  • Joined

  • Last visited

  • Days Won

    44

Posts posted by judda

  1. If they all stem from the same foundation animals or something (i.e. the foundation animals) then really the table shouldn't get unruly since you are only allowed to have 2 parents.  The only thing that I can see being a little bit of a pain is the initial seeding of it, but that would be a one time operation that takes probably a few minutes to run.  After that, you are able to use the "degree of separation" to calculate how far back.  Heck, I would even go fo far as to call the column "foundation_animal_id" instead of "ancestor_animal_id".

    Please Note: The "ancestor_anmial_id" is the top-most (foundation), not each of an animal's ancestors duplicated.  If it was that then it would get bloated quickly with no real value.

    I don't beleive that having hundreds/thousands of foundation animals would pose a technical problem at all.  It could pose an issue with the "storyline" of the game but that's all I can see.

    As for the genetics table, I would consider swapping it to, or something similar to this:

    animal_genetics
    * animal_id
    * trait_id
    * trait_value

    This could lead to code like:

    <?php
    
    class Animal extends Model
    {
      public function genetics(): HasMany {
        return $this->hasMany(AnimalGenetics::class);
      }
    }
    
    class GeneticTrait extends Model {
      
    }
    
    class AnimalGenetics extends Model
    {
      public function animal(): BelongsTo {
        return $this->belongsTo(Animal::class);
      }
      
      public function geneticTrait(): BelongsTo {
        return $this->belongsTo(GeneticTrait::class);
      }
    }
    
    // If we have the "trait" column
    $animalGenetics = $animal
      	->genetics
      	->with('geneticTrait')
      	->keyBy(
      		fn($g) => $g->geneticTrait->name
    	);

    You could do:

    animal_genetics
    * animal_id
    * trait
    * trait_value

    Where "trait" is the column name you previously had.  It is true that this will make the table a fair bit bigger, but it could be a little easier to manage (though you could do that mapping with Laravel too).

    <?php
    
    class Animal extends Model
    {
      public function genetics(): HasMany {
        return $this->hasMany(AnimalGenetics::class);
      }
    }
    
    class AnimalGenetics extends Model
    {
      public function animal(): BelongsTo {
        return $this->belongsTo(Animal::class);
      }
    }
    
    // If we have the "trait" column
    $animalGenetics = $animal->genetics->keyBy('trait');

    This would get you the exact same view over the data (after retrieving every row) for a specific animal.

    -=-=-=-=-=-=-=-

    That being said, having them as columns all in 1 table does have it's potential advantage.  In both of the cases above, there is nothing in place guaranteeing that all genes are accounted for, so if you have a bug where you forget to insert a trait/gene then there is nothing to catch that other than other code since it as a mapping table.  Having it all as columns in the table buys you the benefit of having "NOT NULL" on the columns.  But that also gets gross because if you start moving into other species, for some animals they may not actually have it, which then means you need to make the columns NULLable and then the safety is gone.

    -=-=-=-=-=-=-=-

    Also note: Laravel by default does a "SELECT * FROM table", so if you have a dozen columns in your table just for genetics, whenever you pull the animal you will also pull all of those TINYINT columns which may not seem like much, but they do eat up memory and make the query take longer in order to retrieve all of the records (this is why most optimization guidelines say avoid "SELECT *" and grab only what you need).

    My personal approach to this optimization is ignore it until it becomes an issue, because it's a microoptimization but it gets uber frustrating to develop with if you have to pick and choose what columns are actually needed.  At the very least, wait until the feature is done before even bothering to try this sort of optimization.

    Hope this helps @deathmetal

    Please Note: All code in this post is completely untested and just written to describe the point/approach I would take and should not be taken as "this will work out of the box".

  2. @deathmetal You may want to make a table that has the most "ancient" ancestor mapped to a specific pet.  This would then allow you to see everyone who has at least one common ancestor.

    animal_ancestors
    * animal_id (bigint)
    * ancestor_animal_id (bigint)
    * sire_or_dam (0/1)
    * degrees_of_separation (bigint)

    When inserting the animal in, you can then calculate the "degrees of separation" based on it's parents, which you would then use as a "marker" to figure out how many generations to go back.  Then when calculating breeding type things, you could say where "degrees of separation" is 10 less than my current or something for their "full" heritage.

    This should also allow you to avoid the N+1 since you can eager load each of the animals with the first pass.

    Personally I wouldn't put the genetics all on the animal table because I'm guessing it's pretty much "extra information" that isn't needed in 95% of the queries about the animal.  I don't know how you have it set up but I've seen an "animal" table with 400+ columns in it because of that and I cringed anytime I tried to do anything (phpmyadmin crawls).

  3. Firstly <3 I'm really happy we inspired you in this way!

    @batThe best advice I can give is just make sure you are using migrations to stand up your database changes (and tear them back down if need be).  You will go through multiple iterations of the database structure (each time it could change slightly).  There are "best practices" you should follow, but don't necessarily let learning all of them slow you down/stop the process altogether ... at this phase you just need to learn more about your problem domain, and everything that needs to be done.

    As for where to start, if you use a framework like Laravel, it comes with a handful migrations for user data out of the box, so that's a good place to start.  And if you looking to build it from hand, I would still say look at their samples as a "good place to start" (https://github.com/laravel/laravel/tree/9.x/database/migrations).

    Our Discord has a bunch of developers on it who love to help so hop on in and we can also chat there!

    ~judda

  4. On 11/3/2022 at 8:53 AM, Nightmares said:

    Also this is my code for index.php:

     

    <?php
    
    include 'header.php';
    include 'leftside.php';
    
    ?>
    
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Kinopiron | Home</title>
        <link rel="stylesheet" href="Kinopiron.css">
    </head>
    
    <body>
        <div class="Contentbox"><p class="Content"> 
        <img class="map" src="map2.jpg">
                <br>Testing Testing adding some words to test this out.
                <br> Testing and adding more words.
                <br>Kinopiron Kinopiron Kinopiron1<br> Whoop Whoop
    
    
    
        </p></div>
    </body>
    
    </html>

    and I am using visual code studio and XAMPP for the server.

    I type the exclamation point and it auto inserts everything and I have just gone in to put it needed to include the header and left side bar and type in my <div> and <p> class. 

    So the good thing is you don't have a ton to change to make things valid, you would just need to move your include statements into the actual `body` section.  That being said, I would probably tweak it a little bit more so you aren't having to write the `<html>` every time.  Pop all of that stuff into the `header.php` and you are golden.

    <?php
    $pageTitle = 'News';
    
    include 'header.php';
    ?>    
    <img class="map" src="map2.jpg">
                <br>Testing Testing adding some words to test this out.
                <br> Testing and adding more words.
                <br>Kinopiron Kinopiron Kinopiron1<br> Whoop Whoop
    <?
    include 'footer.php';

    Then your respective files would look something like this ...

    `header.php`

    <html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Kinopiron | <?php echo $pageTitle ?? 'Home'; ?></title>
        <link rel="stylesheet" href="Kinopiron.css">
    </head>
    <body>
    <?php
    include 'leftside.php'; // Or this could just be included in here

    Then your `leftside.php` would include the stuff for the container.

  5. 4 hours ago, crotanite said:

    Got my pumpkin carved saturday. On sunday I made roasted pumpkin seeds, and pumpkin and peanut butter dog treats. The pumpkin seeds actually tasted pretty good, I've never had them before, I did them with garlic and salt but really I wished I just did salt. They sort of taste like popcorn... kind of, they have the texture of it, so I think just salt would have tasted better. My dog loves the dog treats, and I managed to get a load of them so she's going to be happy for a while!

    20221031_111834.jpg

    20221031_112729.jpg

    Those dog treats look so awesome :D

     

  6. There are a few "classic neopets" and other sites which have their owners really focused on the 'classic' elements.  I would say even if not a ton of people join if you have fun and learn from it, I would say go for it!

  7. @April You can consider the bank/current to be a lot like the user login system that you already built (most features end up following a similar pattern).

    1. Create a table (or just a field on the user's table) that will contain their current currency amount
    2. Retrieve the user's current amount of currency from the database
    3. Then whenever you are able to play with it / modify the value since it's been retrieved

    You should aim to have all interactions (removing/adding money) in their own helper functions so that you aren't removing it inconsistently, which will also allow you to add functionality like a transaction log could be easy to implement.

    I know I'm a little vague here, but let me know how we can help!

    • Like 1
    • Thanks 1
  8. Hey All!

    I know, I ended up doing this a few weeks back (although it was already way later than it should have been done), one thing we noticed recently was that with the import it doesn't look like passwords came over correctly, so if you are having issues logging in, just do a reset password and you should be good to go!

    We are looking forward to having you all back!

    ~judda

    • Thanks 2
  9. I am not a lawyer, nor have any variety of that background.  My personal opinion on this matter is, it really depends on two things:

    1. The agreement when you made the art - was it specific to the site or could you re-sellf?
    2. Were you paid for the art?

    If you were paid for the art, although you own some variety of ownership, it cannot be resold unless the other party also agrees with it being resold no matter how much you want to.

    ~judda

×
×
  • Create New...