Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Conditional Time Battle System

I really like how the Conditional Time Battle System (CTB) from Final Fantasy X fits the style of my game. I was wondering if anyone can recreate it or has it on hand. What I want for the script, though, is that I'll be able to set the delay for certain skills or keep it standard for the rest of them. Basically, I just want to be able to adjust the delay for each character's turn at will.

If anyone can provide a script or make one for me, I'd gladly appreciate it.

-Jae
 

Atoa

Member

I have this one.
Code:
 

#==============================================================================

# CTB

#==============================================================================

class RPG::Skill

    CP_COST_DELAY = 300 

    CP_COST_SPELL = 300 

end

 

module CTB_Define

  SPELL_STATE_ID = 300

  CP_COST_ITEM   = 200 

  CP_COST_ATTACK  = 300 

  CP_COST_GUARD   = 200 

  CP_COST_NOTHING = 100 

  CP_COST_ESCAPE  = 100 

  CP_COST_SKILL  = [0,300,300,400,300,300,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,400,550,250,350,250,350,250,350,250,350,250,350,250,350,250,350,250,350,250,350,250,350,400,400,400,400,200,300,400,500,200,300,400,500,200,300,400,500,200,300,400,500,200,300,400,500,200,300,400,500,900]

end

 

#==============================================================================

#  RPG::Skill

#==============================================================================

module RPG

  class Skill

     def name

       name = @name.split(/,/)[0]

       return name != nil ? name : ''

     end

     def delay

       name = @name.split(/,/)[1].to_i

       return name != nil ? name : CP_COST_DELAY

     end

     def spell

       name = @name.split(/,/)[2].to_i

       return name != nil ? name : CP_COST_SPELL

     end

  end

end

 

#==============================================================================

#  Window_CTB

#==============================================================================

class Window_CTB < Window_Base

  include CTB_Define

  #--------------------------------------------------------------------------

  def initialize(avg)

     super(0, 320, 160, 160)

     self.contents = Bitmap.new(self.width - 32, self.height - 32)

     @agi_avg = avg

     @names = []

  end

  #--------------------------------------------------------------------------

  def refresh

     self.contents.clear

      self.contents.font.name = $defaultfonttype

     self.contents.font.size = 20

     self.contents.font.color = system_color

     self.contents.font.size = 16

     self.contents.draw_text(0, 0, 100, 17, "Turn Ratio")

     @names = []

     get_cps

     @names.sort!{|a,b| b[0] <=> a[0] }   

     h = 0

     self.contents.font.size = 17

     for i in 0...6

       @nam = @names[i]

       if @nam == nil

         break

       end

       x = 4

       y = 18 * h + 17

       if @nam[0] >= 500 

         if @nam[2] == true

           self.contents.font.color = Color.new(230, 255, 255, 255)

         else

            self.contents.font.name = $defaultfonttype

     self.contents.font.size = 12

           self.contents.font.color = normal_color

         end

       else

         if @nam[2] == true

           self.contents.font.color = Color.new(190, 225, 225, 255)

         else

           self.contents.font.color = disabled_color

         end

       end

       self.contents.draw_text(x, y, 128, 18, @nam[1])

       h += 1

     end

  end

  #--------------------------------------------------------------------------

  def get_cps

     i = 0

     while @names.size < 15

       for member in $game_party.actors + $game_troop.enemies

         next if member.dead? or !member.exist?

         cp = CP_COST_ATTACK * @agi_avg / member.agi # ????????CP???

         if i == 1 and member.current_action.kind == 1

           skill = $data_skills[member.current_action.skill_id]

           cp = CP_COST_SKILL[skill.id] * @agi_avg / member.agi

         end

         cp = member.cp - (cp * i)

         if i == 0

           spell = member.state?(SPELL_STATE_ID)

         else

           spell = false

         end

         @names.push([cp, member.name, spell])

       end

       i += 1

     end

  end

  #--------------------------------------------------------------------------

  def names_empty

     if @names == []

       return true

     else

       return false

     end

  end

end

 

#==============================================================================

# Window_CTB_All

#==============================================================================

class Window_CTB_All < Window_Base

  #--------------------------------------------------------------------------

  include CTB_Define

  #--------------------------------------------------------------------------

  def initialize(avg)

     super(0, 0, 160, 480)

     self.contents = Bitmap.new(self.width - 32, self.height - 32)

      self.contents.font.name = $defaultfonttype

     self.contents.font.size = 12

     @agi_avg = avg

     @names = []

     get_init_cps

     @names.sort!{|a,b| b[0] <=> a[0] }

  end

  #--------------------------------------------------------------------------

  def refresh(id)

     self.contents.clear

      self.contents.font.name = $defaultfonttype

     self.contents.font.size = 20

     self.contents.font.color = system_color

     self.contents.font.size = 18

     self.contents.draw_text(0, 0, 100, 20, "Turn Ratio")

     h = 0

     self.contents.font.size = 19

     for i in id-1...[id+18,50].min

       @nam = @names[i]

       if @nam == nil

         break

       end

       x = 4

       y = 22 * h + 20

       if @nam[0] >= 500

         if @nam[2] == true

           self.contents.font.color = Color.new(230, 255, 255, 255)

         else

           self.contents.font.color = normal_color

         end

       else

         if @nam[2] == true

           self.contents.font.color = Color.new(190, 225, 225, 255)

         else

           self.contents.font.color = disabled_color

         end

       end

        self.contents.font.name = $defaultfonttype

     self.contents.font.size = $fontsize

       self.contents.draw_text(x, y, 32, 22, (i+1).to_s)

       self.contents.draw_text(x+32, y, 128, 22, @nam[1])

       h += 1

     end

  end

  #--------------------------------------------------------------------------

  def get_init_cps

     i = 0

     while @names.size < 75

       for member in $game_party.actors + $game_troop.enemies

         next if member.dead? or !member.exist?

         cp = CP_COST_ATTACK * @agi_avg / member.agi

         if i == 1 and member.current_action.kind == 1

           @skill = $data_skills[@active_battler.current_action.skill_id]

           skill = $data_skills[member.current_action.skill_id]

           cp = CP_COST_SKILL[skill.id] * @agi_avg / member.agi

         end

         cp = member.cp - (cp * i)

         if i == 0

           spell = member.state?(SPELL_STATE_ID)

         else

           spell = false

         end

         @names.push([cp, member.name, spell])

       end

       i += 1

     end

  end

  #--------------------------------------------------------------------------

  def names_full(id)

     if @names[id] == nil

       return false

     end

     return true

  end

end

 

#==============================================================================

#  Window_PartyCommand

#==============================================================================

class Window_PartyCommand < Window_Selectable

  #--------------------------------------------------------------------------

  def initialize

     super(0, 0, 640, 64)

     self.contents = Bitmap.new(width - 32, height - 32)

     self.back_opacity = 160

     @commands = ["Battle", "Special", "Escape"]

     @item_max = 3

     @column_max = 3

     draw_item(0, normal_color)

     draw_item(1, normal_color)   

     draw_item(2, $game_temp.battle_can_escape ? normal_color : disabled_color)

     self.active = false

     self.visible = false

     self.index = 0

  end

  #--------------------------------------------------------------------------

  def draw_item(index, color)

     self.contents.font.color = color

     rect = Rect.new(80 + index * 160 + 4, 0, 128 - 10, 32)

     self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))

     self.contents.draw_text(rect, @commands[index], 1)

  end

  #--------------------------------------------------------------------------

  def update_cursor_rect

     self.cursor_rect.set(80 + index * 160, 0, 128, 32)

  end

end

#==============================================================================

#  Window_BattleStatus

#==============================================================================

class Window_BattleStatus < Window_Base

  #--------------------------------------------------------------------------

  def initialize

     super(160, 320, 480, 160)

     self.contents = Bitmap.new(width - 32, height - 32)

     @level_up_flags = [false, false, false, false]

     refresh

  end

  #--------------------------------------------------------------------------

  def refresh

     self.contents.clear

      self.contents.font.name = $defaultfonttype

     self.contents.font.size = 19

     @item_max = $game_party.actors.size

     for i in 0...$game_party.actors.size

       actor = $game_party.actors[i]

       actor_x = i * 115 + 9

       draw_actor_name(actor, actor_x, 0)

       draw_actor_hp(actor, actor_x, 31, 90)

       draw_actor_sp(actor, actor_x, 65, 90)

       if @level_up_flags[i]

         self.contents.font.color = normal_color

         self.contents.draw_text(actor_x, 99, 120, 32, "Level Up!")

       else

         draw_actor_state(actor, actor_x, 99)

       end

     end

  end

end

 

#==============================================================================

# ? Game_Battler

#==============================================================================

class Game_Battler

  include CTB_Define

  #--------------------------------------------------------------------------

  attr_accessor :now_guarding             

  attr_accessor :cp                       

  #--------------------------------------------------------------------------

  alias ctb_sys_inputable? inputable?

  def inputable?

     bool = ctb_sys_inputable?

     return false if state?(SPELL_STATE_ID)

     return false if bool == false

     return false if @cp < 500

     return true

  end

end

 

#==============================================================================

#  Game_Actor

#==============================================================================

class Game_Actor < Game_Battler

#--------------------------------------------------------------------------

alias ctb_sys_setup setup

  def setup(actor_id)

     ctb_sys_setup(actor_id)

     @cp = 0

     @now_guarding = false

  end

  #--------------------------------------------------------------------------

  def screen_x

     if self.index != nil

       return self.index * 115 + 215

     else

       return 0

     end

  end

end

 

#==============================================================================

#  Game_Enemy

#==============================================================================

class Game_Enemy < Game_Battler

  #--------------------------------------------------------------------------

  alias ctb_sys_initialize initialize

  def initialize(troop_id, member_index)

     ctb_sys_initialize(troop_id, member_index)

     @cp = 0

     @now_guarding = false

  end

end

 

#==============================================================================

#  Game_BattleAction

#==============================================================================

class Game_BattleAction

#--------------------------------------------------------------------------

attr_accessor :spell                    # ??????

#--------------------------------------------------------------------------

alias ctb_sys_initialize initialize

  def initialize

     @spell = false # spell?false???

     ctb_sys_initialize

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_clear clear

  def clear

     return if @spell

     ctb_sys_clear

  end

end

 

#==============================================================================

#  Scene_Battle

#==============================================================================

class Scene_Battle

  include CTB_Define

  #--------------------------------------------------------------------------

  def main

     $game_temp.in_battle = true

     $game_temp.battle_turn = 0

     $game_temp.battle_event_flags.clear

     $game_temp.battle_abort = false

     $game_temp.battle_main_phase = false

     $game_temp.battleback_name = $game_map.battleback_name

     $game_temp.forcing_battler = nil

     $game_system.battle_interpreter.setup(nil, 0)

     @troop_id = $game_temp.battle_troop_id

     $game_troop.setup(@troop_id)  

     s1 = $data_system.words.attack

     s2 = $data_system.words.skill

     s3 = $data_system.words.guard

     s4 = $data_system.words.item

     @actor_command_window = Window_Command.new(115, [s1, s2, s3, s4])

     @actor_command_window.y = 160

     @actor_command_window.back_opacity = 0

     @actor_command_window.active = false

     @actor_command_window.visible = false

     @party_command_window = Window_PartyCommand.new

     @help_window = Window_Help.new

     @help_window.back_opacity = 0

     @help_window.visible = false

     @status_window = Window_BattleStatus.new

     @message_window = Window_Message.new

     @avg = read_avg

     @ctb_window = Window_CTB.new(@avg)

     first_cp

     @spriteset = Spriteset_Battle.new

     @wait_count = 0

     if $data_system.battle_transition == ""

       Graphics.transition(20)

     else

       Graphics.transition(40, "Graphics/Transitions/" +

         $data_system.battle_transition)

     end

     start_phase1

     loop do

       Graphics.update

       Input.update

       update

       if $scene != self

         break

       end

     end

     $game_map.refresh

     Graphics.freeze

     @actor_command_window.dispose

     @party_command_window.dispose

     @help_window.dispose

     @status_window.dispose

     @message_window.dispose

     @ctb_window.dispose

     if @skill_window != nil

       @skill_window.dispose

     end

     if @skill_window != nil

       @skill_window.dispose

     end

     if @item_window != nil

       @item_window.dispose

     end

     if @result_window != nil

       @result_window.dispose

     end

     @spriteset.dispose

     if $scene.is_a?(Scene_Title)

       Graphics.transition

       Graphics.freeze

     end

     if $BTEST and not $scene.is_a?(Scene_Gameover)

       $scene = nil

     end

  end

  #--------------------------------------------------------------------------

  def update

     if $game_system.battle_interpreter.running?

       $game_system.battle_interpreter.update

       if $game_temp.forcing_battler == nil

         unless $game_system.battle_interpreter.running?

           unless judge

             setup_battle_event

           end

         end

         if @phase != 5

           @status_window.refresh

         end

       end

     end

     $game_system.update

     $game_screen.update

     if $game_system.timer_working and $game_system.timer == 0

       $game_temp.battle_abort = true

     end

     if @phase != 4

       cp_countup

     end

     @ctb_window.update

     @ctb_window.refresh if @ctb_window.names_empty

     @help_window.update

     @party_command_window.update

     @actor_command_window.update

     @status_window.update

     @message_window.update

     @spriteset.update

     if $game_temp.transition_processing

       $game_temp.transition_processing = false

       if $game_temp.transition_name == ""

         Graphics.transition(20)

       else

         Graphics.transition(40, "Graphics/Transitions/" +

           $game_temp.transition_name)

       end

     end

     if $game_temp.message_window_showing

       return

     end

     if @spriteset.effect?

       return

     end

     if $game_temp.gameover

       $scene = Scene_Gameover.new

       return

     end

     if $game_temp.to_title

       $scene = Scene_Title.new

       return

     end

     if $game_temp.battle_abort

       $game_system.bgm_play($game_temp.map_bgm)

       battle_end(1)

       return

     end

     if @wait_count > 0

       @wait_count -= 1

       return

     end

     if $game_temp.forcing_battler == nil and

        $game_system.battle_interpreter.running?

       return

     end

     case @phase

     when 1

       update_phase1

     when 2

       update_phase2

     when 3

       update_phase3

     when 4

       update_phase4

     when 5

       update_phase5

     when 6 

       update_ctb_all

     end

  end

  #--------------------------------------------------------------------------

  def start_phase2

     @phase = 2

     @actor_index = -1

     @active_battler = nil

     @actor_command_window.active = false

     @actor_command_window.visible = false

     $game_temp.battle_main_phase = false

     $game_party.clear_actions   

     unless $game_party.inputable?

       start_phase4

     end

     if @party_command_window.active != true

       start_phase3

     else

       update_phase2

     end

  end

  #--------------------------------------------------------------------------

  def update_phase2

     if Input.trigger?(Input::C)

       case @party_command_window.index

       when 0 

         $game_system.se_play($data_system.decision_se)

         start_phase3

       when 1  

         $game_system.se_play($data_system.decision_se)

         start_phase2_CTB

       when 2

         if $game_temp.battle_can_escape == false

           $game_system.se_play($data_system.buzzer_se)

           return

         end

         $game_system.se_play($data_system.decision_se)

         update_phase2_escape

       end

       return

     elsif Input.trigger?(Input::B)

       $game_system.se_play($data_system.cancel_se)

       start_phase3

     end

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_update_phase2_escape update_phase2_escape

  def update_phase2_escape

     for actor in $game_party.actors

       if actor.exist?

         actor.cp -= CP_COST_ESCAPE * @avg / actor.agi

       end

     end

     ctb_sys_update_phase2_escape

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_phase3_setup_command_window phase3_setup_command_window

  def phase3_setup_command_window

     ctb_sys_phase3_setup_command_window

     @active_battler.now_guarding = false

     @actor_command_window.x = @actor_index * 105 + 160

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_update_phase3_basic_command update_phase3_basic_command

  def update_phase3_basic_command

     if Input.trigger?(Input::X)

       $game_system.se_play($data_system.decision_se)

       @party_command_window.active = true

       @party_command_window.visible = true     

       start_phase2     

     else

       ctb_sys_update_phase3_basic_command

     end

  end

  #--------------------------------------------------------------------------

  def make_action_orders

     @action_battlers = []

     for enemy in $game_troop.enemies

       if enemy.cp >= 500

         @action_battlers.push(enemy)

       end

     end

     for actor in $game_party.actors

       if actor.cp >= 500

         @action_battlers.push(actor)

       end

     end

     for battler in @action_battlers

       battler.make_action_speed

     end

     @action_battlers.sort! {|a,b|

       b.current_action.speed - a.current_action.speed }

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_update_phase4_step1 update_phase4_step1

  def update_phase4_step1

     @ctb_window.refresh

     ctb_sys_update_phase4_step1

  end

  #--------------------------------------------------------------------------

  def update_phase4_step2

     unless @active_battler.current_action.forcing

       if @active_battler.restriction == 2 or @active_battler.restriction == 3

         @active_battler.current_action.kind = 0

         @active_battler.current_action.basic = 0

       end

       if @active_battler.restriction == 4

         $game_temp.forcing_battler = nil

         if @active_battler.cp >= 500

           @active_battler.remove_states_auto

           @active_battler.cp -= CP_COST_NOTHING * @avg / @active_battler.agi

           cp_countup

         end

         @phase4_step = 1

         return

       end

     end

     @target_battlers = []

     case @active_battler.current_action.kind

     when 0  # ??

       make_basic_action_result

     when 1  # ???

       make_skill_action_result

     when 2  # ????

       make_item_action_result

     end

     if @phase4_step == 2

       @phase4_step = 3

     end

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_make_basic_action_result make_basic_action_result

  def make_basic_action_result

     if @active_battler.current_action.basic == 0

       @active_battler.cp -= CP_COST_ATTACK * @avg / @active_battler.agi

     end

     if @active_battler.current_action.basic == 1

       @active_battler.cp -= CP_COST_GUARD * @avg / @active_battler.agi

     end

     if @active_battler.is_a?(Game_Enemy) and

        @active_battler.current_action.basic == 2

       @active_battler.cp -= CP_COST_ESCAPE * @avg / @active_battler.agi

     end

     if @active_battler.current_action.basic == 3

       @active_battler.cp -= CP_COST_NOTHING * @avg / @active_battler.agi

       $game_temp.forcing_battler = nil

       cp_countup

       @phase4_step = 1

       return

     end

     ctb_sys_make_basic_action_result

  end

  #--------------------------------------------------------------------------

  def make_skill_action_result

     @skill = $data_skills[@active_battler.current_action.skill_id]

     skill = $data_skills[@active_battler.current_action.skill_id]

     @status_window.refresh

     @ctb_window.refresh

     @help_window.set_text(@skill.name, 1)

     if @active_battler.state?(SPELL_STATE_ID)

       @active_battler.remove_state(SPELL_STATE_ID)

       @active_battler.current_action.spell = false

     else

       @active_battler.sp -= @skill.sp_cost

       if @skill.spell > 0

         @active_battler.cp -= CP_COST_SKILL[skill.id] * @avg / @active_battler.agi

         @active_battler.add_state(SPELL_STATE_ID)

         @active_battler.current_action.spell = true

       end

     end

     unless @active_battler.state?(SPELL_STATE_ID)

       @active_battler.sp += @skill.sp_cost

       unless @active_battler.current_action.forcing

         unless @active_battler.skill_can_use?(@skill.id)

           $game_temp.forcing_battler = nil

           @phase4_step = 1

           return

         end

       end

       @active_battler.sp -= @skill.sp_cost

       @active_battler.cp -= CP_COST_SKILL[skill.id] * @avg / @active_battler.agi

       @animation1_id = @skill.animation1_id

       @animation2_id = @skill.animation2_id

       @common_event_id = @skill.common_event_id

       set_target_battlers(@skill.scope)

       for target in @target_battlers

         target.skill_effect(@active_battler, @skill)

       end

    end

  end

  #--------------------------------------------------------------------------

  def make_item_action_result

  alias ctb_sys_make_item_action_result make_item_action_result

    ctb_sys_make_item_action_result

    @active_battler.cp -= CP_COST_ITEM * @avg / @active_battler.agi

  end

  #--------------------------------------------------------------------------

  alias ctb_sys_update_phase4_step6 update_phase4_step6

  def update_phase4_step6

    ctb_sys_update_phase4_step6

    cp_countup

  end

  #--------------------------------------------------------------------------

  def read_avg

    temp = 0

    for member in $game_party.actors + $game_troop.enemies

      temp += member.agi

    end

    temp /= $game_troop.enemies.size + $game_party.actors.size

    return temp

  end 

  #--------------------------------------------------------------------------

  def first_cp

    for member in $game_party.actors + $game_troop.enemies

      member.cp = [[5 * (rand(20) + 60) * member.agi / @avg, 0].max, 490].min

    end

  end

  #----------------------------------------------------------------------------

  def cp_countup   

    cpmin = 500

    edead = 0

    for enemy in $game_troop.enemies

      if enemy.dead? == true

        edead +=1

        enemy.cp = 0

        next

      end

      cpmin = [cpmin, 500 - enemy.cp].min

    end

    return if $game_troop.enemies.size == edead

    for actor in $game_party.actors

      if actor.dead? == true

        actor.cp = 0

        next

      end

      cpmin = [cpmin, 500 - actor.cp].min

    end

    return if cpmin <= 0

    for member in $game_party.actors + $game_troop.enemies

      next if member.dead?

      member.cp += cpmin

      next if member.cp < 500

      member.remove_states_auto

      plus = [member.maxsp * 5/ 100,1].max

      member.sp = [member.sp + plus,member.maxsp].min

      if member.slip_damage?

        member.slip_damage_effect

        member.damage_pop = true

      end

    end

    @status_window.refresh

  end

  #--------------------------------------------------------------------------

  def start_phase2_CTB

    @party_command_window.active = false

    @party_command_window.visible = false

    @phase = 6

    @ctb_window.visible = false

    @ctb_window_all = Window_CTB_All.new(@avg)

    @ctb_window_all.update

    @id = 1

    @ctb_window_all.refresh(@id)

  end 

  #--------------------------------------------------------------------------

  def update_ctb_all

    if Input.trigger?(Input::DOWN) or Input.repeat?(Input::DOWN)

      if @id < 50

        @id +=1

      else

        @id = 1

      end

      @ctb_window_all.refresh(@id)

    elsif Input.trigger?(Input::UP) or Input.repeat?(Input::UP)

      if @id > 1

        @id -= 1

      else

        @id = 50

      end

      @ctb_window_all.refresh(@id)

    elsif Input.trigger?(Input::L)

      @id = [@id-18,1].max

      @ctb_window_all.refresh(@id)

    elsif Input.trigger?(Input::R)

      @id = [@id+18, 50].min

      @ctb_window_all.refresh(@id)

    elsif Input.trigger?(Input::B)

      $game_system.se_play($data_system.cancel_se)

      @ctb_window.visible = true

      @ctb_window_all.dispose

      @party_command_window.active = true

      @party_command_window.visible = true     

      start_phase2     

    end

  end

end
 
Is it possible to change the turn delay for specific skills? For example, I have some skills that are really powerful that I would prefer have a larger delay than their counterpart.
 

Atoa

Member

not only you can... you MUST do it x]

Code:
 CP_COST_SKILL  = [0,300,300,400,300,300,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,300,300,400,400,550,250,350,250,350,250,350,250,350,250,350,250,350,250,350,250,350,250,350,250,350,400,400,400,400,200,300,400,500,200,300,400,500,200,300,400,500,200,300,400,500,200,300,400,500,200,300,400,500,900]

in this line are all skills delay, ordered by ID, if you think it confusing, do like this
CP_COST_SKILL[Skill_ID] = Skill_Delay
Code:
  CP_COST_SKILL  = []

  CP_COST_SKILL[1] = 300

  CP_COST_SKILL[2] = 300

  CP_COST_SKILL[3] = 400

i'm not 100% sure, but it looks that if an skill dont have an delay, it will cause errors.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top