diff --git a/DataTables/Datas/__tables__.xlsx b/DataTables/Datas/__tables__.xlsx
index 5cdd1790..e0a0fba9 100644
Binary files a/DataTables/Datas/__tables__.xlsx and b/DataTables/Datas/__tables__.xlsx differ
diff --git a/DataTables/Datas/战斗/战斗资源素材.xlsx b/DataTables/Datas/战斗/战斗资源素材.xlsx
new file mode 100644
index 00000000..75c425a2
Binary files /dev/null and b/DataTables/Datas/战斗/战斗资源素材.xlsx differ
diff --git a/JisolGameCocos/assets/resources/config/data/schema.ts b/JisolGameCocos/assets/resources/config/data/schema.ts
index 2a869278..7ed03e63 100644
--- a/JisolGameCocos/assets/resources/config/data/schema.ts
+++ b/JisolGameCocos/assets/resources/config/data/schema.ts
@@ -690,6 +690,39 @@ export class TOnHookLevel {
 }
 
 
+export namespace TB {
+export class TbBattleResource {
+
+    constructor(_json_: any) {
+        if (_json_.id === undefined) { throw new Error() }
+        this.id = _json_.id
+        if (_json_.path === undefined) { throw new Error() }
+        this.path = _json_.path
+        if (_json_.type === undefined) { throw new Error() }
+        this.type = _json_.type
+    }
+
+    /**
+     * id
+     */
+    readonly id: number
+    /**
+     * 资源路径
+     */
+    readonly path: string
+    /**
+     * 资源类型(0.Spine)
+     */
+    readonly type: number
+
+    resolve(tables:Tables)
+    {
+    }
+}
+
+}
+
+
 
 
 export class TbGGlobal{
@@ -1204,6 +1237,38 @@ export class TbGOnHookMap1{
 
 
 
+export class TbBattleResource{
+    private _dataMap: Map<number, TB.TbBattleResource>
+    private _dataList: TB.TbBattleResource[]
+    constructor(_json_: any) {
+        this._dataMap = new Map<number, TB.TbBattleResource>()
+        this._dataList = []
+        for(var _json2_ of _json_) {
+            let _v: TB.TbBattleResource
+            _v = new TB.TbBattleResource(_json2_)
+            this._dataList.push(_v)
+            this._dataMap.set(_v.id, _v)
+        }
+    }
+
+    getDataMap(): Map<number, TB.TbBattleResource> { return this._dataMap; }
+    getDataList(): TB.TbBattleResource[] { return this._dataList; }
+
+    get(key: number): TB.TbBattleResource | undefined { return this._dataMap.get(key); }
+
+    resolve(tables:Tables)
+    {
+        for(let  data of this._dataList)
+        {
+            data.resolve(tables)
+        }
+    }
+
+}
+
+
+
+
 type JsonLoader = (file: string) => any
 
 export class Tables {
@@ -1239,6 +1304,8 @@ export class Tables {
     get TbGOnHookMaps(): TbGOnHookMaps  { return this._TbGOnHookMaps;}
     private _TbGOnHookMap1: TbGOnHookMap1
     get TbGOnHookMap1(): TbGOnHookMap1  { return this._TbGOnHookMap1;}
+    private _TbBattleResource: TbBattleResource
+    get TbBattleResource(): TbBattleResource  { return this._TbBattleResource;}
 
     constructor(loader: JsonLoader) {
         this._TbGGlobal = new TbGGlobal(loader('tbgglobal'))
@@ -1257,6 +1324,7 @@ export class Tables {
         this._TbGRoleBaseAttribute = new TbGRoleBaseAttribute(loader('tbgrolebaseattribute'))
         this._TbGOnHookMaps = new TbGOnHookMaps(loader('tbgonhookmaps'))
         this._TbGOnHookMap1 = new TbGOnHookMap1(loader('tbgonhookmap1'))
+        this._TbBattleResource = new TbBattleResource(loader('tbbattleresource'))
 
         this._TbGGlobal.resolve(this)
         this._TbGRole.resolve(this)
@@ -1274,5 +1342,6 @@ export class Tables {
         this._TbGRoleBaseAttribute.resolve(this)
         this._TbGOnHookMaps.resolve(this)
         this._TbGOnHookMap1.resolve(this)
+        this._TbBattleResource.resolve(this)
     }
 }
diff --git a/JisolGameCocos/assets/resources/config/json/tbbattleresource.json b/JisolGameCocos/assets/resources/config/json/tbbattleresource.json
new file mode 100644
index 00000000..0637a088
--- /dev/null
+++ b/JisolGameCocos/assets/resources/config/json/tbbattleresource.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/JisolGameCocos/assets/script/App.ts b/JisolGameCocos/assets/script/App.ts
index c93ec116..0a262959 100644
--- a/JisolGameCocos/assets/script/App.ts
+++ b/JisolGameCocos/assets/script/App.ts
@@ -18,13 +18,15 @@ import JLoaderSystem from "../../extensions/ngame/assets/ngame/system/JLoaderSys
 import { sp } from "cc";
 import { SpriteFrame } from "cc";
 import Loading from "../../extensions/ngame/assets/ngame/util/Loading";
-import { Tables } from "../resources/config/data/schema";
+import { TB, Tables } from "../resources/config/data/schema";
 import { JsonAsset } from "cc";
 import { GAction } from "./consts/GAction";
 import { StorageData, StorageEnum } from "./consts/GData";
 import { JAPI, JAPIConfig } from "../../extensions/ngame/assets/ngame/util/JAPI";
 import { AppData } from "./AppData";
 import AppAction from "./AppAction";
+import { Asset } from "cc";
+import { Component } from "cc";
 
 // let APIPath = `http://localhost:8080`
 // let WsPath = `ws://localhost:8080/websocket`
@@ -144,6 +146,10 @@ export class JLoaderBattle extends JLoaderSystem{
     static loading = "JLoaderBattle";
     static loadingInit = "JLoaderBattle_Init";
 
+    //资源
+    resources:{[id:number]:Asset} = {};
+    foreverResources:number[] = [];     //永久资源Id
+
     roleSpine:{[id:number]:sp.SkeletonData} = {};       //角色Spine
     roleResImage:{[id:number]:SpriteFrame} = {};        //角色战斗素材图片
     roleResSpine:{[id:number]:sp.SkeletonData} = {};    //角色战斗素材Spine
@@ -205,6 +211,80 @@ export class JLoaderBattle extends JLoaderSystem{
         
     }
 
+    //加载永久资源
+    async loadForeverResources(...ress:TB.TbBattleResource[]){
+
+        for (const res of ress) {
+            await this.loadForeverResource(res);
+        }
+
+    }
+    //加载永久资源
+    loadForeverResource(res:TB.TbBattleResource){
+        return (new Promise<void>(r => {
+            this.bundle.load(res.path,(error,data) => {
+                if(this.foreverResources.indexOf(res.id) < 0){
+                    //添加永久资源
+                    this.resources[res.id] = data;
+                    data.addRef();
+                }
+                r();
+            })
+        }))
+    }
+
+    //加载组件资源
+    async loadComponentResource<T extends Asset>(res:TB.TbBattleResource,comp:Component):Promise<T>{
+        return (new Promise<T>(r => {
+            this.bundle.load(res.path,(error,data) => {
+                if(!this.resources[res.id])
+                    this.resources[res.id] = data;
+                //添加资源次数
+                data.addRef();
+                //添加销毁资源引用
+                let onDestroy = comp["onDestroy"];
+                comp["onDestroy"] = () => {
+                    if(onDestroy)
+                        onDestroy.bind(comp)();
+                    data.decRef();
+                    this.onUpdateResources();
+                }
+                r(data as T);
+            })
+        }))
+    }
+
+    //销毁永久资源
+    clearForeverResources(...ress:TB.TbBattleResource[]){
+        this.foreverResources.forEach(id => {
+            if(this.resources[id]){
+                this.resources[id].decRef();
+            }
+        });
+        this.foreverResources = [];
+        this.onUpdateResources();
+    }
+
+    //更新资源(过滤没有用的资源)
+    onUpdateResources(){
+        for (const key in this.resources) {
+            if (Object.prototype.hasOwnProperty.call(this.resources, key)) {
+                const data = this.resources[key];
+                if(!data.isValid) this.resources[key] = null;
+            }
+        }
+    }
+
+    //获取资源
+    getData<T extends Asset>(resId:number):T{
+
+        let res = this.resources[resId]
+        if(!res) console.info(`[JLoaderBattle] 未加载资源${resId}`);
+        
+        return res as T;
+        
+    }
+
 }
 
 export const app = {
diff --git a/JisolGameServer/Main/src/main/java/cfg/TB/TbBattleResource.java b/JisolGameServer/Main/src/main/java/cfg/TB/TbBattleResource.java
new file mode 100644
index 00000000..5b2c701d
--- /dev/null
+++ b/JisolGameServer/Main/src/main/java/cfg/TB/TbBattleResource.java
@@ -0,0 +1,55 @@
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+package cfg.TB;
+
+import luban.*;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+
+public final class TbBattleResource extends AbstractBean {
+    public TbBattleResource(JsonObject _buf) { 
+        id = _buf.get("id").getAsInt();
+        path = _buf.get("path").getAsString();
+        type = _buf.get("type").getAsInt();
+    }
+
+    public static TbBattleResource deserialize(JsonObject _buf) {
+            return new cfg.TB.TbBattleResource(_buf);
+    }
+
+    /**
+     * id
+     */
+    public final int id;
+    /**
+     * 资源路径
+     */
+    public final String path;
+    /**
+     * 资源类型(0.Spine)
+     */
+    public final int type;
+
+    public static final int __ID__ = 509266580;
+    
+    @Override
+    public int getTypeId() { return __ID__; }
+
+    @Override
+    public String toString() {
+        return "{ "
+        + "(format_field_name __code_style field.name):" + id + ","
+        + "(format_field_name __code_style field.name):" + path + ","
+        + "(format_field_name __code_style field.name):" + type + ","
+        + "}";
+    }
+}
+
diff --git a/JisolGameServer/Main/src/main/java/cfg/Tables.java b/JisolGameServer/Main/src/main/java/cfg/Tables.java
index c5d0508c..a5072512 100644
--- a/JisolGameServer/Main/src/main/java/cfg/Tables.java
+++ b/JisolGameServer/Main/src/main/java/cfg/Tables.java
@@ -51,6 +51,8 @@ public final class Tables
     public cfg.TbGOnHookMaps getTbGOnHookMaps() { return _tbgonhookmaps; }
     private final cfg.TbGOnHookMap1 _tbgonhookmap1;
     public cfg.TbGOnHookMap1 getTbGOnHookMap1() { return _tbgonhookmap1; }
+    private final cfg.TbBattleResource _tbbattleresource;
+    public cfg.TbBattleResource getTbBattleResource() { return _tbbattleresource; }
 
     public Tables(IJsonLoader loader) throws java.io.IOException {
         _tbgglobal = new cfg.TbGGlobal(loader.load("tbgglobal")); 
@@ -69,6 +71,7 @@ public final class Tables
         _tbgrolebaseattribute = new cfg.TbGRoleBaseAttribute(loader.load("tbgrolebaseattribute")); 
         _tbgonhookmaps = new cfg.TbGOnHookMaps(loader.load("tbgonhookmaps")); 
         _tbgonhookmap1 = new cfg.TbGOnHookMap1(loader.load("tbgonhookmap1")); 
+        _tbbattleresource = new cfg.TbBattleResource(loader.load("tbbattleresource")); 
     }
 }
 
diff --git a/JisolGameServer/Main/src/main/java/cfg/TbBattleResource.java b/JisolGameServer/Main/src/main/java/cfg/TbBattleResource.java
new file mode 100644
index 00000000..ebbbb56a
--- /dev/null
+++ b/JisolGameServer/Main/src/main/java/cfg/TbBattleResource.java
@@ -0,0 +1,37 @@
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+package cfg;
+
+import luban.*;
+import com.google.gson.JsonElement;
+
+
+public final class TbBattleResource {
+    private final java.util.HashMap<Integer, cfg.TB.TbBattleResource> _dataMap;
+    private final java.util.ArrayList<cfg.TB.TbBattleResource> _dataList;
+    
+    public TbBattleResource(JsonElement _buf) {
+        _dataMap = new java.util.HashMap<Integer, cfg.TB.TbBattleResource>();
+        _dataList = new java.util.ArrayList<cfg.TB.TbBattleResource>();
+        
+        for (com.google.gson.JsonElement _e_ : _buf.getAsJsonArray()) {
+            cfg.TB.TbBattleResource _v;
+            _v = cfg.TB.TbBattleResource.deserialize(_e_.getAsJsonObject());
+            _dataList.add(_v);
+            _dataMap.put(_v.id, _v);
+        }
+    }
+
+    public java.util.HashMap<Integer, cfg.TB.TbBattleResource> getDataMap() { return _dataMap; }
+    public java.util.ArrayList<cfg.TB.TbBattleResource> getDataList() { return _dataList; }
+
+    public cfg.TB.TbBattleResource get(int key) { return _dataMap.get(key); }
+
+}
diff --git a/JisolGameServer/Main/src/main/resources/json/tbbattleresource.json b/JisolGameServer/Main/src/main/resources/json/tbbattleresource.json
new file mode 100644
index 00000000..0637a088
--- /dev/null
+++ b/JisolGameServer/Main/src/main/resources/json/tbbattleresource.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file