Defold 1.4.0 has been released

Defold 1.4.0

ATTENTION: This release contains breaking changes!

Please pay extra attention to the release notes and the four breaking changes, as one or more of them may affect your projects. The breaking changes (listed in more detail further down) are:

  • BREAKING CHANGE: (#7081) Added physics.max_collision_object_count field in game.project
  • BREAKING CHANGE: (#7095) Use lua-cjson for both json.encode/json.decode. We’ve also removed the C++ dmJson namespace and json.h.
  • BREAKING CHANGE: (#6963) Improved GUI clipping with layers
  • BREAKING CHANGE: (#7054) Made dmObjectPool into a class, with new access function GetRawObjects()

Release notes

Summary

  • BREAKING CHANGE: (#7081) Added physics.max_collision_object_count field in game.project
  • BREAKING CHANGE: (#7095) Use lua-cjson for both json.encode/json.decode
  • BREAKING CHANGE: (#6963) Improved GUI clipping with layers
  • BREAKING CHANGE: (#7054) Made dmObjectPool into a class, with new access function GetRawObjects()
  • NEW: (#7002) Added option to pass additional headers to the build server
  • NEW: (#7036) Option for bundling without resources to use as a build target.
  • FIX: (#7091) Fix issue when bundling projects with models
  • FIX: (#7114) Fix bug on iOS when profiler doesn’t show CPU and Memory usage
  • FIX: (#7064) Remove partially cached HTTP response on timeout
  • FIX: (#7097) Crash when using sound resource properties
  • FIX: (#7105) Close application when stop debugging
  • FIX: (#7049) Fix editor exception during build if a referenced collection overrides a resource script property
  • FIX: (#7100) Fix atlas image deduplication
  • FIX: (#7027) Make editor more resilient when opening files
  • FIX: (#7062) Fix slow loading of sprite data in the editor
  • FIX: (#7074) Copied collision 3d box doesn’t show properly in the editor
  • FIX: (#7044) Updated to stb_vorbis.c 1.22

Engine

BREAKING CHANGE: (#7081) Added physics.max_collision_object_count field in game.project

Details

Added physics.max_collision_object_count field in game.project to set maximum count of collision objects per physics world. This prevents a crash which would happen in earlier versions when using more than 1024 collision objects in a physics world.

IMPORTANT: This is a breaking change. The default value for physics.max_collision_object_count is 128. Make sure you adjust the value to suit the needs of your project.


BREAKING CHANGE: (#7095) Use lua-cjson for both json.encode/json.decode

Details

The internal library used in Defold for json encoding and decoding is lua-cjson. The decoding performance improvement is about 10x faster than before (when using jsmn). With this change a number of changes have been introduced, one of which is considered a breaking change:

  • BREAKING: The dmJson namespace and functionality has been removed from our C++ dmSdk due to its poor performance and lack of features.
  • NEW: Added the keyword json.null in order to support null values in a Lua table.
  • NEW: Added dmScript::LuaToJson(lua_State* L, char** json, size_t* length) as a new function in the C++dmSdk.

BREAKING CHANGE: (#6963) Improved GUI clipping with layers

Details

The behaviour regarding how clipping interacts with layers in GUI scenes has been modified. Instead of treating each clipping node as its own isolated node tree, where the layers only affect the child nodes, using layers can now change the ordering of the nodes freely.


BREAKING CHANGE: (#7054) Made dmObjectPool into a class, with new access function GetRawObjects()

Details

In order to make it clearer that the access to the internal objects is volatile, we put them in a class and only allowing access to them using the function dmObjectPool::GetRawObjects()


FIX: (#7091) Fix issue when bundling projects with models

Details

Fixes an issue when bundling projects with model components.


FIX: (#7114) Fix bug on iOS when profiler doesn’t show CPU and Memory usage

Details

Fix a regression bug introduced in 1.3.7 when profiler doesn’t show CPU and Memory usage on iOS.


FIX: (#7064) Remove partially cached HTTP response on timeout

Details

This fixes an issue where a network request is interrupted due to a network error or timeout still left a partial response stored in the HTTP cache. Subsequent requests for the same resource would in such a case return the partial and most likely corrupted response stored in the cache. The cache will now remove any partial response on error.


FIX: (#7097) Crash when using sound resource properties

Details

Fix crash that happening when set a sound resource for a sound component that has playing sounds.


FIX: (#7105) Close application when stop debugging

Details

Fix issue introduced in 1.3.7 (regression) when Debugger stop button doesn’t close the application.


Editor

NEW: (#7002) Added option to pass additional headers to the build server

Details

It is now possible to pass additional headers to the build server when building native extensions using command line tools and the editor. The editor has a new Build Server Headers field in the Extensions tab of the Preferences menu. The bob.jar command line tool has a new --build-server-header option.

In the editor headers are added line by line in a multi-line text text area. In bob.jar headers are added one by one using multiple --build-server-header options.

Example:

java -jar bob.jar `--build-server-header="x-my-header1: header1_value" --build-server-header="x-my-header2: My name is Bob"

Will set two headers:

x-my-header1: header1_value
x-my-header2: My name is Bob

NEW: (#7036) Option for bundling without resources to use as a build target.

Details

New option for Bob --exclude-archive and a checkbox in the Bundle popup for bundling without resources. This bundle may be used as a build target.


FIX: (#7049) Fix editor exception during build if a referenced collection overrides a resource script property

Details

Fixed an editor exception during build if a referenced collection overrides a resource script property.


FIX: (#7100) Fix atlas image deduplication

Details

Atlases with duplicate images in different animations will no longer have the images duplicated in the atlas image.


FIX: (#7027) Make editor more resilient when opening files

Details

We used to save all recent files of all projects in a single user preference key. Since preference keys have a size limit, this is clearly a problem. This commit makes the editor use a different preference key per every project root, and also decreases the history limit just to be extra safe.

User-facing changes: Hopefully none :sweat_smile: . If no files in the editor could be opened before, they will now.


FIX: (#7062) Fix slow loading of sprite data in the editor

Details

Fixed slow project load times introduced by the addition of slice-9 support for sprites.


FIX: (#7074) Copied collision 3d box doesn’t show properly in the editor

Details

Collision objects are correctly copy-pasted in projects with 3D physics.


30 Likes

Excellent - thank you! :smiley:
And for all the other fixes and improvements as well, of course.

7 Likes

1.4.0 updated with a hotfix (f4a699eb412a2445e894568f2d7466aba61b4c41)

We found that this version (1.3.7 affected as well) may produce corrupted Lua bytecode for 32-bit systems when bundled for 2 architectures simultaneously (it’s possible to do this only on the Android platform).

As result, Android phones that support only 32bit can’t start such bundles and it may look like a black screen or some other errors which hard to track.
We recommend you update Defold to the latest version with a fix using an internal updating mechanism.

11 Likes

I’ve upgraded to 1.4.0, and the corresponding extension updates. The game is crashing on startup.

Device: Google Pixel 6a.
OS: Android 13

Logcat output attached:
logcat.txt (94.4 KB)

This happened while doing an In-app purchase?

--------- beginning of crash
11-20 23:03:17.871   746   782 F libc    : upload/extension-iap/src/iap_android.cpp:364: void HandlePurchaseResult(const IAPCommand *): assertion "top == lua_gettop(L)" failed
11-20 23:03:17.871 10520 10533 I Finsky  : [31] zpw.F(61): Billing preferred account via installer for dev.skaterdad.applespider: [5yjzO6_Zbz9tdTDxuvMf5QNTP414pClzO6iuRer4l7E]
11-20 23:03:17.871 10520 10532 I Finsky  : [30] zpw.F(14): dev.skaterdad.applespider: Account determined from installer data - [5yjzO6_Zbz9tdTDxuvMf5QNTP414pClzO6iuRer4l7E]
11-20 23:03:17.871 10520 10532 I Finsky  : [30] zpw.F(61): Billing preferred account via installer for dev.skaterdad.applespider: [5yjzO6_Zbz9tdTDxuvMf5QNTP414pClzO6iuRer4l7E]
11-20 23:03:17.871 10305 10305 D BoundBrokerSvc: onBind: Intent { act=com.google.android.gms.signin.service.START pkg=com.google.android.gms }
11-20 23:03:17.871 10305 10305 D BoundBrokerSvc: Loading bound service for intent: Intent { act=com.google.android.gms.signin.service.START pkg=com.google.android.gms }
11-20 23:03:17.878  1220  2415 D audio_hw_output_stream: update stream 3 active 1 gain 0.000000
11-20 23:03:17.878  1220 18560 D audio_hw: prepare raw-playback
11-20 23:03:17.878  1220 18560 D audio_hw: raw-playback:
11-20 23:03:17.878  1220 18560 D audio_hw: rx:
11-20 23:03:17.878  1220 18560 D audio_hw:   #0: OUT_SPEAKER_BE_CFG 0
11-20 23:03:17.878  1220 18560 D audio_hw_aoc: aoc_get_hw_intf_ctrl : HW_INTF : 8
11-20 23:03:17.878  1220 18560 D audio_hw_aoc: aoc_get_hw_intf_ctrl : HW_INTF : 8
11-20 23:03:17.878  1220 18560 W audio_hw_35l41: cs35l41_amp_common_event: ret: 0, event: 1, state: 2, device: 4
11-20 23:03:17.878  1220 18560 D audio_route: Apply path: speaker
11-20 23:03:17.880   678  3252 I BpBinder: onLastStrongRef automatically unlinking death recipients: <uncached descriptor>
11-20 23:03:17.883  4044  5397 I AiAiAdaptiveAudio: updateState: enabledInSettings=false, playbackState=PlaybackState{isPlaying=true, contentType=UNCHECKED_CONTENT_TYPE, isMusicContent=false}
11-20 23:03:17.883  4044  5397 I AiAiAdaptiveAudio: stopMonitoring
11-20 23:03:17.883  4044  5397 I AiAiAdaptiveAudio: Updating calibration state: IDLE -> IDLE
11-20 23:03:17.884  1220 18560 D audio_hw_aoc_route: speaker 1
11-20 23:03:17.884  1220 18560 D audio_route: Apply path: hostless-ulC spk-vi
11-20 23:03:17.884  1220 18560 W audio_hw_35l41: cs35l41_amp_common_event: ret: 0, event: 2, state: 3, device: 4
11-20 23:03:17.884  1220 18560 D audio_hw_soundtrigger: st_comm_aud_event_monitor:codec dev:4 active
11-20 23:03:17.884  1220 18560 I audio_hw_aoc: Mode Ambient is already selected
11-20 23:03:17.884  1220 18560 D audio_route: Apply path: raw-playbackP
11-20 23:03:17.885  1220 18560 D audio_hw_aoc_route: raw-playbackP 1
11-20 23:03:17.885  1220 18560 E audio_route: unable to find path 'speaker-post'
11-20 23:03:17.885  1220 18560 D audio_hw_aoc_route: speaker-post 1
11-20 23:03:17.885  1220  1729 D audio_hw_35l41: cs35l41_rtlogger_data_analysis: play with low vol, skip
11-20 23:03:17.885  1220  1729 D audio_hw_35l41: cs35l41_bdlogger_data_analysis: Left/Top Max temp: 0xfb6f4 ==> 62.858643 C
11-20 23:03:17.886  1220 18560 D audio_hw_waves: update_rotation_from_adev: update sink 1 info
11-20 23:03:17.886  1575  1575 D AOC     : F1:MSG: controller.cc, 273: AudioOutCtrl: cmd ID: 0x010f, tag: 0xe2 [cntr = 2066]
11-20 23:03:17.886  1575  1575 D AOC     : F1:Source 9 mastered by sink 0
11-20 23:03:17.886  1575  1575 D AOC     : F1:AT Map:200 (LL:0), 1 EPs active, Power: Yes, Config: No
11-20 23:03:17.886  1575  1575 D AOC     : F1:Mixer 0 configuration changed: (200)
11-20 23:03:17.886  1575  1575 D AOC     : F1:Sink 0 Configuration changed: ULL (enabled)
11-20 23:03:17.886  1575  1575 D AOC     : F1:AHWSinkSPKR started: 48 samples (32-bit,2 ch,48 kHz) block 384
11-20 23:03:17.886  1220  1729 D audio_hw_35l41: cs35l41_bdlogger_data_analysis: Left/Top Max exc: 0x39999 ==> 0.449999 mm
11-20 23:03:17.886  1575  1575 D AOC     : F1:[AHWSinkSPKR] DL resync B: 0, A:0. wo: 0, target offset: 1632 (align 0) -> ro:0
11-20 23:03:17.886  1220  1729 D audio_hw_35l41: cs35l41_bdlogger_data_analysis: Left/Top dsp heartbeat = 0x13bb
11-20 23:03:17.886  1575  1575 D AOC     : F1:MSG: controller.cc, 811: AudioOutCtrl: ipc: audio_output_co, cmd ID: 0x010f, tag: 0xe2, rc: 0
11-20 23:03:17.887  1575  1575 D AOC     : F1:Speaker Started (DualDMA on 1 and 2)
11-20 23:03:17.887  1220  1729 D audio_hw_35l41: cs35l41_bdlogger_data_analysis: Right/Bottom Max temp: 0x148d04 ==> 82.203369 C
11-20 23:03:17.887  1575  1575 D AOC     : F1:MSG: controller.cc, 273: AudioOutCtrl: cmd ID: 0x00ce, tag: 0xe3 [cntr = 2067]
11-20 23:03:17.887  1220  1729 D audio_hw_35l41: cs35l41_bdlogger_data_analysis: Right/Bottom Max exc: 0x33333 ==> 0.400000 mm
11-20 23:03:17.887  1575  1575 D AOC     : F1:ERR: controller_audio_output.cc, 1596: Entrypoint 23 cannot be configured
11-20 23:03:17.887  1220  1729 D audio_hw_35l41: cs35l41_bdlogger_data_analysis: Right/Bottom dsp heartbeat = 0x13bb
11-20 23:03:17.887  1575  1575 D AOC     : F1:ERR: controller.cc, 808: AudioOutCtrl: ipc: audio_output_co, cmd ID: 0x00ce, tag: 0xe3, rc: -1
11-20 23:03:17.887  1575  1575 D AOC     : H0:Mixer AMixSPKR: 480 samples (0200/0200) (OFF)
11-20 23:03:17.890  1575  1575 D AOC     : F1:MSG: controller.cc, 273: AudioOutCtrl: cmd ID: 0x00c9, tag: 0xe4 [cntr = 2068]
11-20 23:03:17.890  1575  1575 D AOC     : F1:ERR: controller_audio_output.cc, 1418: Entrypoint 23 cannot be enabled
11-20 23:03:17.890  1575  1575 D AOC     : F1:ERR: controller.cc, 808: AudioOutCtrl: ipc: audio_output_co, cmd ID: 0x00c9, tag: 0xe4, rc: -1
11-20 23:03:17.894   746   782 I defold  : INFO:CRASH: Successfully wrote Crashdump to file: /data/user/0/dev.skaterdad.applespider/files/_crash
11-20 23:03:17.894   746   782 E defold  : ERROR:CRASH: CALL STACK:
11-20 23:03:17.894   746   782 E defold  :
11-20 23:03:17.894   746   782 E defold  : # 0 pc     0x1d3988 ...8HQ==/split_config.arm64_v8a.apk <unknown>+0
11-20 23:03:17.894   746   782 E defold  : # 1 pc        0x874 [vdso] <unknown>+0
11-20 23:03:17.894   746   782 E defold  : # 2 pc      0x160f0 ...oid.runtime/lib64/bionic/libc.so abort+160
11-20 23:03:17.894   746   782 E defold  :
11-20 23:03:17.894   746   782 E defold  :

No, the game is crashing immediately upon launch.

This is the iap.init callback. It’s pretty standard, I think. None of my IAP are consumable, so the purchases are always active.

iap.init callback
local function iap_listener(self, transaction, error)
	if error == nil then
		if transaction.state == iap.TRANS_STATE_PURCHASING then
			print("Purchasing...")
		elseif transaction.state == iap.TRANS_STATE_PURCHASED then
			print("Purchased!")
			-- this is called on game startup for non-consumables.
			-- also called during purchase of consumables
			if transaction.ident == const.IAP_REMOVE_ADS then
				local already_have_it = settings.ads_disabled()
				commit_iap(const.IAP_REMOVE_ADS)
				iap.acknowledge(transaction)
				if not already_have_it then
					show_messagebox(defglot.get_text("IAP_ADS_THANKS"))
				end
			elseif transaction.ident == const.IAP_TP then
				local already_have_it = settings.have_tp()
				commit_iap(const.IAP_TP)
				iap.acknowledge(transaction)
				if not already_have_it then
					show_messagebox(defglot.get_text("IAP_TP_THANKS"))
				end
			else
				-- iap.finish(transaction) -- consumables need this
			end
		elseif transaction.state == iap.TRANS_STATE_UNVERIFIED then
			print("Unverified!")
		elseif transaction.state == iap.TRANS_STATE_FAILED then
			show_messagebox(defglot.get_text("IAP_FAILED"))
		elseif transaction.state == iap.TRANS_STATE_RESTORED then
			print("Restored")
		end
	else
		show_messagebox(error.error .. ": " .. error.reason)
		print(error.error .. ": " .. error.reason)
	end
end

pls try

adb bugreport tombstone.zip

and check if you have this crash with full call stack there.

I wonder if you have an ongoing purchase? From a previous run? (I’m basing this on the mention of an assert in HandlePurchaseResult.

I’m going to check the extension again

What do you know, I’m getting the exact same error! Checking!

@SkaterDad we’ve released a fix for extension-iap. Please give it a try!

4 Likes

Seems to be working well now!

Thanks for the quick fix :clap:

3 Likes

Hi!
json now decodes very strange:
field in json string:
“some_field”:null

if i pprint decoded table, i got:
some_field = userdata: NULL

in 1.3.7
some_field = nil

is it bug?

It is not a bug. This new functionality exists to allow developers to distinguish between JSON data which has a key with value ‘null’ versus JSON data which is missing the key. It is part of the breaking change we did in this release.

3 Likes