XaiJu
thomasmoonkang

thomasmoonkang

patreon


thomasmoonkang posts

Saffron splash art concepts

Here are some concept art and the final render for Saffron's splash art!

The new style is looking really sleek and modern. I think it will give Duelists of Eden a really cool vibe.

Feel free to comment on what else you'd like to see from here

View Post

Local PvP Test

Of course there needs to be local PvP. But when you play online you'll be able to always play on the right or left side, up to you!

View Post

Art Style Test Poll


View Post

Saffron Art Style Test

Left or Right, which one do you like better?

View Post

Potential Poses for new art style test!

I've been communicating with HOAI Artworks as a new splash artist to give Duelists of Eden a fresh new style. We decided to do a render of Saffron to figure out what style we want to go with. HOAI (or Victor) has a kind of wet and shiny painting style which I think makes the game look really slick.

View Post

Custom Lobby functionality v1

Here's an old dev video from when I first got custom lobbies working with lobby code and everything!

View Post

Weekly Update #4 - Status Effects

In OSFE statuses were a list of enums , and all the code for them were kept in Being() which was not as modular as we would like.

I'm doing Status Effects completely differently this time around. There's a parent class of StatusEffect and all the different statuses will be their own class inheriting from it.

So what do we need for a Status Effect?

  • amount
  • duration
  • maximum duration
  • owner
  • display (around the character)
  • icon (on the status bar)
  • list of stacks (so that multiple instances do not interfere with each other)

OnAddNew(amount, duration, source)

OnAddExisting(amount, duration, source)

OnUpdate()

OnRemove()

OnAddStack(amount, duration, source)

OnRemoveStack()

CalculateStatusStacks()


This way we can easily customize functionality of each status and if we have duplicate functionality we can just inherit from a child class.

For example:

Frost overrides OnAddNew() to just have it call OnAddExisting() since they'll have the same functionality. OnAddExisting() creates the vfx adds the amounts, and deals damage if the total amount of frost is 3 or higher, then subtracts the amount by 3.

Okay I'm gonna eat dinner I'll continue this later.

View Post

Weekly Update #3 - Bouncing Projectiles

I wanted to add a character who's attacks chain bounced to other enemies. The number of bounces could be changed and I wanted it to be an addon to an existing attack, so I made it an Effect that can be added to a spell.

First let's break down the requirements:

Bounce strike should:

  • Prioritize new (un-hit) targets
  • Bounce to the closest target
  • If no new targets, bounce to the oldest target that is still alive

If bounces is greater than 0, we run the following actions:

1. Clone the spell

2. Reduce the new cloned spell's remaining bounces by 1

3. Set the new cloned spells'
location to: "NearestOtherToTargetHit"
pattern to: "PrioritizeUnhit"
origin tile to the hit unit's tile

4. If this is not the original spell, Despawn it

Now how do we prioritize unhit? Well, every time the spell hits an enemy, we can add that enemy to a list of Hit Beings. If the list already contains the enemy, we just move it to the end of the list. Then when we are prioritizing Un Hit enemies, we get the list of All Enemies and for each enemy in our list of Hit Beings, if the list of All Enemies contains the Hit Being, we move that Enemy to the end of the list.

This will happen in the order we hit the enemies, so the most recently hit Enemy will be at the very end of the "All Enemies" list!


I don't really like how you can embed webm's here since I'm  too lazy to make gifs. Maybe when this goes public I'll start making gifs? I'll just upload the webm for now.


View Post

Weekly Update #2 - Drag and drop


https://giant.gfycat.com/EsteemedVapidCobra.webm

We want moving units around to be as simple and easy as possible using drag and drop. Using Unit's Event Pointer Handler interfaces, we have access to OnBeginDrag(), OnDrag(), and OnEndDrag() which we'll trigger on the Unit itself.


OnBeginDrag() {

disable unit's collider so that we can raycast behind it

raise sorting layer

saved tile = starting tile

}


OnDrag() {

set transform to mouse position

if hovering over an empty tile, save it

if hovering over an occupied tile, save it

if hovering over another unit, save it 

}


OnEndDrag() {

if in the sell zone, sell the unit

if saved unit, swap places with it

if no unit to swap with, use the saved tile

reenable collider

reset sorting layer
}


There's a few more rules like not allowing drags during battle, and end drags on the enemy side of the field. Also checking the unit limit while still allowing tile swaps on the battlefield.

We also check whether we are moving the ally to the Bench or to the Field


Usability:

We use boxes that cover the entire tile as the colliders that the mouse can click, a lot of users may try to click the center of the character, but that won't work with multiple units next to each other. The only unoccupied space is on the tiles themselves.

We slightly highlight the occupied tiles and when hovering over a unit. Maybe we can highlight the saved tile while dragging too. May need to check if it's valid before that.


View Post

Weekly Update #1 - Effect Apps

In One Step From Eden, I kept a list of all Artifacts on each unit which I'll refer to as "Being"s. Every time something was triggered, like OnSpellCast, it would go through all of the Artifacts on the Being. Each artifact had a number of Effect Apps which basically contained a Trigger enum and an Effect function.

In a lot of cases it would go through all artifacts on all Beings because the enemies might have Artifacts that triggered when the player Shuffled or Moved for example. There were Artifacts that triggered every frame so we'd have to loop through them every frame. I tried using a system where we only checked them every x amount of frames but it didn't make a noticeable difference. This system was super expensive so I moved to using delegates.

Instead of going through all of them and checking which ones should be Triggered, we can use delegates. We'll need a delegate for every Trigger


So we check for the Trigger once, then we assign the method to the multicast delegate.


We still use switch case for the triggers and effects..


Still have to figure out how to add Checks like (if health is below 50%). We can't do them before we add to the delegates since the check results may change during runtime. Maybe we can add them as part of the method passed to the delegate?

Almost every effect uses these effect apps, including the ones in Spells and Traits.


Here's an example of an effect app in json that heals all allies.


That's it for now. We've also decided on a couple features being melee units and opening up the grid (like Serif's boss battle) once the battle start.

CYA

View Post

Auto Rogue - Initial Post

Starting a new side project, codenamed Auto Rogue. The idea is a hybrid of auto chess and roguelite. Since we have lots of code and sprites from One Step From Eden we're going to do the combat in a similar format. But we're going to be rebuilding the entire thing from the ground up!

Switching from tumblr to patreon for dev blogging. All the posts will probably be available to the public anyway, so we'll see how that goes. It would be nice to have extra funds that I can use exclusively for the game!

Here are the core pillars:

  1. Teambuilding
  2. Evolving and changing strategies
  3. Ability interaction mid-fight
  4. Artifacts

One of the interesting mechanics is varying traits and synergies. Since it's a roguelite we'll have to make sure to shake things up every run!

My biggest worry right now is readability. The 2d battle grid can get kind of packed  especially now that we're increasing the grid size to 8x6!

The biggest inspiration for the game is Teamfight Tactics, by far the best auto-battler out there. Though the champion/ability/item pool they have to work with is unfair!

Alright, let's do this!

View Post