DEV Community

Cover image for A L I E N - S O L I T A R E
Peter Vivo
Peter Vivo

Posted on • Edited on

A L I E N - S O L I T A R E

This is a submission for the Web Game Challenge, Build a Game: Alien Edition

What I Built

A L I E N - S O L I T A R E
powered by jsdoc-duck

TLDR: play: alien-solitare.vercel.app How to play are included.

Image description
finally I reach the status where images don't selected randomly

Technical Achievement: I created a small jsDoc source React state handling npm module called: jsdoc-duck but until now I don't write any example application for it, I think this Challange is a right time for do it, and proof my module concept are working. Also proof the jsDoc working fine, and usable to typesafe JS coding without TypeScript.

Plagiarism: Saddly my time is very limited, so a first moment I write down the base concept to my phone meanwhile of passenger of country drive ( 2hr ) in temux and vim. My plane was 2 or 3 day development time is need to be enough, but I am not the fastes developer. That why I choose this game method which is very lovely, mid complex, used by: Card Crawl - base idea, reworked that game mechanism to Alien theme.

Art: A previous year I spended to create many (60K+) AI generated images with (dream.ai, clipDrop, ChatGPT) , so I have enough Sci-Fi related which is handy for this game.

Something above us!

Aliens or worst. For solving our mankind agression we are decide: stop the war on Earth, and let's go outside and conquerer as many planet as possible - we hope to find at least one. Each political group and great company agree to start exploring a different direction!

"We ended the war on Earth by starting a war in the stars."

Image description

Key Code:

duck working according this developer declared type contain all actions with their types

/**
 * @typedef { |
 * { type: "CREATE_DECK", payload: Card[] } |
 * { type: "SHUFFLE_DECK" } |
 * { type: "RELEASE_CARD", payload: SlotId } |
 * { type: "DRAG_START", payload: {from:SlotId, card:Card} } |
 * { type: "MOVE_CARD", payload: Card } |
 * { type: "DRAG_END", payload: SlotId } |
 * { type: "PLAY_CARD", payload: {actor:Card, slotId:SlotId } } |
 * { type: "GO_ON", payload: Phases } |
 * { type: "WHAT_IS_NEXT" }
 * } Actions
 */
Enter fullscreen mode Exit fullscreen mode

Demo

GitHub logo Pengeszikra / alien-solitare

jsdoc-duck example game for dev.io Challenge

This is a submission for the Web Game Challenge, Build a Game: Alien Edition

What I Built

A L I E N - S O L I T A R E powered by jsdoc-duck

Technical Achievement: I created a small jsDoc source React state handling npm module called: jsdoc-duck but until now I don't write any example application for it, I think this Challange is a right time for do it, and proof my module concept are working. Also proof the jsDoc working fine, and usable to typesafe JS coding without TypeScript.

Plagiarism: Saddly my time is very limited, so a first moment I write down the base concept to my phone meanwhile of passenger of country drive ( 2hr ) in temux and vim. My plane was 2 or 3 day development time is need to be enough, but I am not the fastes developer. That why Iā€¦

jsdoc-duck - npm

react/jsdoc minimal typesafe state handling. Latest version: 0.0.5, last published: 2 months ago. Start using jsdoc-duck in your project by running `npm i jsdoc-duck`. There are no other projects in the npm registry using jsdoc-duck.

favicon npmjs.com

Journey

Under heavy development:

Image description

... when the drag and drop are start working

Image description

... deck building according Crawl Card Deck List plagium

Image description

I was rethink, this is a perfect example of interactive TDD development in process, because on editor I was modify the cardCollections.js and on the screen I continous show the result, which is collected this query on proper format, on game page.

<pre>{JSON.stringify({
  hostile: state.deck.filter(card => card.side === "DARK" && card.work === "HIT").map(card => card.power).sort(descend).join(),
  fighter: state.deck.filter(card => card.side === "LIGHT" && card.work === "HIT").map(card => card.power).sort(descend).join(),
  survivor: state.deck.filter(card => card.side === "LIGHT" && card.work === "PROTECT").map(card => card.power).sort(descend).join(),
  medicine: state.deck.filter(card => card.side === "LIGHT" && card.work === "RAISE").map(card => card.power).sort(descend).join(),
  assets: state.deck.filter(card => card.side === "LIGHT" && card.work === "WORTH").map(card => card.power).sort(descend).join(),
  skill: state.deck.filter(card => card.side === "LIGHT" && card.work === "SKILL").map(card => card.name).join(),
  debug: state.deck.filter(card => card.side !== "LIGHT" && card.side !== "DARK").map(card => card.id).join(),
  }, null, 2)}</pre>
Enter fullscreen mode Exit fullscreen mode

final rush aganst the time: just 9h left, and need to be finalize the game rule, replace a random images with a selected set, publish to somwhere the running code. This is still a POC, that why I choose jump into a middle of development, and the game core part will realise.

Image description

License: Open Source

[    ][    ][     ][         ] <- 4 possible card draw from deck
[item][hero][alien][spaceship] <- hero have solution points 
Enter fullscreen mode Exit fullscreen mode

Burn Out vs. Survive

Our Captain (represent you in the game) have a bunch of solution to facing with incoming problems. But you can also manage allys and collect the assets. Two possible outcome will happen: Captain run out of solution and that is lead to Burn Out. But if no more problems, then Captain Survive and happy after all. Until the next mission...

Code size by Tokei

Comments is the jsDoc type system.

Image description

Yellow are indicated TYPE in code

thx to jsDoc

Image description

Live Without CSS file

Instead CSS I using Tailwind, but for simplify it is directly linked to html as cdn:

<script src="https://cdn.tailwindcss.com"></script>
Enter fullscreen mode Exit fullscreen mode

Drawback: Not for product ready warning:

Image description
Previous image devtool log also show we can live without redux devtool, because we saw the ongoing react actions like in Redux just much lighter weight. Do not burn the woods!:
Image description

React Devtool

Proof to our game component structure keep as simple as possible.

Image description

Conclusion

So this game are very early POC state at right moment, but it is open source (jsdoc-duck also), so any one who is feel energy to improving this one will be a full functional game. This is a short feature list which is need to be develop:

  • some begining of game
  • card release animation
  • drop the Ally
  • skill cards
  • collect a new skill, captain card
  • more dangerous mission
  • UI graph
  • Redesign card border
  • high score
  • L5, L6, A3, S2 :: Space-ship / Location dynamic table size feature
  • responsive design
  • ... lot of in my head, but need to be finishing the code MVP version.

Image description

Happy Coding! Remember: Something Above Us! quack . quack .. quack ....

Top comments (4)

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

When I was start implementing the drag and drop parts which is hold a main branch of game rule. A first iteration was a if statement, but shortly identifyed, that is a too painfull, that why I choose a switch - case - return solution, whicsh is wery familar on React programmin. Just the returning state is need to be rework a good old redux reducer way.

/** @type {(move:Move) => State} */
const tableRule = (move) => {
  console.log('move::', move)
  const { table } = state;
  switch (move.join()) {

    case _(["LINE", "ACTIVE", "ALLY", "FIX"]):
    case _(["STORE", "ACTIVE", "ALLY", "FIX"]): {
      // captain solution fix aka heal
      if (table[to].card) return state;
      const captain = table.HERO.card;  
      const regen = Math.min(
          captain.maxPower - captain.power, 
          card.power
       );
      captain.power += regen;
      return {
        ...state,
        table: {
          ...table,
          [from]: { ...table[from], card: null }, 
          [to]: { ...table[to], card },
          HERO: { ...table.HERO, card: captain }
        },
        fly: null,
      };
      case _(["STORE", "ACTIVE", "ALLY", "ENGAGE"]):
      case _(["STORE", "ACTIVE", "ALLY", "GUARD"]):
      case _(["STORE", "ACTIVE", "ALLY", "SKILL"]):
        return table[to].card
          ? state
          : playOnTable(table)
        ;
      case: default: return state;
    }

  }
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
pengeszikra profile image
Peter Vivo • Edited

The missing piece of my game was the easy interaction and animation. Instead of drag and drop which is working on desktop perfect. This click based with mooving anim is better. Bonus: this code a pure one page HTML just tailwind include. Using template tag.

Also critical part is the responsibility: This layout POC just works on portrait mode. Some minor fixes are need for this. But this POC can show the possibilities: have a life without framework. ( just CSS framework a good reason ).

Bit harder to remove drag and drop from my code and implement this method.

Collapse
 
pengeszikra profile image
Peter Vivo

Mobile Last

known issue: This development process using Mobile Last philosophy, I don't tested on mobile until yesterday, result: Basic HTML drag and drop solution is don't work fine on mobile, so sure to make reworking ... soon.

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

responsive version on air:
Image description