├── images └── banner.png ├── .gitattributes ├── .github └── FUNDING.yml ├── seedpod ├── scripts │ ├── scr_seedpod_basics │ │ ├── scr_seedpod_basics.yy │ │ └── scr_seedpod_basics.gml │ ├── scr_seedpod_strings │ │ ├── scr_seedpod_strings.yy │ │ └── scr_seedpod_strings.gml │ └── scr_seedpod_instances │ │ ├── scr_seedpod_instances.yy │ │ └── scr_seedpod_instances.gml ├── seedpod.resource_order ├── options │ ├── main │ │ └── options_main.yy │ ├── linux │ │ └── options_linux.yy │ ├── operagx │ │ └── options_operagx.yy │ ├── html5 │ │ └── options_html5.yy │ ├── mac │ │ └── options_mac.yy │ ├── tvos │ │ └── options_tvos.yy │ ├── windows │ │ └── options_windows.yy │ ├── ios │ │ └── options_ios.yy │ ├── windowsuap │ │ └── options_windowsuap.yy │ └── android │ │ └── options_android.yy └── seedpod.yyp ├── LICENSE └── README.md /images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daikon-games/gm-seedpod/HEAD/images/banner.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ignore .yy files for language statistics 2 | *.yy linguist-generated=true 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: daikon-games 4 | patreon: nickavv 5 | -------------------------------------------------------------------------------- /seedpod/scripts/scr_seedpod_basics/scr_seedpod_basics.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMScript", 3 | "resourceVersion": "1.0", 4 | "name": "scr_seedpod_basics", 5 | "isCompatibility": false, 6 | "isDnD": false, 7 | "parent": { 8 | "name": "Seedpod", 9 | "path": "folders/scripts/Seedpod.yy", 10 | }, 11 | } -------------------------------------------------------------------------------- /seedpod/scripts/scr_seedpod_strings/scr_seedpod_strings.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMScript", 3 | "resourceVersion": "1.0", 4 | "name": "scr_seedpod_strings", 5 | "isCompatibility": false, 6 | "isDnD": false, 7 | "parent": { 8 | "name": "Seedpod", 9 | "path": "folders/scripts/Seedpod.yy", 10 | }, 11 | } -------------------------------------------------------------------------------- /seedpod/scripts/scr_seedpod_instances/scr_seedpod_instances.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMScript", 3 | "resourceVersion": "1.0", 4 | "name": "scr_seedpod_instances", 5 | "isCompatibility": false, 6 | "isDnD": false, 7 | "parent": { 8 | "name": "Seedpod", 9 | "path": "folders/scripts/Seedpod.yy", 10 | }, 11 | } -------------------------------------------------------------------------------- /seedpod/seedpod.resource_order: -------------------------------------------------------------------------------- 1 | { 2 | "FolderOrderSettings": [], 3 | "ResourceOrderSettings": [ 4 | {"name":"scr_seedpod_strings","order":1,"path":"scripts/scr_seedpod_strings/scr_seedpod_strings.yy",}, 5 | {"name":"scr_seedpod_instances","order":2,"path":"scripts/scr_seedpod_instances/scr_seedpod_instances.yy",}, 6 | ], 7 | } -------------------------------------------------------------------------------- /seedpod/scripts/scr_seedpod_strings/scr_seedpod_strings.gml: -------------------------------------------------------------------------------- 1 | // feather ignore all 2 | // feather disable all 3 | 4 | /// @function string_pad(_value, _amount, _padChar) 5 | /// @param value {Real} The real number to be turned into a string 6 | /// @param amount {Real} The total number of characters to show 7 | /// @param padChar {String} The padding character. This will be used to pad value out to amount places. 8 | /// @description As string_format(), but allows for an arbitrary padding character instead of just the space character 9 | function string_pad(_value, _amount, _padChar) { 10 | return string_replace_all(string_format(_value, _amount, 0), " ", _padChar); 11 | } 12 | -------------------------------------------------------------------------------- /seedpod/options/main/options_main.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMMainOptions", 3 | "resourceVersion": "1.4", 4 | "name": "Main", 5 | "option_author": "", 6 | "option_collision_compatibility": false, 7 | "option_copy_on_write_enabled": false, 8 | "option_draw_colour": 4294967295, 9 | "option_game_speed": 60, 10 | "option_gameguid": "4ef6db21-56a5-47a5-a405-90987f199ae3", 11 | "option_gameid": "0", 12 | "option_mips_for_3d_textures": false, 13 | "option_sci_usesci": false, 14 | "option_spine_licence": false, 15 | "option_steam_app_id": "0", 16 | "option_template_description": null, 17 | "option_template_icon": "${base_options_dir}/main/template_icon.png", 18 | "option_template_image": "${base_options_dir}/main/template_image.png", 19 | "option_window_colour": 255, 20 | } -------------------------------------------------------------------------------- /seedpod/options/linux/options_linux.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMLinuxOptions", 3 | "resourceVersion": "1.0", 4 | "name": "Linux", 5 | "option_linux_allow_fullscreen": false, 6 | "option_linux_disable_sandbox": false, 7 | "option_linux_display_cursor": true, 8 | "option_linux_display_name": "Created with GameMaker", 9 | "option_linux_display_splash": false, 10 | "option_linux_enable_steam": false, 11 | "option_linux_homepage": "http://www.yoyogames.com", 12 | "option_linux_icon": "${base_options_dir}/linux/icons/64.png", 13 | "option_linux_interpolate_pixels": true, 14 | "option_linux_long_desc": "", 15 | "option_linux_maintainer_email": "", 16 | "option_linux_resize_window": false, 17 | "option_linux_scale": 0, 18 | "option_linux_short_desc": "", 19 | "option_linux_splash_screen": "${base_options_dir}/linux/splash/splash.png", 20 | "option_linux_start_fullscreen": false, 21 | "option_linux_sync": false, 22 | "option_linux_texture_page": "2048x2048", 23 | "option_linux_version": "1.0.0.0", 24 | } -------------------------------------------------------------------------------- /seedpod/options/operagx/options_operagx.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMOperaGXOptions", 3 | "resourceVersion": "1.1", 4 | "name": "operagx", 5 | "option_operagx_display_cursor": true, 6 | "option_operagx_editUrl": "", 7 | "option_operagx_game_name": "${project_name}", 8 | "option_operagx_guid": "", 9 | "option_operagx_internalShareUrl": "", 10 | "option_operagx_interpolate_pixels": true, 11 | "option_operagx_mod_editUrl": "", 12 | "option_operagx_mod_game_name": "${project_name}", 13 | "option_operagx_mod_guid": "", 14 | "option_operagx_mod_internalShareUrl": "", 15 | "option_operagx_mod_next_version": "1.0.0.0", 16 | "option_operagx_mod_publicShareUrl": "", 17 | "option_operagx_mod_team_id": "", 18 | "option_operagx_mod_team_name": "", 19 | "option_operagx_mod_version": "1.0.0.0", 20 | "option_operagx_next_version": "1.0.0.0", 21 | "option_operagx_publicShareUrl": "", 22 | "option_operagx_scale": 0, 23 | "option_operagx_team_id": "", 24 | "option_operagx_team_name": "", 25 | "option_operagx_texture_page": "2048x2048", 26 | "option_operagx_version": "1.0.0.0", 27 | } -------------------------------------------------------------------------------- /seedpod/options/html5/options_html5.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMHtml5Options", 3 | "resourceVersion": "1.0", 4 | "name": "HTML5", 5 | "option_html5_allow_fullscreen": true, 6 | "option_html5_browser_title": "Created with GameMaker", 7 | "option_html5_centregame": false, 8 | "option_html5_display_cursor": true, 9 | "option_html5_facebook_app_display_name": "", 10 | "option_html5_facebook_id": "", 11 | "option_html5_flurry_enable": false, 12 | "option_html5_flurry_id": "", 13 | "option_html5_foldername": "html5game", 14 | "option_html5_google_analytics_enable": false, 15 | "option_html5_google_tracking_id": "", 16 | "option_html5_icon": "${base_options_dir}/html5/fav.ico", 17 | "option_html5_index": "", 18 | "option_html5_interpolate_pixels": true, 19 | "option_html5_jsprepend": "", 20 | "option_html5_loadingbar": "", 21 | "option_html5_localrunalert": true, 22 | "option_html5_outputdebugtoconsole": true, 23 | "option_html5_outputname": "index.html", 24 | "option_html5_scale": 0, 25 | "option_html5_splash_png": "${base_options_dir}/html5/splash.png", 26 | "option_html5_texture_page": "2048x2048", 27 | "option_html5_use_facebook": false, 28 | "option_html5_usebuiltinfont": true, 29 | "option_html5_usebuiltinparticles": true, 30 | "option_html5_usesplash": false, 31 | "option_html5_version": "1.0.0.0", 32 | "option_html5_webgl": 2, 33 | } -------------------------------------------------------------------------------- /seedpod/seedpod.yyp: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMProject", 3 | "resourceVersion": "1.7", 4 | "name": "seedpod", 5 | "AudioGroups": [ 6 | {"resourceType":"GMAudioGroup","resourceVersion":"1.3","name":"audiogroup_default","targets":-1,}, 7 | ], 8 | "configs": { 9 | "children": [], 10 | "name": "Default", 11 | }, 12 | "defaultScriptType": 1, 13 | "Folders": [ 14 | {"resourceType":"GMFolder","resourceVersion":"1.0","name":"scripts","folderPath":"folders/scripts.yy",}, 15 | {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Seedpod","folderPath":"folders/scripts/Seedpod.yy",}, 16 | ], 17 | "IncludedFiles": [], 18 | "isEcma": false, 19 | "LibraryEmitters": [], 20 | "MetaData": { 21 | "IDEVersion": "2023.6.0.89", 22 | }, 23 | "resources": [ 24 | {"id":{"name":"scr_seedpod_strings","path":"scripts/scr_seedpod_strings/scr_seedpod_strings.yy",},}, 25 | {"id":{"name":"scr_seedpod_instances","path":"scripts/scr_seedpod_instances/scr_seedpod_instances.yy",},}, 26 | {"id":{"name":"scr_seedpod_basics","path":"scripts/scr_seedpod_basics/scr_seedpod_basics.yy",},}, 27 | ], 28 | "RoomOrderNodes": [], 29 | "TextureGroups": [ 30 | {"resourceType":"GMTextureGroup","resourceVersion":"1.3","name":"Default","autocrop":true,"border":2,"compressFormat":"bz2","directory":"","groupParent":null,"isScaled":true,"loadType":"default","mipsToGenerate":0,"targets":-1,}, 31 | ], 32 | } -------------------------------------------------------------------------------- /seedpod/options/mac/options_mac.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMMacOptions", 3 | "resourceVersion": "1.0", 4 | "name": "macOS", 5 | "option_mac_allow_fullscreen": false, 6 | "option_mac_allow_incoming_network": false, 7 | "option_mac_allow_outgoing_network": false, 8 | "option_mac_app_category": "Games", 9 | "option_mac_app_id": "com.company.game", 10 | "option_mac_apple_sign_in": false, 11 | "option_mac_arm64": true, 12 | "option_mac_build_app_store": false, 13 | "option_mac_copyright": "", 14 | "option_mac_disable_sandbox": false, 15 | "option_mac_display_cursor": true, 16 | "option_mac_display_name": "Created with GameMaker", 17 | "option_mac_enable_retina": false, 18 | "option_mac_enable_steam": false, 19 | "option_mac_icon_png": "${base_options_dir}/mac/icons/1024.png", 20 | "option_mac_installer_background_png": "${base_options_dir}/mac/splash/installer_background.png", 21 | "option_mac_interpolate_pixels": true, 22 | "option_mac_menu_dock": false, 23 | "option_mac_min_version": "10.10", 24 | "option_mac_output_dir": "~/gamemakerstudio2", 25 | "option_mac_resize_window": false, 26 | "option_mac_scale": 0, 27 | "option_mac_signing_identity": "Developer ID Application:", 28 | "option_mac_splash_png": "${base_options_dir}/mac/splash/splash.png", 29 | "option_mac_start_fullscreen": false, 30 | "option_mac_team_id": "", 31 | "option_mac_texture_page": "2048x2048", 32 | "option_mac_version": "1.0.0.0", 33 | "option_mac_vsync": false, 34 | "option_mac_x86_64": true, 35 | } -------------------------------------------------------------------------------- /seedpod/options/tvos/options_tvos.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMtvOSOptions", 3 | "resourceVersion": "1.3", 4 | "name": "tvOS", 5 | "option_tvos_bundle_name": "com.company.game", 6 | "option_tvos_cocoapods_checkbox": true, 7 | "option_tvos_display_cursor": false, 8 | "option_tvos_display_name": "Made in GameMaker", 9 | "option_tvos_icon_1280": "${base_options_dir}/tvos/icons/1280.png", 10 | "option_tvos_icon_400": "${base_options_dir}/tvos/icons/400.png", 11 | "option_tvos_icon_400_2x": "${base_options_dir}/tvos/icons/400_2x.png", 12 | "option_tvos_interpolate_pixels": true, 13 | "option_tvos_min_version": "10.0", 14 | "option_tvos_output_dir": "~/GameMakerStudio2/tvOS", 15 | "option_tvos_podfile_lock_path": "${options_dir}\\tvos\\Podfile.lock", 16 | "option_tvos_podfile_path": "${options_dir}\\tvos\\Podfile", 17 | "option_tvos_scale": 0, 18 | "option_tvos_splash_time": 0, 19 | "option_tvos_splashscreen": "${base_options_dir}/tvos/splash/splash.png", 20 | "option_tvos_splashscreen_2x": "${base_options_dir}/tvos/splash/splash_2x.png", 21 | "option_tvos_team_id": "", 22 | "option_tvos_texture_page": "2048x2048", 23 | "option_tvos_topshelf": "${base_options_dir}/tvos/topshelf/topshelf.png", 24 | "option_tvos_topshelf_2x": "${base_options_dir}/tvos/topshelf/topshelf_2x.png", 25 | "option_tvos_topshelf_wide": "${base_options_dir}/tvos/topshelf/topshelf_wide.png", 26 | "option_tvos_topshelf_wide_2x": "${base_options_dir}/tvos/topshelf/topshelf_wide_2x.png", 27 | "option_tvos_version": "1.0.0.0", 28 | } -------------------------------------------------------------------------------- /seedpod/options/windows/options_windows.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMWindowsOptions", 3 | "resourceVersion": "1.1", 4 | "name": "Windows", 5 | "option_windows_allow_fullscreen_switching": false, 6 | "option_windows_borderless": false, 7 | "option_windows_company_info": "YoYo Games Ltd", 8 | "option_windows_copy_exe_to_dest": false, 9 | "option_windows_copyright_info": "", 10 | "option_windows_description_info": "A GameMaker Game", 11 | "option_windows_disable_sandbox": false, 12 | "option_windows_display_cursor": true, 13 | "option_windows_display_name": "Created with GameMaker", 14 | "option_windows_enable_steam": false, 15 | "option_windows_executable_name": "${project_name}.exe", 16 | "option_windows_icon": "${base_options_dir}/windows/icons/icon.ico", 17 | "option_windows_installer_finished": "${base_options_dir}/windows/installer/finished.bmp", 18 | "option_windows_installer_header": "${base_options_dir}/windows/installer/header.bmp", 19 | "option_windows_interpolate_pixels": false, 20 | "option_windows_license": "${base_options_dir}/windows/installer/license.txt", 21 | "option_windows_nsis_file": "${base_options_dir}/windows/installer/nsis_script.nsi", 22 | "option_windows_product_info": "Created with GameMaker", 23 | "option_windows_resize_window": false, 24 | "option_windows_save_location": 0, 25 | "option_windows_scale": 0, 26 | "option_windows_sleep_margin": 10, 27 | "option_windows_splash_screen": "${base_options_dir}/windows/splash/splash.png", 28 | "option_windows_start_fullscreen": false, 29 | "option_windows_steam_use_alternative_launcher": false, 30 | "option_windows_texture_page": "2048x2048", 31 | "option_windows_use_splash": false, 32 | "option_windows_version": "1.0.0.0", 33 | "option_windows_vsync": false, 34 | } -------------------------------------------------------------------------------- /seedpod/scripts/scr_seedpod_instances/scr_seedpod_instances.gml: -------------------------------------------------------------------------------- 1 | // feather disable all 2 | // feather ignore all 3 | 4 | // Seedpod Instances includes useful APIs for interacting with instances in the game at runtime 5 | 6 | /// @function with_tagged(_tag, _lambda) 7 | /// @param {String, Array} _tag The tag or array of tags to operate on 8 | /// @param {Function} _lambda A function to be run on the tagged instances 9 | /// @description Runs the lambda function provided on every instance in the room with a given tag 10 | function with_tagged(tag, lambda) { 11 | var tagged = tag_get_asset_ids(tag, asset_object); 12 | for (var i = 0; i < array_length(tagged); i++) { 13 | with (tagged[i]) { 14 | var boundMethod = method(self, lambda); 15 | boundMethod(); 16 | } 17 | } 18 | } 19 | 20 | /// @function change_sprite(_newSpriteIndex) 21 | /// @param {Asset.GMSprite} newSpriteIndex The desired sprite_index of the instance 22 | /// @description Changes the instance's sprite_index to the newly provided one, only if it does not already match. 23 | /// If it changes, the image_index will be reset to 0 so the animation begins at that frame. 24 | function change_sprite(_newSpriteIndex) { 25 | if(sprite_index != _newSpriteIndex) { 26 | // Only change sprites if necessary, and always start from animation frame 0 27 | image_index = 0; 28 | sprite_index = _newSpriteIndex; 29 | } 30 | } 31 | 32 | /// @function center_x([_inst]) 33 | /// @param {ID.Instance, Asset.GMObject} [_inst] The instance whose X midpoint to find. Optional, will use self if not provided 34 | /// @description Returns the midpoint X coordinate of the given instance, calculated using the bbox coordinates 35 | /// @returns {Real} 36 | function center_x(_inst = self) { 37 | return _inst.bbox_left + (_inst.bbox_right - _inst.bbox_left)/2; 38 | } 39 | 40 | /// @function center_y([_inst]) 41 | /// @param {ID.Instance, Asset.GMObject} [_inst] The instance whose Y midpoint to find. Optional, will use self if not provided 42 | /// @description Returns the midpoint Y coordinate of the given instance, calculated using the bbox coordinates 43 | /// @returns {Real} 44 | function center_y(_inst = self) { 45 | return _inst.bbox_top + (_inst.bbox_bottom - _inst.bbox_top)/2; 46 | } 47 | 48 | /// @function point_in_bounds(_pX, _pY) 49 | /// @param {Real} _pX The X coordinate to check 50 | /// @param {Real} _pY The Y coordinate to check 51 | /// @description Checks whether an X/Y coordinate lies within the bounding box of this instance 52 | /// @returns {Bool} true if the point is within this instance's bbox, false if not 53 | function point_in_bounds(_pX, _pY) { 54 | return point_in_rectangle(_pX, _pY, bbox_left, bbox_top, bbox_right, bbox_bottom); 55 | } -------------------------------------------------------------------------------- /seedpod/options/ios/options_ios.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMiOSOptions", 3 | "resourceVersion": "1.3", 4 | "name": "iOS", 5 | "option_ios_bundle_name": "com.company.game", 6 | "option_ios_cocoapods_checkbox": true, 7 | "option_ios_defer_home_indicator": false, 8 | "option_ios_devices": 2, 9 | "option_ios_display_name": "Created with GameMaker", 10 | "option_ios_half_ipad1_textures": false, 11 | "option_ios_icon_ipad_app_152": "${base_options_dir}/ios/icons/app/ipad_152.png", 12 | "option_ios_icon_ipad_app_76": "${base_options_dir}/ios/icons/app/ipad_76.png", 13 | "option_ios_icon_ipad_notification_20": "${base_options_dir}/ios/icons/notification/ipad_20.png", 14 | "option_ios_icon_ipad_notification_40": "${base_options_dir}/ios/icons/notification/ipad_40.png", 15 | "option_ios_icon_ipad_pro_app_167": "${base_options_dir}/ios/icons/app/ipad_pro_167.png", 16 | "option_ios_icon_ipad_settings_29": "${base_options_dir}/ios/icons/settings/ipad_29.png", 17 | "option_ios_icon_ipad_settings_58": "${base_options_dir}/ios/icons/settings/ipad_58.png", 18 | "option_ios_icon_ipad_spotlight_40": "${base_options_dir}/ios/icons/spotlight/ipad_40.png", 19 | "option_ios_icon_ipad_spotlight_80": "${base_options_dir}/ios/icons/spotlight/ipad_80.png", 20 | "option_ios_icon_iphone_app_120": "${base_options_dir}/ios/icons/app/iphone_120.png", 21 | "option_ios_icon_iphone_app_180": "${base_options_dir}/ios/icons/app/iphone_180.png", 22 | "option_ios_icon_iphone_notification_40": "${base_options_dir}/ios/icons/notification/iphone_40.png", 23 | "option_ios_icon_iphone_notification_60": "${base_options_dir}/ios/icons/notification/iphone_60.png", 24 | "option_ios_icon_iphone_settings_58": "${base_options_dir}/ios/icons/settings/iphone_58.png", 25 | "option_ios_icon_iphone_settings_87": "${base_options_dir}/ios/icons/settings/iphone_87.png", 26 | "option_ios_icon_iphone_spotlight_120": "${base_options_dir}/ios/icons/spotlight/iphone_120.png", 27 | "option_ios_icon_iphone_spotlight_80": "${base_options_dir}/ios/icons/spotlight/iphone_80.png", 28 | "option_ios_icon_itunes_artwork_1024": "${base_options_dir}/ios/icons/itunes/itunes_1024.png", 29 | "option_ios_interpolate_pixels": false, 30 | "option_ios_launchscreen_fill": 0, 31 | "option_ios_launchscreen_image": "${base_options_dir}/ios/splash/launchscreen.png", 32 | "option_ios_launchscreen_image_landscape": "${base_options_dir}/ios/splash/launchscreen-landscape.png", 33 | "option_ios_min_version": "10.0", 34 | "option_ios_orientation_landscape": true, 35 | "option_ios_orientation_landscape_flipped": true, 36 | "option_ios_orientation_portrait": true, 37 | "option_ios_orientation_portrait_flipped": true, 38 | "option_ios_output_dir": "~/gamemakerstudio2", 39 | "option_ios_podfile_lock_path": "${options_dir}/ios/Podfile.lock", 40 | "option_ios_podfile_path": "${options_dir}/ios/Podfile", 41 | "option_ios_scale": 0, 42 | "option_ios_splashscreen_background_colour": 255, 43 | "option_ios_team_id": "", 44 | "option_ios_texture_page": "2048x2048", 45 | "option_ios_version": "1.0.0.0", 46 | } -------------------------------------------------------------------------------- /seedpod/options/windowsuap/options_windowsuap.yy: -------------------------------------------------------------------------------- 1 | { 2 | "option_windowsuap_display_name": "Created with GameMaker", 3 | "option_windowsuap_package_name": "YourPackageName", 4 | "option_windowsuap_publisher_display_name": "YourPublisherName", 5 | "option_windowsuap_package_display_name": "YourPackageDisplayName", 6 | "option_windowsuap_description": "Your Description", 7 | "option_windowsuap_version": "1.0.0.0", 8 | "option_windowsuap_orient_portrait": true, 9 | "option_windowsuap_orient_portrait_flipped": true, 10 | "option_windowsuap_orient_landscape": true, 11 | "option_windowsuap_orient_landscape_flipped": true, 12 | "option_windowsuap_small_logo": "${base_options_dir}/windowsuap/logos/SmallLogo.scale-100.png", 13 | "option_windowsuap_smallish_logo": "${base_options_dir}/windowsuap/logos/SmallishLogo.scale-100.png", 14 | "option_windowsuap_store_logo": "${base_options_dir}/windowsuap/logos/StoreLogo.scale-100.png", 15 | "option_windowsuap_logo": "${base_options_dir}/windowsuap/logos/Logo.scale-100.png", 16 | "option_windowsuap_logo_background_colour": 4278190080, 17 | "option_windowsuap_logo_foreground_text": 0, 18 | "option_windowsuap_wide_logo": "${base_options_dir}/windowsuap/logos/WideLogo.scale-100.png", 19 | "option_windowsuap_large_logo": "${base_options_dir}/windowsuap/logos/LargeLogo.scale-100.png", 20 | "option_windowsuap_splash_png": "${base_options_dir}/windowsuap/splash/SplashScreen.scale-100.png", 21 | "option_windowsuap_splash_background_colour": 4278190080, 22 | "option_windowsuap_interpolate_pixels": false, 23 | "option_windowsuap_display_cursor": true, 24 | "option_windowsuap_start_fullscreen": false, 25 | "option_windowsuap_allow_fullscreen_switching": false, 26 | "option_windowsuap_use_synchronization": true, 27 | "option_windowsuap_scale": 0, 28 | "option_windowsuap_texture_page": "2048x2048", 29 | "option_windowsuap_certificate_location": "${base_options_dir}\\windowsuap\\keys\\WinUWPRunner_TemporaryKey.pfx", 30 | "option_windowsuap_certificate_publishername": "CN=Sandbox", 31 | "option_windowsuap_native_cpu": 0, 32 | "option_windowsuap_internet_capable": false, 33 | "option_windowsuap_microphone_capable": false, 34 | "option_windowsuap_iap_sandbox": false, 35 | "option_windowsuap_targetdevicefamily_universal": true, 36 | "option_windowsuap_target_platform_version": "10.0.14393.0", 37 | "option_windowsuap_target_platform_min_version": "10.0.14393.0", 38 | "option_windowsuap_targetdevicefamily_desktop": false, 39 | "option_windowsuap_desktop_family_platform_version": "10.0.14393.0", 40 | "option_windowsuap_desktop_family_platform_min_version": "10.0.14393.0", 41 | "option_windowsuap_targetdevicefamily_xbox": false, 42 | "option_windowsuap_xbox_family_platform_version": "10.0.14393.0", 43 | "option_windowsuap_xbox_family_platform_min_version": "10.0.14393.0", 44 | "option_windowsuap_targetdevicefamily_mobile": false, 45 | "option_windowsuap_mobile_family_platform_version": "10.0.14393.0", 46 | "option_windowsuap_mobile_family_platform_min_version": "10.0.14393.0", 47 | "option_windowsuap_targetdevicefamily_holographic": false, 48 | "option_windowsuap_holographic_family_platform_version": "10.0.14393.0", 49 | "option_windowsuap_holographic_family_platform_min_version": "10.0.14393.0", 50 | "option_windowsuap_targetdevicefamily_team": false, 51 | "option_windowsuap_team_family_platform_version": "10.0.14393.0", 52 | "option_windowsuap_team_family_platform_min_version": "10.0.14393.0", 53 | "option_windowsuap_xbox_live": false, 54 | "option_windowsuap_xbox_live_creators_program": false, 55 | "option_windowsuap_xbox_live_title_id": "0", 56 | "option_windowsuap_xbox_live_scid": "00000000-0000-0000-0000-000000000000", 57 | "resourceVersion": "1.0", 58 | "name": "Windows UWP", 59 | "tags": [], 60 | "resourceType": "GMWindowsUAPOptions", 61 | } -------------------------------------------------------------------------------- /seedpod/scripts/scr_seedpod_basics/scr_seedpod_basics.gml: -------------------------------------------------------------------------------- 1 | // feather ignore all 2 | // feather disable all 3 | 4 | // Seedpod Basics includes general purpose APIs that make GameMaker programming easier 5 | 6 | /// @function echo(_debugString, _data...) 7 | /// @param {String} _debugString The string to print to the console 8 | /// @param {Any} _data Variable data to substitute into the console string. Will each be cast to strings 9 | /// @description Enhanced debug logging. Replaces show_debug_message with something easier to type 10 | /// and which replaces any "%s" found in the string with your debug data. 11 | function echo(_debugString) { 12 | var _result = _debugString; 13 | if (argument_count > 1) { 14 | for (var i = 1; i < argument_count; i++) { 15 | _result = string_replace(_result, "%s", string(argument[i])); 16 | } 17 | } 18 | show_debug_message(_result); 19 | } 20 | 21 | /// @function mod_wrap(_newValue, _listLength) 22 | /// @param {Real} _newValue The value to perform modulus on 23 | /// @param {Real} _listLength The maximum size of the list to wrap 24 | /// @description As mod, but deals with negative numbers so it can be used for wrapping around lists 25 | function mod_wrap(_newValue, _listLength) { 26 | return ((_newValue) % _listLength + _listLength) % _listLength; 27 | } 28 | 29 | /// @function choose_from(_choices) 30 | /// @param {Array} _choices An array containing values from which to randomly choose 31 | /// @description as choose() but with an array of options rather than varargs 32 | function choose_from(_choices) { 33 | return _choices[irandom_range(0, array_length(_choices) - 1)]; 34 | } 35 | 36 | /// @function array_remove(_array, _value) 37 | /// @param {Array} _array The array to operate on 38 | /// @param {Any} _value The value to find and remove within the array 39 | /// @description Searches an array for a specific value, and removes the first instance of it if found 40 | function array_remove(_array, _value) { 41 | var _index = array_get_index(_array, _value); 42 | if (_index != -1) { 43 | array_delete(_array, _index, 1); 44 | } 45 | } 46 | 47 | /// @function round_to_nearest(_value, _multiple) 48 | /// @param {Real} _value The value to round 49 | /// @param {Real} _multiple The number to round value to the nearest multiple of 50 | /// @description Rounds value to the nearest multiple. 51 | function round_to_nearest(_value, _multiple) { 52 | /// Adapted from stackoverflow answer by user siddhartha agarwal 53 | /// https://stackoverflow.com/questions/29557459/round-to-nearest-multiple-of-a-number 54 | var _smallerMultiple = round(_value / _multiple) * _multiple; 55 | var _largerMultiple = _smallerMultiple + _multiple; 56 | 57 | // Return of closest of two 58 | return (_value - _smallerMultiple >= _largerMultiple - _value) ? _largerMultiple : _smallerMultiple; 59 | } 60 | 61 | /// @function real_truncate(_real) 62 | /// @param {Real} _real The number to truncate 63 | /// @description Takes a real number and returns just the integer portion 64 | /// @returns {Real} The integer portion of a real number, positive or negative 65 | function real_truncate(_real) { 66 | if (_real < 0) { 67 | return ceil(_real); 68 | } else { 69 | return floor(_real); 70 | } 71 | } 72 | 73 | /// @function variable_struct_get_or_else(_struct, _name, _defaultValue) 74 | /// @param {Struct} _struct The struct reference to use 75 | /// @param {String} _name The name of the variable to get 76 | /// @param {Any} _defaultValue The value to return if the named key does not exist in the struct 77 | /// @description Streamlines the process of checking for a key's existance in a struct before returning either the value found, or a default value if the key did not exist in the struct 78 | /// @returns {Any} The value with the given key in the struct, or _defaultValue if the key does not exist in the struct 79 | function variable_struct_get_or_else(_struct, _name, _defaultValue) { 80 | if (!variable_struct_exists(_struct, _name)) { 81 | return _defaultValue; 82 | } else { 83 | return variable_struct_get(_struct, _name); 84 | } 85 | } -------------------------------------------------------------------------------- /seedpod/options/android/options_android.yy: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "GMAndroidOptions", 3 | "resourceVersion": "1.0", 4 | "name": "Android", 5 | "option_android_application_tag_inject": "", 6 | "option_android_arch_arm64": true, 7 | "option_android_arch_armv7": false, 8 | "option_android_arch_x86_64": false, 9 | "option_android_build_tools": "", 10 | "option_android_compile_sdk": "", 11 | "option_android_device_support": 0, 12 | "option_android_display_name": "Created with GameMaker", 13 | "option_android_facebook_app_display_name": "", 14 | "option_android_facebook_id": "", 15 | "option_android_gamepad_support": true, 16 | "option_android_google_apk_expansion": false, 17 | "option_android_google_cloud_saving": false, 18 | "option_android_google_dynamic_asset_delivery": false, 19 | "option_android_google_licensing_public_key": "", 20 | "option_android_google_services_app_id": "", 21 | "option_android_icon_adaptive_generate": false, 22 | "option_android_icon_adaptive_hdpi": "${base_options_dir}/android/icons_adaptive/hdpi.png", 23 | "option_android_icon_adaptive_ldpi": "${base_options_dir}/android/icons_adaptive/ldpi.png", 24 | "option_android_icon_adaptive_mdpi": "${base_options_dir}/android/icons_adaptive/mdpi.png", 25 | "option_android_icon_adaptive_xhdpi": "${base_options_dir}/android/icons_adaptive/xhdpi.png", 26 | "option_android_icon_adaptive_xxhdpi": "${base_options_dir}/android/icons_adaptive/xxhdpi.png", 27 | "option_android_icon_adaptive_xxxhdpi": "${base_options_dir}/android/icons_adaptive/xxxhdpi.png", 28 | "option_android_icon_adaptivebg_hdpi": "${base_options_dir}/android/icons_adaptivebg/hdpi.png", 29 | "option_android_icon_adaptivebg_ldpi": "${base_options_dir}/android/icons_adaptivebg/ldpi.png", 30 | "option_android_icon_adaptivebg_mdpi": "${base_options_dir}/android/icons_adaptivebg/mdpi.png", 31 | "option_android_icon_adaptivebg_xhdpi": "${base_options_dir}/android/icons_adaptivebg/xhdpi.png", 32 | "option_android_icon_adaptivebg_xxhdpi": "${base_options_dir}/android/icons_adaptivebg/xxhdpi.png", 33 | "option_android_icon_adaptivebg_xxxhdpi": "${base_options_dir}/android/icons_adaptivebg/xxxhdpi.png", 34 | "option_android_icon_hdpi": "${base_options_dir}/android/icons/hdpi.png", 35 | "option_android_icon_ldpi": "${base_options_dir}/android/icons/ldpi.png", 36 | "option_android_icon_mdpi": "${base_options_dir}/android/icons/mdpi.png", 37 | "option_android_icon_xhdpi": "${base_options_dir}/android/icons/xhdpi.png", 38 | "option_android_icon_xxhdpi": "${base_options_dir}/android/icons/xxhdpi.png", 39 | "option_android_icon_xxxhdpi": "${base_options_dir}/android/icons/xxxhdpi.png", 40 | "option_android_install_location": 0, 41 | "option_android_interpolate_pixels": false, 42 | "option_android_launchscreen_fill": 0, 43 | "option_android_lint": false, 44 | "option_android_logcat": "yoyo:V DEBUG:V AndroidRuntime:V", 45 | "option_android_minimum_sdk": "", 46 | "option_android_orient_landscape": true, 47 | "option_android_orient_landscape_flipped": true, 48 | "option_android_orient_portrait": true, 49 | "option_android_orient_portrait_flipped": true, 50 | "option_android_package_company": "company", 51 | "option_android_package_domain": "com", 52 | "option_android_package_product": "game", 53 | "option_android_permission_bluetooth": true, 54 | "option_android_permission_internet": true, 55 | "option_android_permission_network_state": false, 56 | "option_android_permission_read_phone_state": false, 57 | "option_android_permission_record_audio": false, 58 | "option_android_permission_write_external_storage": false, 59 | "option_android_proguard_minifying": false, 60 | "option_android_proguard_shrinking": false, 61 | "option_android_scale": 0, 62 | "option_android_screen_depth": 0, 63 | "option_android_sleep_margin": 4, 64 | "option_android_splash_screens_landscape": "${base_options_dir}/android/splash/landscape.png", 65 | "option_android_splash_screens_portrait": "${base_options_dir}/android/splash/portrait.png", 66 | "option_android_splash_time": 0, 67 | "option_android_splashscreen_background_colour": 255, 68 | "option_android_support_lib": "", 69 | "option_android_sync_amazon": false, 70 | "option_android_target_sdk": "", 71 | "option_android_texture_page": "2048x2048", 72 | "option_android_tools_from_version": false, 73 | "option_android_tv_banner": "${base_options_dir}/android/tv_banner.png", 74 | "option_android_tv_isgame": true, 75 | "option_android_use_facebook": false, 76 | "option_android_version": "1.0.0.0", 77 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Seedpod for GameMaker 2 | 3 | ![Seedpod Banner Image](/images/banner.png) 4 | 5 | **Seedpod** is Daikon Games' collection of the APIs we think GML is missing. Every game Daikon creates includes these functions as our first step. 6 | 7 | Seedpod is an opinionated set of APIs meant to be well designed, easy to use, and enhance your GameMaker programming experience. The collection is split into multiple scripts so you can import everything, or just the category of scripts you need! 8 | 9 | #### Table of Contents 10 | * [Get Seedpod](#get-seedpod) 11 | * [Seedpod Basics](#seedpod-basics) 12 | * [Seedpod Instances](#seedpod-instances) 13 | * [Seedpod Strings](#seedpod-strings) 14 | * [Licensing](#licensing) 15 | 16 | ## Get Seedpod 17 | ### Manual Package Installation 18 | You can download the latest release of **Seedpod** from the [GitHub Releases page](https://github.com/daikon-games/gm-seedpod/releases), or from our [itch.io page](https://nickavv.itch.io/seedpod-for-gamemaker). 19 | 20 | Once you have downloaded the the package, in GameMaker click on the **Tools** menu and select **Import Local Package**. Choose the `.yymps` file you downloaded, and import any or all of the Seedpod scripts. 21 | 22 | ### GameMaker Marketplace 23 | **Seedpod** can be downloaded directly from the GameMaker Marketplace. Simply visit the [Marketplace page](https://marketplace.yoyogames.com/assets/10806/seedpod) and click the **Add to Account** button. 24 | 25 | ## Seedpod Basics 26 | Seedpod Basics (`scr_seedpod_basics`) is a collection of general purpose APIs to make GameMaker programming easier and faster. 27 | 28 | ### echo 29 | 30 | This function is a replacement for GameMaker's `show_debug_message` API. It will take data and print it the output console for debugging purposes. However compared to `show_debug_message` it is easier to type, and its string can be templated with other variables for debugging convenience. 31 | 32 | ```gml 33 | echo(debugString, data...) 34 | ``` 35 | | Argument | Type | Description | 36 | | -------- | ---- | ----------- | 37 | |`debugString` | String | The debug message to print to the console | 38 | |`data...` | Any | Optional, provide any amount of additional arguments of any datatype. They will be cast to strings and replace occurrences of the string `%s` in `debugString` in order | 39 | 40 | #### Returns 41 | 42 | N/A 43 | 44 | #### Example 45 | 46 | ```gml 47 | echo("Player x: %s, y: %s", obj_player.x, obj_player.y); 48 | ``` 49 | Assuming `obj_player` is an instance in the room with coordinates of x = 25, y = 100. The above code will print the following string to the output console: 50 | `Player x: 25, y: 100` 51 | 52 | ### mod_wrap 53 | 54 | This function acts similarly to the `mod`/`%` operator, but it wraps around when provided negative numbers. It is useful for changing selections in a menu, for instance, where you want to wrap around to the other side of the list when you reach either the beginning or the end 55 | 56 | ```gml 57 | mod_wrap(newValue, listLength) 58 | ``` 59 | | Argument | Type | Description | 60 | | -------- | ---- | ----------- | 61 | |`newValue` | Integer | The value to perform modulus on | 62 | |`listLength` | Integer | The maximum length of the list of data being operated on | 63 | 64 | #### Returns 65 | 66 | `newValue mod listLength`, but with the wrapping logic described above applied. 67 | 68 | #### Example 69 | 70 | ```gml 71 | if (keyboard_check_pressed(vk_up)) { 72 | selection = mod_wrap(selection - 1, array_length(menuItems)); 73 | } else if (keyboard_check_pressed(vk_down)) { 74 | selection = mod_wrap(selection + 1, array_length(menuItems)); 75 | } 76 | ``` 77 | The above code will decrement the `selection` variable when the up keyboard key is pressed, and increment it when the down keyboard key is pressed. By using `mod_wrap`, if the decremented value is less than 0 or the incremented value is less than the length of the array `menuItems`, the variable `selection` will instead loop around to the other side rather than going out of bounds. 78 | 79 | ### choose_from 80 | 81 | This function acts similarly to the built-in `choose`, in that it randomly selects one of a list of items. Unlike `choose` which uses a variable amount of arguments, `choose_from` returns a random item from an array. This can be useful for choosing from a programatically defined set of items rather than a pre-defined one. 82 | 83 | ```gml 84 | choose_from(choices) 85 | ``` 86 | | Argument | Type | Description | 87 | | -------- | ---- | ----------- | 88 | |`choices` | Array | An array whose items to randomly choose from | 89 | 90 | #### Returns 91 | 92 | Any one item from `choices`, selected at random. 93 | 94 | #### Example 95 | 96 | ```gml 97 | var footstepSound = choose_from(footstepSounds); 98 | audio_play_sound(footstepSound, 1, false); 99 | ``` 100 | Assumes that `footstepSounds` is an array defined elsewhere, containing references to multiple sound files. Every time the code above is run it randomly selects an item from `footstepSounds` and plays it. 101 | 102 | ### array_remove 103 | 104 | This function searches an array for a given value, and removes the first instance of it if found 105 | 106 | ```gml 107 | array_remove(array, value) 108 | ``` 109 | | Argument | Type | Description | 110 | | -------- | ---- | ----------- | 111 | |`array` | Array | The array to search | 112 | |`value` | Any | The value to remove from the array, if found | 113 | 114 | #### Returns 115 | 116 | N/A 117 | 118 | #### Example 119 | 120 | ```gml 121 | var sampleArray = ["A", "B", "C", "D"]; 122 | array_remove(sampleArray, "C"); 123 | ``` 124 | After the code above is run, the value of `sampleArray` will be `["A", "B", "D"]`. 125 | 126 | ### round_to_nearest 127 | 128 | This function rounds a numeric value to the nearest multiple of another value. 129 | 130 | ```gml 131 | round_to_nearest(value, multiple) 132 | ``` 133 | | Argument | Type | Description | 134 | | -------- | ---- | ----------- | 135 | |`value` | Real | The value to round | 136 | |`multiple` | Real | The multiple to round `value` to | 137 | 138 | #### Returns 139 | 140 | The multiple of `multiple` closest to `value`. 141 | 142 | #### example 143 | ```gml 144 | var testVal = 19; 145 | var testVal2 = 30; 146 | var roundedVal = round_to_nearest(testVal, 16); 147 | var roundedVal2 = round_to_nearest(testVal2, 16); 148 | ``` 149 | After the code above is run, the value of `roundedVal` would be 16. The value of `roundedVal2` would be 32. 150 | 151 | ### real_truncate 152 | 153 | This function returns just the integer portion of a real number. 154 | 155 | ```gml 156 | real_truncate(real) 157 | ``` 158 | | Argument | Type | Description | 159 | | -------- | ---- | ----------- | 160 | |`real` | Real | The real value to truncate | 161 | 162 | #### Returns 163 | 164 | The integer portion of `value`. 165 | 166 | #### example 167 | ```gml 168 | var testVal = 19.24; 169 | var truncVal = real_truncate(testVal); 170 | ``` 171 | After the code above is run, the value of `truncVal` would be 19. 172 | 173 | ### variable_struct_get_or_else 174 | 175 | This function streamlines the process of checking for a key's existance in a Struct, and getting the value of that key. 176 | 177 | ```gml 178 | variable_struct_get_or_else(struct, name, defaultValue) 179 | ``` 180 | | Argument | Type | Description | 181 | | -------- | ---- | ----------- | 182 | |`struct` | Struct | The struct reference to use | 183 | |`name` | String | The name of the variable to get | 184 | |`defaultValue` | Any | The value to return if the named key does not exist in the struct | 185 | 186 | #### Returns 187 | 188 | The value of the given key in the given struct, or `defaultValue` if the key does not exist in the struct. 189 | 190 | #### example 191 | ```gml 192 | var monster1 = { 193 | type: "monster", 194 | hp: 15 195 | }; 196 | var monster2 = { 197 | type: "monster", 198 | hp: 20, 199 | color: c_red 200 | }; 201 | var monsterColor1 = variable_struct_get_or_else(monster1, "color", c_black); 202 | var monsterColor2 = variable_struct_get_or_else(monster2, "color", c_black); 203 | ``` 204 | After the code above is run, the value of `monsterColor1` would be `c_black`, whereas the value of `monsterColor2` would be `c_red`. You can see that since the key `color` did not exist in the first struct, the default value of `c_black` was returned, and no manual existence checks were needed. 205 | 206 | ## Seedpod Instances 207 | Seedpod Instances (`scr_seedpod_instances`) is a collection of functions pertaining to live instances in the game at runtime. 208 | 209 | ### with_tagged 210 | 211 | This function lets you quickly apply a function to all instances in the room whose object asset has a given tag. 212 | 213 | ```gml 214 | with_tagged(tag, lambda) 215 | ``` 216 | | Argument | Type | Description | 217 | | -------- | ---- | ----------- | 218 | |`tag` | String or Array of Strings | The tag or array of asset tags to operate on | 219 | |`lambda` | Function | A function to run on every instance in the room whose tag or tags matches `tag` 220 | 221 | #### Returns 222 | 223 | N/A 224 | 225 | #### Example 226 | 227 | ```gml 228 | with_tagged("enemy", function() { 229 | instance_destroy(); 230 | }); 231 | ``` 232 | The above code will destroy every instance in the room whose object has the Asset Tag `enemy`. 233 | 234 | ### change_sprite 235 | 236 | This function changes the caller's `sprite_index` and resets its animation (`image_index`) to frame 0, only if it is not already showing the desired sprite. Lets you easily start all animations from frame 0 without having to write a conditional, you can simply call `change_sprite` every frame. 237 | 238 | ```gml 239 | change_sprite(newSpriteIndex) 240 | ``` 241 | | Argument | Type | Description | 242 | | -------- | ---- | ----------- | 243 | |`newSpriteIndex` | Sprite Asset | The desired `sprite_index` for the caller | 244 | 245 | #### Returns 246 | 247 | N/A 248 | 249 | #### Example 250 | 251 | ```gml 252 | switch (state) { 253 | case playerState.idle: 254 | change_sprite(spr_player_idle); 255 | break; 256 | case playerState.running: 257 | change_sprite(spr_player_running); 258 | break; 259 | } 260 | ``` 261 | The above code will change the player's sprite depending on the state of the character controller's state machine. Whenever the state changes, the new animation will start from frame 0. 262 | 263 | ### center_x 264 | 265 | This function returns the horizontal midpoint of an instance, as defined by its `bbox_left` and `bbox_right` values. 266 | 267 | ```gml 268 | center_x(inst = self) 269 | ``` 270 | | Argument | Type | Description | 271 | | -------- | ---- | ----------- | 272 | |`inst` | Instance ID or Object Asset | Optional, the instance whose midpoint to find. If not provided, the caller's midpoint will be returned | 273 | 274 | #### Returns 275 | 276 | An X coordinate representing the exact midpoint of `inst`, as defined by its `bbox` values. 277 | 278 | #### Example 279 | 280 | ```gml 281 | instance_create_layer(center_x(), center_y(), layer, obj_smoke_puff); 282 | ``` 283 | The above code creates an object at the exact midpoint coordinates of the caller, regardless of the caller's size, sprite, or position. 284 | 285 | ### center_y 286 | 287 | This function returns the vertical midpoint of an instance, as defined by its `bbox_top` and `bbox_bottom` values. 288 | 289 | ```gml 290 | center_y(inst = self) 291 | ``` 292 | | Argument | Type | Description | 293 | | -------- | ---- | ----------- | 294 | |`inst` | Instance ID or Object Asset | Optional, the instance whose midpoint to find. If not provided, the caller's midpoint will be returned | 295 | 296 | #### Returns 297 | 298 | A Y coordinate representing the exact midpoint of `inst`, as defined by its `bbox` values. 299 | 300 | #### Example 301 | 302 | ```gml 303 | instance_create_layer(center_x(), center_y(), layer, obj_smoke_puff); 304 | ``` 305 | The above code creates an object at the exact midpoint coordinates of the caller, regardless of the caller's size, sprite, or position. 306 | 307 | 308 | ### point_in_bounds 309 | 310 | This function tests whether a given X/Y coordinate exists within an instance's bounds, defined by the `bbox_*` internal variables. 311 | 312 | ```gml 313 | point_in_bounds(pX, pY) 314 | ``` 315 | | Argument | Type | Description | 316 | | -------- | ---- | ----------- | 317 | |`pX` | Real | The X coordinate to test | 318 | |`pY` | Real | The Y coordinate to test | 319 | 320 | #### Returns 321 | 322 | True if `pX, pY` falls within the `bbox` bounds of this instance. 323 | 324 | #### Example 325 | 326 | ```gml 327 | if (point_in_bounds(mouse_x, mouse_y)) { 328 | change_sprite(spr_moused_over); 329 | } 330 | ``` 331 | The above code tests whether the mouse cursor's room position is over the given instance. If so, it changes the instances sprite using `change_sprite`. 332 | 333 | ## Seedpod Strings 334 | Seedpod Instances (`scr_seedpod_strings`) is a collection of functions useful for string data manipulation 335 | 336 | ### string_pad 337 | 338 | This function operates similarly to `string_format`, except it lets you define an arbitrary padding character rather than just the space character. 339 | 340 | ```gml 341 | string_pad(value, amount, padChar) 342 | ``` 343 | | Argument | Type | Description | 344 | | -------- | ---- | ----------- | 345 | |`value` | Real | The number to be converted to a string | 346 | |`amount` | Integer | The total number of places to pad out `value` to | 347 | |`padChar` | String | The character to use for padding out `value` | 348 | 349 | #### Returns 350 | 351 | A string containing the number `value` but padded out to `amount` characters minimum using `padChar` to fill out the extra space. 352 | 353 | #### Example 354 | 355 | ```gml 356 | return string_pad(coins, 3, "0"); 357 | ``` 358 | The above code will pad out a `coins` variable to 3 places using the character `0`. For instance, if `coins` is equal to `56` then the above code will return the string `"056"`. Useful for displaying data in game UIs. 359 | 360 | ## Licensing 361 | 362 | Seedpod for GameMaker is licensed under Creative Commons 0. Essentially, you may use it, change it, ship it, and share it with absolutely no restrictions. 363 | --------------------------------------------------------------------------------