can my "big" project work in construct?

Discussion and feedback on Construct 2

Post » Tue Jun 16, 2015 8:04 am

Greetings Construct users!
I have in the past made many minor casual projects on programs such as RPG Maker, Construct classic and 2, etc. Lately me and my friends have been throwing around a project idea and considering making it a serious game. The only issue is find the right game making engine for our project.

Basically the first thing I need to get out of the way is that online capabilities is a must. I have seen that construct has pulled this off to some extent. The ability to face other people and have a rankings system of some sort is really the meat of it though.
What we are working on is a turn based strategy, that also has a 2D side scrolling shoot em up in there (recruit guys in the shoot em up for the turn based). Graphically this game wouldn't be intensive, and I have been able to make shells of both parts of the game in construct, though not yet combine the two. We have some graphic designers and programmers on board with us, and I myself am of the business/accounting professions.

Is this project doable in Construct? Do you guys know a better program for this project?
Any and all feedback would be greatly appreciated :)
B
2
Posts: 2
Reputation: 154

Post » Tue Jun 16, 2015 11:14 am

Hi !

C2 sounds perfectly suitable for this project ; just be aware that the built-in multiplayer functionalities are designed around the host/peer architecture, not server/client. It may or may not be an issue depending on your concept
Image
B
23
S
9
Posts: 237
Reputation: 2,207

Post » Tue Jun 16, 2015 12:15 pm

Refeuh wrote:just be aware that the built-in multiplayer functionalities are designed around the host/peer architecture, not server/client. It may or may not be an issue depending on your concept

"host" and "peer" are just different names for "server" and "client", it's the same architecture. The connections are what go peer-to-peer, but it's still an authoritative server model - the host acts as the server.
Scirra Founder
B
387
S
230
G
87
Posts: 24,249
Reputation: 192,240

Post » Tue Jun 16, 2015 12:33 pm

Don't know about multiplayer, but "big" project are perfectly fine with C2. My current project is an ecosystem simulation with 7200 events, using largely functions & families, where the world evolves according to natural rules, seasons, animals reproduction, plants getting energy from the sun... thousands objects on a large map having their own life span. So yes, C2 allows you to do a lot of stuff if you know how to.
B
62
S
22
G
4
Posts: 357
Reputation: 6,478

Post » Tue Jun 16, 2015 12:44 pm

it's still an authoritative server model - the host acts as the server


Absolutely, fair statement - my apologies for the misleading over-simplification, I only mentioned this as a quick way to make sure the OP, who doesn't seem to have used C2 yet, wouldn't expect distinct modules for the client and server sides, like some other tools do, and would need to understand the symmetry between peers to develop proper host "authority" logic
Image
B
23
S
9
Posts: 237
Reputation: 2,207

Post » Thu Jun 18, 2015 5:41 pm

Thank you for all the responses. I have continued the research on server functions such as online play and rankings and it seems like a lot of work. Server work 99 to game 1 as a ratio. At least for the server, I may hire someone. Thanks for the feedback guys!
B
2
Posts: 2
Reputation: 154

Post » Fri Jun 19, 2015 8:52 am

best choice youl ever make, using c2 :) go for it, and yes a good decision finding someone to hire for the server side setup. the rest is 10 minutes away from your finished game :D cheers
B
70
S
20
G
67
Posts: 1,314
Reputation: 42,301

Post » Fri Jun 19, 2015 9:08 am

I work with Smartfox 2X Server. (100 user slots is free)
It is very doable, but very hard to understand for beginners.

A few hundret lines java, some mysql tables and it does all you want. That is fast done. :D
But you also need to write one or more Construct plugins to handle sends and data.
And you need a RootServer, thats also a problem. Not to buy, but to hold it safe. Better is Photon, it works with cloud, but I dont know how it works...

In my project, and I think its normal, the Construct part is much bigger! Where, what, when send or get and work with much big dictionarys.
In SFS its only income message, set or get some data, send a message back, no big work.

To be able to assess the work, I give you an example how a SFS Server extension can look like:
CreateCharacter.java: (looks harder as it is, most is duplicated...)
Code: Select all
package com.zerno.main;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.smartfoxserver.v2.db.IDBManager;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;
import com.smartfoxserver.v2.extensions.ExtensionLogLevel;
import com.smartfoxserver.v2.extensions.SFSExtension;
import com.zerno.helper.Globals.ErrorCodes;
import com.zerno.helper.SendError;
import com.zerno.helper.Validators;

public class CreateCharacter extends BaseClientRequestHandler {

   @Override
   public void handleClientRequest(User user, ISFSObject params) {
      
      // create objects
      SFSExtension ext = getParentExtension();
      IDBManager dbManager = getParentExtension().getParentZone().getDBManager();         
      Connection cn = null;
      
      // create vars
      int acc_id = user.getVariable("acc_id").getIntValue();
      String className = this.getClass().getSimpleName();
      int char_count_max = 0;
      
      // create vars from params
      String name = "";
      String second_name = "";
      int gender = 0;
      int race = 0;
      int map = 0;
      int location_x = 0;
      int location_y = 0;
      int location_a = 0;
      String look = "";
      
      try{ name = params.getUtfString("name"); }
      catch(Exception e)
      {
         // send name string error
         new SendError(ext, className, user, ErrorCodes.INVALID_CHAR_NAME_STRING, e.getMessage());
         return;
      }
      try{ second_name = params.getUtfString("second_name"); }
      catch(Exception e)
      {
         // send name string error
         new SendError(ext, className, user, ErrorCodes.INVALID_CHAR_SECOND_NAME_STRING, e.getMessage());
         return;
      }
      try   { gender = params.getInt("gender"); }
      catch(Exception e)
      {
         // send gender int error
         new SendError(ext, className, user, ErrorCodes.INVALID_GENDER_INTEGER, e.getMessage());
         return;
      }
      try { race = params.getInt("race");   }
      catch(Exception e)
      {
         // send race int error
         new SendError(ext, className, user, ErrorCodes.INVALID_RACE_INTEGER, e.getMessage());
         return;
      }
      try { look = params.getSFSObject("look").toJson(); }
      catch(Exception e)
      {
         // send look string error
         new SendError(ext, className, user, ErrorCodes.INVALID_LOOK_OBJECT, e.getMessage());
         return;
      }
      
      // check name string
      if(!Validators.validate(ErrorCodes.INVALID_CHAR_NAME_STRING, name))
      {
         // send name string error
         new SendError(ext, className, user, ErrorCodes.INVALID_CHAR_NAME_STRING, "");
         return;
      }
      // check second_name string
      if(!Validators.validate(ErrorCodes.INVALID_CHAR_SECOND_NAME_STRING, second_name))
      {
         // send name string error
         new SendError(ext, className, user, ErrorCodes.INVALID_CHAR_SECOND_NAME_STRING, "");
         return;
      }
      // check gender int
      if (!Validators.validate(ErrorCodes.INVALID_GENDER_INTEGER, gender))
      {
         // send gender int error
         new SendError(ext, className, user, ErrorCodes.INVALID_GENDER_INTEGER, "");
         return;
         
      }
      // check race int
      if(!Validators.validate(ErrorCodes.INVALID_RACE_INTEGER, race))
      {
         // send race int error
         new SendError(ext, className, user, ErrorCodes.INVALID_RACE_INTEGER, "");
         return;
      }
      
      // create SQL connection
      try
      {
         cn = dbManager.getConnection();
         PreparedStatement st = null;
         ResultSet rs = null;
         
         // get char_count_max
         try
         {
            // create SQL query
              st = cn.prepareStatement("SELECT `char_count_max` FROM `user_accounts` where `acc_id` = ? ");
             st.setInt(1, acc_id);
              rs = st.executeQuery();
             
             // verify that a record was found
             if (rs.first())
             {
                // set var
                char_count_max = rs.getInt("char_count_max");
             }
             else
             {
                // send unknown acc_id error
                new SendError(ext, className, user, ErrorCodes.INVALID_ACCOUNTID, "");
               return;
             }
         }
         catch (SQLException e)
         {
            // send SQL error
            new SendError(ext, className, user, ErrorCodes.SQL_ERROR, e.getMessage());
            return;
         }
         finally
         {
            // close statement and result
            try { if( rs != null ) rs.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
            try { if( st != null ) st.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
         }
         
         // get character count
         try
         {
            // create SQL query
              st = cn.prepareStatement("SELECT COUNT(*) FROM `user_characters` where `acc_id` = ? ");
             st.setInt(1, acc_id);
              rs = st.executeQuery();
             
             // verify that record was found
             if (rs.first())
             {
                // check character space
                if(rs.getInt("COUNT(*)") >= char_count_max)
                {
                   // send character space error
                   new SendError(ext, className, user, ErrorCodes.NOT_ENOUGH_CHARACTER_PLACES, "");
                  return;
                }
             }
         }
         catch (SQLException e)
         {
            // send SQL error
            new SendError(ext, className, user, ErrorCodes.SQL_ERROR, e.getMessage());
            return;
         }
         finally
         {
            // close statement and result
            try { if( rs != null ) rs.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
            try { if( st != null ) st.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
         }
         
         // get char_count_max
         try
         {
            // create SQL query
              st = cn.prepareStatement("SELECT * FROM `race_positions` where `race_id` = ? ");
             st.setInt(1, race);
              rs = st.executeQuery();
             
             // verify that a record was found
             if (rs.first())
             {
                // set var
                map = rs.getInt("map");
                location_x = rs.getInt("location_x");
                location_y = rs.getInt("location_y");
                location_a = rs.getInt("location_a");
             }
             else
             {
                // send unknown acc_id error
                new SendError(ext, className, user, ErrorCodes.INVALID_RACE, "");
               return;
             }
         }
         catch (SQLException e)
         {
            // send SQL error
            new SendError(ext, className, user, ErrorCodes.SQL_ERROR, e.getMessage());
            return;
         }
         finally
         {
            // close statement and result
            try { if( rs != null ) rs.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
            try { if( st != null ) st.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
         }
         
         // insert character
         try
         {
            // create SQL query
            st = cn.prepareStatement("INSERT into `user_characters`(`acc_id`, `name`, `second_name`, `gender`, `race`, `current_map`, `location_x`, `location_y`, `location_a`, `look`) values ( ? , ? , ?, ?, ?, ?, ?, ?, ?, ? )");
            st.setInt(1, acc_id);
            st.setString(2, name);
            st.setString(3, second_name);
            st.setInt(4, gender);
            st.setInt(5, race);
            st.setInt(6, map);
            st.setInt(7, location_x);
            st.setInt(8, location_y);
            st.setInt(9, location_a);
            st.setString(10, look);
            st.executeUpdate();
         }
         catch (SQLException e)
         {
            // send SQL error
            new SendError(ext, className, user, ErrorCodes.SQL_ERROR, e.getMessage());
            return;
         }
         finally
         {
            // close statement and result
            try { if( rs != null ) rs.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
            try { if( st != null ) st.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
         }
      }
      catch (SQLException e)
      {
         // send SQL error
         new SendError(ext, className, user, ErrorCodes.SQL_ERROR, e.getMessage());
         return;
      }
      finally
      {
         //close connection
         try { if( cn != null ) cn.close(); } catch( Exception e ) {new SendError(ext, className, user, 0, e.getMessage());}
      }
      
      // send success
      send(className + "Success", null, user);
      trace(ExtensionLogLevel.INFO, className + ": " + acc_id);
   }
   
}


My extension file list:
Image
Sorry for my bad english, but I really do my best! And use and check with Google Translator.
B
10
S
4
G
1
Posts: 158
Reputation: 1,303


Return to Construct 2 General

Who is online

Users browsing this forum: tumira and 1 guest