Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scrap Mecahanic Finder

Tool for finding creations in the Scrap Mechanic game.

Setup

Install node from https://nodejs.org/en/download/ This tool was developed with node version 14.8.0.

then clone the project, and run npm install from the project directory.

Usage

The tool will parse a save file (which is a sqlite database file) and will look for creations contain specified parts. So, if you've lost a creation and you know it contains (for example) one or more Level 5 Thrusters then you can use the tool to list the co-ordinates of all creations containing that part.

All Scrap Mechanic survival parts are defined in the game file: C:\Program Files (x86)\Steam\steamapps\common\Scrap Mechanic\Survival\Scripts\game\survival_items.lua

In that file, each part has a unique identified (UUID), e.g. a Level 5 Thruster is:

obj_interactive_thruster_05 = sm.uuid.new( "a736ffdf-22c1-40f2-8e40-988cab7c0559" )

You can run the tool specifying the part UUID, e.g.:

node sm_finder.js mygame.db a736ffdf-22c1-40f2-8e40-988cab7c0559

Output

Here is an example of the output you can expect:

Total number of bodies in save file: 3462
Found creation with part. BodyId: 28042
Found 1 matching bodies
Co-ordinates for body 28042:
{"minX":-737,"maxX":-735,"minY":622,"maxY":625,"absZ":198}
Finished

The min and max values are the co-ordinates of the creation, and absZ is its altitude.

Using the co-ordinates

You'll need a mod or code change to display the co-ordinates on the HUD. There are many available. You might also want a mod to allow you to teleport to specific co-ordinates.

Currently I am using this change to show co-ordinates on the HUD:

File: C:\Program Files (x86)\Steam\steamapps\common\Scrap Mechanic\Survival\Scripts\game\SurvivalPlayer.lua, change the top of function SurvivalPlayer.cl_localPlayerUpdate as follows:

function SurvivalPlayer.cl_localPlayerUpdate( self, dt )
	self:cl_updateCamera( dt )

	if g_survivalHud then
        g_survivalHud:setText( "TimePanel", getTimeOfDayString() )
        local character = self.player:getCharacter()
        if character then
            local text =  character.worldPosition.x ..", ".. character.worldPosition.y .. ", ".. character.worldPosition.z
            local direction = character.direction
            local yaw = math.atan2( direction.y, direction.x )
            if math.abs( yaw ) < math.pi * 0.25 then
                text = text.." E"
            elseif math.abs( yaw ) > math.pi * 0.75 then
                text = text.." W"
            elseif yaw >= math.pi * 0.25 then
                text = text.." N"
            else
                text = text.." S"
            end
                g_survivalHud:setText( "TimePanel", text )
        end
	end

and in File: C:\Program Files (x86)\Steam\steamapps\common\Scrap Mechanic\Data\Gui\Layouts\Hud\Hud_SurvivalHud.layout, add this line as part of the widget definitions:

<Widget type="TextBox" skin="TextBox" name="TimePanel" position_real="0 0 0.228125 0.0740741" />

Internals

Here's what I've discovered about the save file database tables:

RigidBody

This table contains an entry for each creation. It includes bodies that exist at the start of a new game (so your first creation won't have ID 1).

The ID seems to change e.g. when you put a creation on or off the lift.

I have not fully decoded it.

  74|1|000201 0000004A 0001 C5217B5D C52185B1 C511CCCF C511D943 0001 3E6CF065 BF2ED471 3ED1FCDE 3F0EF633 C511BF12 C5215350 4122445E 00000000000000000000000000000000000000000000000000
       0      3             9        13       17       21            27       31       35       39       43       47       51
              ID (74)       maxY     minY     maxX     minX                                                                Z

Note that co-ordinates are stored in IEEE 754 floating point format, see e.g. https://gregstoll.com/~gregstoll/floattohex/

ChildShape

This table contains simple shapes. A single block would be represented with a single row in this table.

Contiguous identical blocks appear to only take up one row. For example, if you made a row of three 'Metal 1' blocks then only one row in the table would be created. If you coloured one of those blocks then you'd end up with 2 rows.

I have not fully decoded it.

  591|72|011F01 0000024F 00000048 1E2F557C22A0D4890645E194C2F6ED8A 00000048 FFF6FFFF 000CFF 222222 00 0100010001
         0      3        7        11                               27                       38
                ID       Blk      Part UUID                        Blk again                Clr

Note that UUIDs are stored in big-endian format so the bytes are reversed, e.g. the example above is the 'Metal 1' UUID:

blk_metal1 = sm.uuid.new( "8aedf6c2-94e1-4506-89d4-a0227c552f1e" )

The row includes a reference (Blk) to the containing RigidBody. That's how I am able to find parts: I scan ChildShape to find rows containing the part of interest, and then I can look up the co-ordinates of the containing body in the RigidBody table.

Harvestable

I'm not making use of this table in the tool, but it can be used to find harvestable items, e.g. I used it manually to find a plot of mature potatoes.

The parts are listed in file: C:\Program Files (x86)\Steam\steamapps\common\Scrap Mechanic\Survival\Scripts\game\survival_harvestable.lua

and the partially decoded table format is:

  05000100 014953 00FFFFFFE5FFFFFFE500010001 D62F47C69D6F9D8EE2487E9BAE4993B3 3C3439F0 C4D4AC00 C4D4E400 BF0000013EFFFFFF3EFFFFFFBF00000100000000EE9E28FF
           ID                                UUID                             Z pos    Y pos    X pos

About

Tools for finding creations in the Scrap Mechanic game

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages