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.

Custom Game.exe Source Code

Status
Not open for further replies.
I was a bit fed up that the only custom Game.exe projects out there were written in simplified Chinese and they are 100% written in 1 main file.

I basically rewrote it in English and hid the windows specific functions (and types) behind some classes, so the bulk of the RGSS stuff is in main.cpp and there is an RGSS3 binding written in RGSS3.h and .cpp as a class.

xiGameSrc.zip

this is by no means tidy code, but hopefully things are easier to navigate compared to the other custom game.exe projects.

This is a visual c++ 2013 project for RGSS3 projects.
 
Wow. I have way too many things to play around with but this just made top of the list. There's exciting stuff being done these days :eek:

Potentially daft question, but would this is aid cross-platforming?
 
Yes it would if someone were to rewrite the DLLs, I can very easily write this to be a cross platform executable but it still relies on the original windows DLLs
 
Xilef":1jtx17cc said:
Yes it would if someone were to rewrite the DLLs, I can very easily write this to be a cross platform executable but it still relies on the original windows DLLs

Meh, this is why theory and I embedded Ruby directly into an executable we were working on.
 
I think it's worth re-writing the RGSS libraries so .so and .dylib creation is possible.

I'm at the stage of trying to get Ruby hooks in my own executable right now :U
 
Also I think there should be some Licensing issues with this. Are you allowed to distribute RGSS DLL with this custom Game.exe like that? One workaround I see is distributing the game without it but making the user download RTP (of which you can probably only use the RGSS DLL).
 
@Drago del Fato : When we distribute our game, we are allowed, RPG Maker put the RGSS DLL in the installer.
@Xilef : Your program can only launch games in debug mode for the moment x)
But it's a good way to do it: using classes :3
Now for the Ruby hooks you'll have a lot of matters, good luck to find how to properly call the ruby functions...
 
@Nuri Yuri
Just because they distribute it themselves doesn't mean they allow everyone to distribute them in any way they please. RGSS DLL, in this instance, is being used in a way it was not intended for (i.e. by a custom Game.exe) so they might have a problem with this, I'm not a lawyer though.

@Xilef
What kind of Ruby hooks do you actually mean?
 
Using this exe or not, the actual game still must be made in RPG Maker, so it shouldn't be a problem. Don't quote me on that though. You're still distributing a game made with RPG Maker, you've just neglected to include their exe to run it and added your own.
 
Drago del Fato, there are no licensing issues as this is a clean-room program, it has no RGSS code and does not supply any RGSS code, you can use any compatible DLL with this program and it'll be fine.

And yes, the Eval() method in the RGSS3 class will set the $TEST flag to true, change that to false to stop the debug mode.
 
Seems the way most people hook with RGSS3 is abuse the Eval function and call some Win32API stuff to initialise their bindings, which is not ideal at all.

I remember discussing the idea of having custom DLL code running on a thread with a messaging system between RGSS and the thread so as to run the Win32API with little over-head, sounds a bit painful but if we can't find the addresses of the other ruby functions:
viewtopic.php?f=48&t=75669

Some help with the guess-work would be cool...!
 
Code:
[url=http://www.opensource.apple.com/source/ruby/ruby-75/ruby/variable.c]http://www.opensource.apple.com/source/ ... variable.c[/url]

[url=http://rxr.whitequark.org/mri/source/ext/socket/?v=1.8.7-p370]http://rxr.whitequark.org/mri/source/ex ... 1.8.7-p370[/url]

optlink

 

//Ruby

rb_warning 

rb_warn  //rb_warn("no super class for `%s', Object assumed", name);

rb_raise 

rb_raise2 10026210 //rb_raise(rb_eTypeError, "can't make subclass of Class");

rb_name_error  //rb_name_error(id, "%s is already defined", name)

rb_to_id 

global_id 

rb_global_entry 

rb_intern 100481B0

rb_id2name 

rb_check_type 

rb_secure 

rb_alias 10031AE0

rb_attr 

rb_fatal 

rb_block_given_p 10069E00

//rb_need_block 10069E30

LONG2NUM 

rb_yield 

rb_equal 

rb_check_type_string 

rb_class_new_instance 

rb_class_superclass 

rb_define_alloc_func 10032C00

rb_undef_alloc_func 

rb_data_object_alloc 

rb_obj_alloc 

rb_obj_call_init 

//rb_add_method 

str_new 100361A0 //ATTENTION METHODE D4APPEL DIFFERENTE ! __fastcall ? Nop, c'est pas du fastcall c'est de l'optimisation de gros bourrin.

rb_str_new 10036290 //ATTENTION METHODE D4APPEL DIFFERENTE !

rb_str_new2 10036340 //ATTENTION METHODE D4APPEL DIFFERENTE !

ary_new 10088D20

rb_ary_new 10088DC0 //???

rb_ary_new2 10088DA0

rb_ary_new3 10088DD0

rb_ary_new4 10088E50

---

 

//

rgss_print 

rgss_p 

//rgss_init 

 

 

//Eval

rb_f_eval 

eval 

rb_eval_string 

---

 

<!BASIC RUBY FUNC>

//String

rb_str_cmp_m  1

rb_str_equal  1

rb_str_hash_m  0

rb_str_casecmp  1

rb_str_plus  1

rb_str_times  1

rb_str_format_m  1

rb_str_aref_m  -1

rb_str_aset_m  -1

rb_str_insert  2

rb_str_length  0

rb_str_empty  0

rb_str_match  1

rb_str_match_m  1

rb_str_succ  0

rb_str_succ_bang  0

rb_str_upto_m  -1

rb_str_index_m  -1

rb_str_rindex_m  -1

rb_str_replace  1

rb_str_to_i  -1

rb_str_to_f  0

rb_str_to_s  0

rb_str_inspect  0

rb_str_dump  0

rb_str_upcase  0

rb_str_downcase  0

rb_str_capitalize  0

rb_str_swapcase  0

rb_str_upcase_bang  0

rb_str_downcase_bang  0

rb_str_capitalize_bang  0

rb_str_swapcase_bang  0

rb_str_hex  0

rb_str_oct  0

rb_str_split_m  -1

rb_str_reverse  0

rb_str_reverse_bang  0

rb_str_concat  1

rb_str_crypt  1

rb_str_intern  0

rb_str_include  1

rb_str_scan  1

rb_str_ljust  -1

rb_str_rjust  -1

rb_str_center  -1

rb_str_sub  -1

rb_str_gsub  -1

rb_str_chop  0

rb_str_chomp  -1

rb_str_strip  0

rb_str_lstrip  0

rb_str_rstrip  0

rb_str_sub_bang  -1

rb_str_gsub_bang  -1

rb_str_chop_bang  0

rb_str_chomp_bang  -1

rb_str_strip_bang  0

rb_str_lstrip_bang  0

rb_str_rstrip_bang  0

rb_str_tr  2

rb_str_tr_s  2

rb_str_delete  -1

rb_str_squeeze  -1

rb_str_count  -1

rb_str_tr_bang  2

rb_str_tr_s_bang  2

rb_str_delete_bang  -1

rb_str_squeeze_bang  -1

rb_str_each_line  -1

 

 

---

 

//Array 

rb_ary_aref  -1

rb_ary_fetch  -1

rb_ary_index  -1

rb_ary_rindex  -1

rb_ary_aset  -1

rb_ary_insert  -1

rb_ary_each_index  0

rb_ary_reverse_each  0

rb_ary_length  0

rb_ary_empty_p  0

//rb_ary_reverse 

rb_ary_reverse_bang  0

rb_ary_reverse_m  0

rb_ary_transpose  0

rb_ary_replace  1

rb_ary_fill  -1

rb_ary_times  1

rb_ary_equal  1

rb_ary_to_s  0

rb_ary_inspect  0

rb_ary_eql  1

rb_ary_at  1

rb_ary_first  -1

rb_ary_last  -1

rb_ary_concat  1

rb_ary_push_m  -1

rb_ary_unshift  -1

rb_ary_each  0

rb_ary_join_m  -1

rb_ary_sort  0

rb_ary_sort_bang  0

rb_ary_collect  0

rb_ary_collect_bang  0

rb_ary_delete  1

rb_ary_delete_at_m  1

rb_ary_reject  0

rb_ary_reject_bang  0

rb_ary_clear  0

rb_ary_includes  1

rb_ary_compact  0

rb_ary_compact_bang  0

---

 

//Hash

rb_hash_equal  1

rb_hash_aref  1

rb_hash_aset  2

rb_hash_default  -1

rb_hash_set_default  1

rb_hash_index  1

rb_hash_indexes  -1

rb_hash_size  0

rb_hash_empty_p  0

rb_hash_each  0

rb_hash_sort  0

rb_hash_keys  0

rb_hash_values  0

rb_hash_shift  0

rb_hash_delete  1

rb_hash_select  0

rb_hash_reject  0

rb_hash_reject_bang  0

rb_hash_clear  0

rb_hash_invert  0

rb_hash_has_key  1

rb_hash_has_value  1

<!BASIC RUBY FUNC>

 

//Class Variable

rb_mod_remove_cvar 

rb_define_class_variable 

rb_cvar_defined 

mod_av_set 

rb_cvar_get 

rb_cvar_set 

rb_cv_get 

rb_cv_set 

---

 

//Constantes

rb_const_set 

rb_define_const 

rb_const_defined_at 

rb_const_defined 

rb_const_defined_from 

rb_const_defined_0 

rb_mod_remove_const 

rb_const_get_at 

rb_const_get 

rb_const_get_from 

rb_const_get_0 

rb_define_global_const 

---

 

//Instance Variable

rb_ivar_get 

rb_attr_get 

rb_ivar_set 

rb_ivar_defined 

rb_obj_remove_instance_variable 

rb_iv_get 

rb_iv_set 

---

 

//Global Variable

rb_gv_set 

rb_gv_get 

rb_gvar_defined 

---

 

//Object

rb_obj_clone 

rb_obj_dup 

---

 

//Class

rb_funcall2 

rb_funcall3 

rb_define_sigleton_method 1005F050

rb_define_method 1005EDE0

rb_define_global_function 1005F0E0

rb_define_module 

rb_define_class_under 

rb_define_class 1005E5B0

rb_define_module_under 

rb_class_new 

rb_define_class_id 

rb_class_boot 

rb_set_class_path 

rb_class_inherited 

rb_mod_included_modules 

rb_mod_include_p 

rb_mod_ancestors 

rb_singleton_class 

rb_define_private_method 1005EE10

rb_define_module_function 

rb_define_alias 1005F130

rb_define_attr 

rb_scan_args 

rb_undef_method 1005EE40

rb_include_module 1005EA30

---

 

ruby_xmalloc 

ruby_xrealloc 

ruby_xfree 100563E0

ruby_xcalloc 

 

//ENDEF FUNCT//

 

 

//T_NYANYANYA

T_Class=

T_Module=

 

 

Macros :

#define FIXNUM_P(a) a&0x00000001

#define SYMBOL_P(a) (a&0x000000FF)==0x0e

#define NIL_P(a) a==0x04

 

RGSSInitialize 100035C0

RGSSGameMain 100036E0

RGSSSetupRTP 10003740

 

 

Classes

    kAudio ,

    kGraphics ,

    kInput ,

    kObject 102AC098,

    kModule 102AC08C,

    kClass ,

    kKernel 102AC080,

    kNilClass ,

    kSymbol ,

    kTrueClass ,

    kData ,

    kFalseClass ,

    kArray 102ABFE8,

    kString 102AC070,

    kFloat ,

    kInteger ,

    kNumeric ,

    kSprite ,

    kBitmap ,

    kViewport ,

    kRect ,

    kTone ,

    kColor ,

    kFont ,

  eTypeError ,

  eArgError 102AC108,

  eIndexError ,

  eException ,

  eStandardError ,

  kHash
I've shearched some functions, rb_define_sigleton_method, rb_define_method , rb_define_global_function , rb_define_class should work with the __cdecl calling convention...
 
Nuri Yuri":m5y71o66 said:
I've shearched some functions, rb_define_sigleton_method, rb_define_method , rb_define_global_function , rb_define_class should work with the __cdecl calling convention...
I can see that what you've posted is for RGSS1xx, we're dealing with RGSS301 which as you know is pretty well locked down (I have seen some assembly style function calling used around it [__fastcall maybe?], so that might be something I'll try next).

All I can find in RGSS301 that are C declared are the functions below:
RGSSAddRTPPath 0x100046d0 0x000046d0 1 (0x1) RGSS301.dll
RGSSAudioFinalize 0x100036b0 0x000036b0 2 (0x2) RGSS301.dll
RGSSAudioInitialize 0x10003610 0x00003610 3 (0x3) RGSS301.dll
RGSSClearRTPPath 0x100046f0 0x000046f0 4 (0x4) RGSS301.dll
RGSSErrorMessage 0x100040f0 0x000040f0 5 (0x5) RGSS301.dll
RGSSErrorType 0x100040d0 0x000040d0 6 (0x6) RGSS301.dll
RGSSEval 0x10003760 0x00003760 7 (0x7) RGSS301.dll
RGSSFinalize 0x10003600 0x00003600 8 (0x8) RGSS301.dll
RGSSGameMain 0x10003700 0x00003700 10 (0xa) RGSS301.dll
RGSSGC 0x10004720 0x00004720 9 (0x9) RGSS301.dll
RGSSGetBool 0x10003790 0x00003790 11 (0xb) RGSS301.dll
RGSSGetDouble 0x10003840 0x00003840 12 (0xc) RGSS301.dll
RGSSGetInt 0x100037c0 0x000037c0 13 (0xd) RGSS301.dll
RGSSGetPathWithRTP 0x10004120 0x00004120 14 (0xe)
RGSSGetRTPPath 0x100046b0 0x000046b0 15 (0xf)
RGSSGetStringACP 0x10003a00 0x00003a00 16 (0x10)
RGSSGetStringUTF16 0x10003b70 0x00003b70 17 (0x11)

I tried a brute-force approach with testing every pointer on the DLL from 0x0 to 0x10FFFFFF for the rb_define_module and running an in-game script that detects for the module to exist but none of those pointers worked, so I'm out of ideas time to do some analysis of __fastcall.
 
You're using RGSS301.dll XD
My pointers are for RGSS300.dll, can you send me RGSS301.dll ?

You'll never find anything by using Ruby, eval should probably not call rb_define_anything but rb_module_new that won't help you to create a module because it's like Module.new x)

Edit : Just forget about _fastcall, it isn't fastcall it's some new optimisation feature that send arguments in random register before calling the function when the function isn't exported.
 
From looking at those address I can see that my brute force programming detected ruby functions around those RGSS10X pointers you posted earlier, but I had no way of testing their functions, how did you figure them out for RMXP?

Edit: meant to write 300 not 10x, still getting confused with all these DLLs hanging around
 
Well those are standard ruby API functions which are always incorporated when you embed Ruby and they haven't changed much even today (I'm working currently with Ruby 2.1.0 on my engine and I didn't have to change a thing) so there is high chance that you can use them even here, but if they aren't in export table of the DLL there isn't much you can do about it, also take note that those are C functions, not C++.
 
The RGSS and Ruby functions are programmed in C/C++ so to make ruby functions work, the rb_define_method/class/module/etc... function should be called somewhere in the RGSS DLL.

For the functions like ruby_xfree, ruby_xmalloc or the functions like rb_gv_get that are called nowhere, I just watch something that looks like the assembly version of them.
To test them :
C:
<div class="c" id="{CB}" style="font-family: monospace;"><ol><span style="color: #993333;">typedef VALUE (*frb_gv_set)(<span style="color: #993333;">char* name,VALUE* val);

//(char* name,VALUE* val);

<span style="color: #339933;">#define rb_gv_set(name,val) ((frb_gv_set)0x100B7300)(name,val)
C++:
    //Validation du mode de fonctionnement du RGSS

    if(wcscmp(lpCmdLine, TEXT(<span style="color: #666666;">"btest")) == <span style="color: #0000dd;">0)

    {BattleTest=<span style="color: #0000dd;">2;}

    rb_gv_set(<span style="color: #666666;">"BTEST",&BattleTest);
I started to search function's pointers in RGSS301 :
Code:
[url=http://www.opensource.apple.com/source/ruby/ruby-75/ruby/variable.c]http://www.opensource.apple.com/source/ ... variable.c[/url]

[url=http://rxr.whitequark.org/mri/source/ext/socket/?v=1.8.7-p370]http://rxr.whitequark.org/mri/source/ex ... 1.8.7-p370[/url]

optlink

 

//Ruby

rb_warning 

rb_warn  //rb_warn("no super class for `%s', Object assumed", name);

rb_raise 

rb_raise2 //rb_raise(rb_eTypeError, "can't make subclass of Class");

rb_name_error  //rb_name_error(id, "%s is already defined", name)

rb_to_id 

global_id 

rb_global_entry 

rb_intern 

rb_intern2 100483E0 //rb_intern2("str",size)

rb_id2name 

rb_check_type 

rb_secure 

rb_alias 

rb_attr 

rb_fatal 

rb_block_given_p 

//rb_need_block 

LONG2NUM 

rb_yield 

rb_equal 

rb_check_type_string 

rb_class_new_instance 

rb_class_superclass 

rb_define_alloc_func 10032E20

rb_undef_alloc_func 100316A0

rb_data_object_alloc 

rb_obj_alloc 

rb_obj_call_init 

//rb_add_method 

str_new //ATTENTION METHODE D4APPEL DIFFERENTE ! __fastcall ? Nop, c'est pas du fastcall c'est de l'optimisation de gros bourrin.

rb_str_new //ATTENTION METHODE D4APPEL DIFFERENTE !

rb_str_new2 //ATTENTION METHODE D4APPEL DIFFERENTE !

ary_new 

rb_ary_new //???

rb_ary_new2 

rb_ary_new3 

rb_ary_new4 

---

 

//

rgss_print 

rgss_p 

//rgss_init 

 

 

//Eval

rb_f_eval 

eval 

rb_eval_string 

---

 

<!BASIC RUBY FUNC>

//String

rb_str_cmp_m  1

rb_str_equal  1

rb_str_hash_m  0

rb_str_casecmp  1

rb_str_plus  1

rb_str_times  1

rb_str_format_m  1

rb_str_aref_m  -1

rb_str_aset_m  -1

rb_str_insert  2

rb_str_length  0

rb_str_empty  0

rb_str_match  1

rb_str_match_m  1

rb_str_succ  0

rb_str_succ_bang  0

rb_str_upto_m  -1

rb_str_index_m  -1

rb_str_rindex_m  -1

rb_str_replace  1

rb_str_to_i  -1

rb_str_to_f  0

rb_str_to_s  0

rb_str_inspect  0

rb_str_dump  0

rb_str_upcase  0

rb_str_downcase  0

rb_str_capitalize  0

rb_str_swapcase  0

rb_str_upcase_bang  0

rb_str_downcase_bang  0

rb_str_capitalize_bang  0

rb_str_swapcase_bang  0

rb_str_hex  0

rb_str_oct  0

rb_str_split_m  -1

rb_str_reverse  0

rb_str_reverse_bang  0

rb_str_concat  1

rb_str_crypt  1

rb_str_intern  0

rb_str_include  1

rb_str_scan  1

rb_str_ljust  -1

rb_str_rjust  -1

rb_str_center  -1

rb_str_sub  -1

rb_str_gsub  -1

rb_str_chop  0

rb_str_chomp  -1

rb_str_strip  0

rb_str_lstrip  0

rb_str_rstrip  0

rb_str_sub_bang  -1

rb_str_gsub_bang  -1

rb_str_chop_bang  0

rb_str_chomp_bang  -1

rb_str_strip_bang  0

rb_str_lstrip_bang  0

rb_str_rstrip_bang  0

rb_str_tr  2

rb_str_tr_s  2

rb_str_delete  -1

rb_str_squeeze  -1

rb_str_count  -1

rb_str_tr_bang  2

rb_str_tr_s_bang  2

rb_str_delete_bang  -1

rb_str_squeeze_bang  -1

rb_str_each_line  -1

 

 

---

 

//Array 

rb_ary_aref  -1

rb_ary_fetch  -1

rb_ary_index  -1

rb_ary_rindex  -1

rb_ary_aset  -1

rb_ary_insert  -1

rb_ary_each_index  0

rb_ary_reverse_each  0

rb_ary_length  0

rb_ary_empty_p  0

//rb_ary_reverse 

rb_ary_reverse_bang  0

rb_ary_reverse_m  0

rb_ary_transpose  0

rb_ary_replace  1

rb_ary_fill  -1

rb_ary_times  1

rb_ary_equal  1

rb_ary_to_s  0

rb_ary_inspect  0

rb_ary_eql  1

rb_ary_at  1

rb_ary_first  -1

rb_ary_last  -1

rb_ary_concat  1

rb_ary_push_m  -1

rb_ary_unshift  -1

rb_ary_each  0

rb_ary_join_m  -1

rb_ary_sort  0

rb_ary_sort_bang  0

rb_ary_collect  0

rb_ary_collect_bang  0

rb_ary_delete  1

rb_ary_delete_at_m  1

rb_ary_reject  0

rb_ary_reject_bang  0

rb_ary_clear  0

rb_ary_includes  1

rb_ary_compact  0

rb_ary_compact_bang  0

---

 

//Hash

rb_hash_equal  1

rb_hash_aref  1

rb_hash_aset  2

rb_hash_default  -1

rb_hash_set_default  1

rb_hash_index  1

rb_hash_indexes  -1

rb_hash_size  0

rb_hash_empty_p  0

rb_hash_each  0

rb_hash_sort  0

rb_hash_keys  0

rb_hash_values  0

rb_hash_shift  0

rb_hash_delete  1

rb_hash_select  0

rb_hash_reject  0

rb_hash_reject_bang  0

rb_hash_clear  0

rb_hash_invert  0

rb_hash_has_key  1

rb_hash_has_value  1

<!BASIC RUBY FUNC>

 

//Class Variable

rb_mod_remove_cvar 

rb_define_class_variable 

rb_cvar_defined 

mod_av_set 

rb_cvar_get 

rb_cvar_set 

rb_cv_get 

rb_cv_set 

---

 

//Constantes

rb_const_set 

rb_define_const 

rb_const_defined_at 

rb_const_defined 

rb_const_defined_from 

rb_const_defined_0 

rb_mod_remove_const 

rb_const_get_at 

rb_const_get 

rb_const_get_from 

rb_const_get_0 

rb_define_global_const 10068320

---

 

//Instance Variable

rb_ivar_get 

rb_attr_get 

rb_ivar_set 

rb_ivar_defined 

rb_obj_remove_instance_variable 

rb_iv_get 

rb_iv_set 

---

 

//Global Variable

rb_gv_set 

rb_gv_get 

rb_gvar_defined 

---

 

//Object

rb_obj_clone 

rb_obj_dup 

---

 

//Class

rb_funcall2 

rb_funcall3 

rb_define_sigleton_method 1005F1E0

rb_define_method 1005EF70

rb_define_global_function 1005F270

rb_define_module 1005E990

rb_define_class_under 

rb_define_class 1005E740

rb_define_module_under 

rb_class_new 

rb_define_class_id 

rb_class_boot 

rb_set_class_path 

rb_class_inherited 

rb_mod_included_modules 

rb_mod_include_p 

rb_mod_ancestors 

rb_singleton_class 

rb_define_private_method 1005EFA0

rb_define_module_function 

rb_define_alias 1005F2C0

rb_define_attr 

rb_scan_args 

rb_undef_method 1005EFD0

rb_include_module 1005EBC0

---

 

ruby_xmalloc 

ruby_xrealloc 

ruby_xfree 

ruby_xcalloc 

 

//ENDEF FUNCT//

 

 

 

Macros :

#define FIXNUM_P(a) a&0x00000001

#define SYMBOL_P(a) (a&0x000000FF)==0x0e

#define NIL_P(a) a==0x04

 

RGSSInitialize 

RGSSGameMain 

RGSSSetupRTP 

 

 

Classes

    kAudio ,

    kGraphics ,

    kInput ,

    kObject 102AC098,

    kModule ,

    kClass ,

    kKernel 102AC080,

    kNilClass 102AC090,

    kSymbol ,

    kTrueClass 102AC094,

    kData 102AC078,

    kFalseClass 102AC088,

    kArray 102ABFE8,

    kString ,

    kFloat ,

    kInteger ,

    kNumeric ,

    kSprite ,

    kBitmap ,

    kViewport ,

    kRect ,

    kTone ,

    kColor ,

    kFont ,

  eTypeError ,

  eArgError ,

  eIndexError ,

  eException ,

  eStandardError ,

  kHash
@Drago del Fato : Using ruby API will make your Game crash, I tried Win32API.new("socket.so","Init_Socket","","").call() looong time ago and the result was "RGSS Player a cessé de fonctionner.". But it's right : the arguments of the functions didn't change.
 
Status
Not open for further replies.

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